зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1303008 - refactor Fennec Finder.jsm integration to always show the correct match count results in the findbar. r=nalexander
MozReview-Commit-ID: KZIstsbHAyT --HG-- extra : rebase_source : 24972d38daa947d62410b43d14f0da6c7662e5da
This commit is contained in:
Родитель
114a132b2e
Коммит
05f70d10ef
|
@ -67,7 +67,9 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
|||
mStatusText = (TextView) content.findViewById(R.id.find_status);
|
||||
|
||||
mInflated = true;
|
||||
GeckoApp.getEventDispatcher().registerGeckoThreadListener(this, "TextSelection:Data");
|
||||
GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
|
||||
"FindInPage:MatchesCountResult",
|
||||
"TextSelection:Data");
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
@ -110,7 +112,34 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
|||
if (!mInflated) {
|
||||
return;
|
||||
}
|
||||
GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this, "TextSelection:Data");
|
||||
GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
|
||||
"FindInPage:MatchesCountResult",
|
||||
"TextSelection:Data");
|
||||
}
|
||||
|
||||
private void onMatchesCountResult(final int total, final int current, final int limit, final String searchString) {
|
||||
if (total == -1) {
|
||||
updateResult(Integer.toString(limit) + "+");
|
||||
} else if (total > 0) {
|
||||
updateResult(Integer.toString(current) + "/" + Integer.toString(total));
|
||||
} else if (TextUtils.isEmpty(searchString)) {
|
||||
updateResult("");
|
||||
} else {
|
||||
// We display 0/0, when there were no
|
||||
// matches found, or if matching has been turned off by setting
|
||||
// pref accessibility.typeaheadfind.matchesCountLimit to 0.
|
||||
updateResult("0/0");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateResult(final String statusText) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mStatusText.setVisibility(statusText.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mStatusText.setText(statusText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TextWatcher implementation
|
||||
|
@ -160,6 +189,14 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
|||
|
||||
@Override
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
if (event.equals("FindInPage:MatchesCountResult")) {
|
||||
onMatchesCountResult(message.optInt("total", 0),
|
||||
message.optInt("current", 0),
|
||||
message.optInt("limit", 0),
|
||||
message.optString("searchString"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.equals("TextSelection:Data") || !REQUEST_ID.equals(message.optString("requestId"))) {
|
||||
return;
|
||||
}
|
||||
|
@ -203,21 +240,8 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
|||
GeckoAppShell.sendRequestToGecko(new GeckoRequest(request, searchString) {
|
||||
@Override
|
||||
public void onResponse(NativeJSObject nativeJSObject) {
|
||||
final int total = nativeJSObject.optInt("total", 0);
|
||||
if (total == -1) {
|
||||
final int limit = nativeJSObject.optInt("limit", 0);
|
||||
updateResult(Integer.toString(limit) + "+");
|
||||
} else if (total > 0) {
|
||||
final int current = nativeJSObject.optInt("current", 0);
|
||||
updateResult(Integer.toString(current) + "/" + Integer.toString(total));
|
||||
} else if (TextUtils.isEmpty(searchString)) {
|
||||
updateResult("");
|
||||
} else {
|
||||
// We display 0/0, when there were no
|
||||
// matches found, or if matching has been turned off by setting
|
||||
// pref accessibility.typeaheadfind.matchesCountLimit to 0.
|
||||
updateResult("0/0");
|
||||
}
|
||||
// We don't care about the return value, because `onMatchesCountResult`
|
||||
// does the heavy lifting.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -227,16 +251,6 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
|||
searchString + "]");
|
||||
updateResult("");
|
||||
}
|
||||
|
||||
private void updateResult(final String statusText) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mStatusText.setVisibility(statusText.isEmpty() ? View.GONE : View.VISIBLE);
|
||||
mStatusText.setText(statusText);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ var FindHelper = {
|
|||
_initialViewport: null,
|
||||
_viewportChanged: false,
|
||||
_result: null,
|
||||
_limit: 0,
|
||||
|
||||
// Start of nsIObserver implementation.
|
||||
|
||||
observe: function(aMessage, aTopic, aData) {
|
||||
switch(aTopic) {
|
||||
|
@ -31,34 +32,25 @@ var FindHelper = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* When the FindInPageBar opens/ becomes visible, it's time to:
|
||||
* 1. Add listeners for other message types sent from the FindInPageBar
|
||||
* 2. initialize the Finder instance, if necessary.
|
||||
*/
|
||||
_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);
|
||||
return this._getMatchesCountResult(data);
|
||||
}, "FindInPage:Find");
|
||||
|
||||
Messaging.addListener((data) => {
|
||||
this.findAgain(data, false);
|
||||
return this._getMatchesCountResult(data);
|
||||
}, "FindInPage:Next");
|
||||
|
||||
Messaging.addListener((data) => {
|
||||
this.findAgain(data, true);
|
||||
return this._getMatchesCountResult(data);
|
||||
}, "FindInPage:Prev");
|
||||
Messaging.addListener(data => this.doFind(data), "FindInPage:Find");
|
||||
Messaging.addListener(data => this.findAgain(data, false), "FindInPage:Next");
|
||||
Messaging.addListener(data => this.findAgain(data, true), "FindInPage:Prev");
|
||||
|
||||
// Initialize the finder component for the current page by performing a fake find.
|
||||
this._init();
|
||||
this._finder.requestMatchesCount("", 1);
|
||||
this._finder.requestMatchesCount("");
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the Finder instance from the active tabs' browser and start tracking
|
||||
* the active viewport.
|
||||
*/
|
||||
_init: function() {
|
||||
// If there's no find in progress, start one.
|
||||
if (this._finder) {
|
||||
|
@ -78,6 +70,10 @@ var FindHelper = {
|
|||
this._viewportChanged = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach from the Finder instance (so stop listening for messages) and stop
|
||||
* tracking the active viewport.
|
||||
*/
|
||||
_uninit: function() {
|
||||
// If there's no find in progress, there's nothing to clean up.
|
||||
if (!this._finder) {
|
||||
|
@ -92,6 +88,9 @@ var FindHelper = {
|
|||
this._viewportChanged = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* When the FindInPageBar closes, it's time to stop listening for its messages.
|
||||
*/
|
||||
_findClosed: function() {
|
||||
Messaging.removeListener("FindInPage:Find");
|
||||
Messaging.removeListener("FindInPage:Next");
|
||||
|
@ -99,47 +98,86 @@ var FindHelper = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Request, wait for, and return the current matchesCount results for a string.
|
||||
* Start an asynchronous find-in-page operation, using the current Finder
|
||||
* instance and request to count the amount of matches.
|
||||
* If no Finder instance is currently active, we'll lazily initialize it here.
|
||||
*
|
||||
* @param {String} searchString Word to search for in the current document
|
||||
* @return {Object} Echo of the current find action
|
||||
*/
|
||||
_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) {
|
||||
if (!this._finder) {
|
||||
this._init();
|
||||
}
|
||||
|
||||
this._finder.fastFind(searchString, false);
|
||||
return { searchString, findBackwards: false };
|
||||
},
|
||||
|
||||
/**
|
||||
* Restart the same find-in-page operation as before via `doFind()`. If we
|
||||
* haven't called `doFind()`, we simply kick off a regular find.
|
||||
*
|
||||
* @param {String} searchString Word to search for in the current document
|
||||
* @param {Boolean} findBackwards Direction to search in
|
||||
* @return {Object} Echo of the current find action
|
||||
*/
|
||||
findAgain: function(searchString, findBackwards) {
|
||||
// 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);
|
||||
return;
|
||||
return this.doFind(searchString);
|
||||
}
|
||||
|
||||
this._finder.findAgain(findBackwards, false, false);
|
||||
return { searchString, findBackwards };
|
||||
},
|
||||
|
||||
// Start of Finder.jsm listener implementation.
|
||||
|
||||
/**
|
||||
* Pass along the count results to FindInPageBar for display. The result that
|
||||
* is sent to the FindInPageBar is augmented with the current find-in-page count
|
||||
* limit.
|
||||
*
|
||||
* @param {Object} result Result coming from the Finder instance that contains
|
||||
* the following properties:
|
||||
* - {Number} total The total amount of matches found
|
||||
* - {Number} current The index of current found range
|
||||
* in the document
|
||||
*/
|
||||
onMatchesCountResult: function(result) {
|
||||
this._result = result;
|
||||
|
||||
Messaging.sendRequest(Object.assign({
|
||||
type: "FindInPage:MatchesCountResult"
|
||||
}, this._result));
|
||||
},
|
||||
|
||||
/**
|
||||
* When a find-in-page action finishes, this method is invoked. This is mainly
|
||||
* used at the moment to detect if the current viewport has changed, which might
|
||||
* be indicated by not finding a string in the current page.
|
||||
*
|
||||
* @param {Object} aData A dictionary, representing the find result, which
|
||||
* contains the following properties:
|
||||
* - {String} searchString Word that was searched for
|
||||
* in the current document
|
||||
* - {Number} result One of the following
|
||||
* Ci.nsITypeAheadFind.* result
|
||||
* indicators: FIND_FOUND,
|
||||
* FIND_NOTFOUND, FIND_WRAPPED,
|
||||
* FIND_PENDING
|
||||
* - {Boolean} findBackwards Whether the search direction
|
||||
* was backwards
|
||||
* - {Boolean} findAgain Whether the previous search
|
||||
* was repeated
|
||||
* - {Boolean} drawOutline Whether we may (re-)draw the
|
||||
* outline of a hyperlink
|
||||
* - {Boolean} linksOnly Whether links-only mode was
|
||||
* active
|
||||
*/
|
||||
onFindResult: function(aData) {
|
||||
if (aData.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
|
||||
if (this._viewportChanged) {
|
||||
|
|
|
@ -374,8 +374,6 @@
|
|||
prefsvc.getIntPref("accessibility.typeaheadfind.timeout");
|
||||
this._flashFindBar =
|
||||
prefsvc.getIntPref("accessibility.typeaheadfind.flashBar");
|
||||
this._matchesCountLimit =
|
||||
prefsvc.getIntPref("accessibility.typeaheadfind.matchesCountLimit");
|
||||
this._useModalHighlight = prefsvc.getBoolPref("findbar.modalHighlight");
|
||||
|
||||
prefsvc.addObserver("accessibility.typeaheadfind",
|
||||
|
@ -1309,9 +1307,9 @@
|
|||
if (aResult.total !== 0) {
|
||||
if (aResult.total == -1) {
|
||||
this._foundMatches.value = this.pluralForm.get(
|
||||
this._matchesCountLimit,
|
||||
aResult.limit,
|
||||
this.strBundle.GetStringFromName("FoundMatchesCountLimit")
|
||||
).replace("#1", this._matchesCountLimit);
|
||||
).replace("#1", aResult.limit);
|
||||
} else {
|
||||
this._foundMatches.value = this.pluralForm.get(
|
||||
aResult.total,
|
||||
|
|
|
@ -394,7 +394,8 @@ Finder.prototype = {
|
|||
_notifyMatchesCount: function(result = this._currentMatchesCountResult) {
|
||||
// The `_currentFound` property is only used for internal bookkeeping.
|
||||
delete result._currentFound;
|
||||
if (result.total == this.matchesCountLimit)
|
||||
result.limit = this.matchesCountLimit;
|
||||
if (result.total == result.limit)
|
||||
result.total = -1;
|
||||
|
||||
for (let l of this._listeners) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче