mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-07-14 12:29:01 +00:00
159 lines
4.4 KiB
JavaScript
159 lines
4.4 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/. */
|
||
|
"use strict";
|
||
|
|
||
|
var FindHelper = {
|
||
|
_finder: null,
|
||
|
_targetTab: null,
|
||
|
_initialViewport: null,
|
||
|
_viewportChanged: false,
|
||
|
_result: null,
|
||
|
_limit: 0,
|
||
|
|
||
|
observe: function(aMessage, aTopic, aData) {
|
||
|
switch(aTopic) {
|
||
|
case "FindInPage:Opened": {
|
||
|
this._findOpened();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "Tab:Selected": {
|
||
|
// Allow for page switching.
|
||
|
this._uninit();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case "FindInPage:Closed":
|
||
|
this._uninit();
|
||
|
this._findClosed();
|
||
|
break;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_findOpened: function() {
|
||
|
try {
|
||
|
this._limit = Services.prefs.getIntPref("accessibility.typeaheadfind.matchesCountLimit");
|
||
|
} catch (e) {
|
||
|
// Pref not available, assume 0, no match counting.
|
||
|
this._limit = 0;
|
||
|
}
|
||
|
|
||
|
Messaging.addListener((data) => {
|
||
|
this.doFind(data.searchString, data.matchCase);
|
||
|
return this._getMatchesCountResult(data.searchString);
|
||
|
}, "FindInPage:Find");
|
||
|
|
||
|
Messaging.addListener((data) => {
|
||
|
this.findAgain(data.searchString, false, data.matchCase);
|
||
|
return this._getMatchesCountResult(data.searchString);
|
||
|
}, "FindInPage:Next");
|
||
|
|
||
|
Messaging.addListener((data) => {
|
||
|
this.findAgain(data.searchString, true, data.matchCase);
|
||
|
return this._getMatchesCountResult(data.searchString);
|
||
|
}, "FindInPage:Prev");
|
||
|
},
|
||
|
|
||
|
_init: function() {
|
||
|
// If there's no find in progress, start one.
|
||
|
if (this._finder) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._targetTab = BrowserApp.selectedTab;
|
||
|
try {
|
||
|
this._finder = this._targetTab.browser.finder;
|
||
|
} catch (e) {
|
||
|
throw new Error("FindHelper: " + e + "\n" +
|
||
|
"JS stack: \n" + (e.stack || Components.stack.formattedStack));
|
||
|
}
|
||
|
|
||
|
this._finder.addResultListener(this);
|
||
|
this._initialViewport = JSON.stringify(this._targetTab.getViewport());
|
||
|
this._viewportChanged = false;
|
||
|
},
|
||
|
|
||
|
_uninit: function() {
|
||
|
// If there's no find in progress, there's nothing to clean up.
|
||
|
if (!this._finder) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._finder.removeSelection();
|
||
|
this._finder.removeResultListener(this);
|
||
|
this._finder = null;
|
||
|
this._targetTab = null;
|
||
|
this._initialViewport = null;
|
||
|
this._viewportChanged = false;
|
||
|
},
|
||
|
|
||
|
_findClosed: function() {
|
||
|
Messaging.removeListener("FindInPage:Find");
|
||
|
Messaging.removeListener("FindInPage:Next");
|
||
|
Messaging.removeListener("FindInPage:Prev");
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Request, wait for, and return the current matchesCount results for a string.
|
||
|
*/
|
||
|
_getMatchesCountResult: function(findString) {
|
||
|
// Count matches up to any provided limit.
|
||
|
if (this._limit <= 0) {
|
||
|
return { total: 0, current: 0, limit: 0 };
|
||
|
}
|
||
|
|
||
|
// Sync call to Finder, results available immediately.
|
||
|
this._finder.requestMatchesCount(findString, this._limit);
|
||
|
return this._result;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Pass along the count results to FindInPageBar for display.
|
||
|
*/
|
||
|
onMatchesCountResult: function(result) {
|
||
|
this._result = result;
|
||
|
this._result.limit = this._limit;
|
||
|
},
|
||
|
|
||
|
doFind: function(searchString, matchCase) {
|
||
|
if (!this._finder) {
|
||
|
this._init();
|
||
|
}
|
||
|
|
||
|
this._finder.caseSensitive = matchCase;
|
||
|
this._finder.fastFind(searchString, false);
|
||
|
},
|
||
|
|
||
|
findAgain: function(searchString, findBackwards, matchCase) {
|
||
|
// This always happens if the user taps next/previous after re-opening the
|
||
|
// search bar, and not only forces _init() but also an initial fastFind(STRING)
|
||
|
// before any findAgain(DIRECTION).
|
||
|
if (!this._finder) {
|
||
|
this.doFind(searchString, matchCase);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._finder.caseSensitive = matchCase;
|
||
|
this._finder.findAgain(findBackwards, false, false);
|
||
|
},
|
||
|
|
||
|
onFindResult: function(aData) {
|
||
|
if (aData.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
|
||
|
if (this._viewportChanged) {
|
||
|
if (this._targetTab != BrowserApp.selectedTab) {
|
||
|
// this should never happen
|
||
|
Cu.reportError("Warning: selected tab changed during find!");
|
||
|
// fall through and restore viewport on the initial tab anyway
|
||
|
}
|
||
|
this._targetTab.setViewport(JSON.parse(this._initialViewport));
|
||
|
this._targetTab.sendViewportUpdate();
|
||
|
}
|
||
|
} else {
|
||
|
// Disabled until bug 1014113 is fixed
|
||
|
// ZoomHelper.zoomToRect(aData.rect);
|
||
|
this._viewportChanged = true;
|
||
|
}
|
||
|
}
|
||
|
};
|