gecko/browser/metro/base/content/contenthandlers/FindHandler.js

88 lines
3.1 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
dump("### FindHandler.js loaded\n");
var FindHandler = {
get _fastFind() {
delete this._fastFind;
this._fastFind = Cc["@mozilla.org/typeaheadfind;1"].createInstance(Ci.nsITypeAheadFind);
this._fastFind.init(docShell);
return this._fastFind;
},
init: function findHandlerInit() {
addMessageListener("FindAssist:Find", this);
addMessageListener("FindAssist:Next", this);
addMessageListener("FindAssist:Previous", this);
},
receiveMessage: function findHandlerReceiveMessage(aMessage) {
let findResult = Ci.nsITypeAheadFind.FIND_NOTFOUND;
let json = aMessage.json;
switch (aMessage.name) {
case "FindAssist:Find":
findResult = this._fastFind.find(json.searchString, false);
break;
case "FindAssist:Previous":
findResult = this._fastFind.findAgain(true, false);
break;
case "FindAssist:Next":
findResult = this._fastFind.findAgain(false, false);
break;
}
if (findResult == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
sendAsyncMessage("FindAssist:Show", { rect: null, result: findResult });
return;
}
if (!this._fastFind.currentWindow)
return;
let selection = this._fastFind.currentWindow.getSelection();
if (!selection.rangeCount || selection.isCollapsed) {
// The selection can be into an input or a textarea element
let nodes = content.document.querySelectorAll("input[type='text'], textarea");
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i];
if (node instanceof Ci.nsIDOMNSEditableElement && node.editor) {
selection = node.editor.selectionController.getSelection(Ci.nsISelectionController.SELECTION_NORMAL);
if (selection.rangeCount && !selection.isCollapsed)
break;
}
}
}
// Return the bounding selection rect in content coordinates
// including the scroll offset.
let offset = ContentScroll.getScrollOffset(content);
for (let frame = this._fastFind.currentWindow; frame != content; frame = frame.parent) {
let rect = frame.frameElement.getBoundingClientRect();
let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth;
let top = frame.getComputedStyle(frame.frameElement, "").borderTopWidth;
offset.add(rect.left + parseInt(left), rect.top + parseInt(top));
}
let rangeRect = selection.getRangeAt(0).getBoundingClientRect();
let rect = new Rect(offset.x + rangeRect.left, offset.y + rangeRect.top,
rangeRect.width, rangeRect.height);
// Ensure the potential "scroll" event fired during a search as already fired
let timer = new Util.Timeout(function() {
sendAsyncMessage("FindAssist:Show", {
rect: rect.isEmpty() ? null: rect,
contentHeight: content.document.documentElement.scrollHeight,
result: findResult
});
});
timer.once(0);
}
};
FindHandler.init();