2013-02-12 12:51:25 -08:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2013-06-06 15:14:44 -07:00
|
|
|
if (!this._fastFind.currentWindow)
|
|
|
|
return;
|
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let scroll = 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;
|
|
|
|
scroll.add(rect.left + parseInt(left), rect.top + parseInt(top));
|
|
|
|
}
|
|
|
|
|
|
|
|
let rangeRect = selection.getRangeAt(0).getBoundingClientRect();
|
|
|
|
let rect = new Rect(scroll.x + rangeRect.left, scroll.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 , result: findResult });
|
|
|
|
});
|
|
|
|
timer.once(0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
FindHandler.init();
|