Bug 1093571 - Cancel pending GetSuggestion events when we receive a Search request. r=adw

This commit is contained in:
byron jones 2015-10-23 14:03:55 -04:00
Родитель b44ed5f63d
Коммит 9e02c3ec3d
2 изменённых файлов: 50 добавлений и 0 удалений

Просмотреть файл

@ -576,6 +576,12 @@ ContentSearchUIController.prototype = {
}
},
_onMsgSuggestionsCancelled: function () {
if (!this._table.hidden) {
this._hideSuggestions();
}
},
_onMsgState: function (state) {
this.engines = state.engines;
// No point updating the default engine (and the header) if there's no change.

Просмотреть файл

@ -56,6 +56,8 @@ const MAX_SUGGESTIONS = 6;
* data: the entry, a string
* Search
* Performs a search.
* Any GetSuggestions messages in the queue from the same target will be
* cancelled.
* data: { engineName, searchString, healthReportKey, searchPurpose }
* SetCurrentEngine
* Sets the current engine.
@ -81,6 +83,10 @@ const MAX_SUGGESTIONS = 6;
* Suggestions
* Sent in reply to GetSuggestions.
* data: see _onMessageGetSuggestions
* SuggestionsCancelled
* Sent in reply to GetSuggestions when pending GetSuggestions events are
* cancelled.
* data: null
*/
this.ContentSearch = {
@ -98,6 +104,10 @@ this.ContentSearch = {
// Resolved when we finish shutting down.
_destroyedPromise: null,
// The current controller and browser in _onMessageGetSuggestions. Allows
// fetch cancellation from _cancelSuggestions.
_currentSuggestion: null,
init: function () {
Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager).
@ -165,6 +175,12 @@ this.ContentSearch = {
};
msg.target.addEventListener("SwapDocShells", msg, true);
// Search requests cause cancellation of all Suggestion requests from the
// same browser.
if (msg.data.type == "Search") {
this._cancelSuggestions(msg);
}
this._eventQueue.push({
type: "Message",
data: msg,
@ -208,6 +224,27 @@ this.ContentSearch = {
}.bind(this));
},
_cancelSuggestions: function (msg) {
let cancelled = false;
// cancel active suggestion request
if (this._currentSuggestion && this._currentSuggestion.target == msg.target) {
this._currentSuggestion.controller.stop();
cancelled = true;
}
// cancel queued suggestion requests
for (let i = 0; i < this._eventQueue.length; i++) {
let m = this._eventQueue[i].data;
if (msg.target == m.target && m.data.type == "GetSuggestions") {
this._eventQueue.splice(i, 1);
cancelled = true;
i--;
}
}
if (cancelled) {
this._reply(msg, "SuggestionsCancelled");
}
},
_onMessage: Task.async(function* (msg) {
let methodName = "_onMessage" + msg.data.type;
if (methodName in this) {
@ -302,7 +339,14 @@ this.ContentSearch = {
let priv = PrivateBrowsingUtils.isBrowserPrivate(msg.target);
// fetch() rejects its promise if there's a pending request, but since we
// process our event queue serially, there's never a pending request.
this._currentSuggestion = { controller: controller, target: msg.target };
let suggestions = yield controller.fetch(data.searchString, priv, engine);
this._currentSuggestion = null;
// suggestions will be null if the request was cancelled
if (!suggestions) {
return;
}
// Keep the form history result so RemoveFormHistoryEntry can remove entries
// from it. Keeping only one result isn't foolproof because the client may