Backed out changeset e53686543601 (bug 1303781) for timing out in browser_popupNotification_no_anchors.js

MozReview-Commit-ID: LbBFgw1LN9t
This commit is contained in:
Phil Ringnalda 2017-05-17 18:52:56 -07:00
Родитель da09631fd3
Коммит 72740149e6
2 изменённых файлов: 39 добавлений и 157 удалений

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

@ -135,11 +135,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this.inputField.removeEventListener("overflow", this); this.inputField.removeEventListener("overflow", this);
this.inputField.removeEventListener("underflow", this); this.inputField.removeEventListener("underflow", this);
if (this._deferredKeyEventTimeout) {
clearTimeout(this._deferredKeyEventTimeout);
this._deferredKeyEventTimeout = null;
}
// Null out the one-offs' popup and textbox so that it cleans up its // Null out the one-offs' popup and textbox so that it cleans up its
// internal state for both. Most importantly, it removes the event // internal state for both. Most importantly, it removes the event
// listeners that it added to both. // listeners that it added to both.
@ -242,137 +237,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this.popup.selectedIndex = -1; this.popup.selectedIndex = -1;
break; break;
} }
if (!this.popup.disableKeyNavigation) { if (this.popup.popupOpen &&
if (this._keyCodesToDefer.has(aEvent.keyCode) && !this.popup.disableKeyNavigation &&
this._shouldDeferNextKeyEvent) { this.popup.handleKeyPress(aEvent)) {
this._deferKeyEvent(aEvent, "onKeyPress");
return false;
}
if (this.popup.popupOpen && this.popup.handleKeyPress(aEvent)) {
return true;
}
}
return this.handleKeyPress(aEvent);
]]></body>
</method>
<!--
Search results arrive asynchronously, which means that keypresses may
arrive before results do and therefore not have the effect the user
intends. That's especially likely to happen with the down arrow and
enter keys due to the one-off search buttons: if the user very quickly
pastes something in the input, presses the down arrow key, and then hits
enter, they are probably expecting to visit the first result. But if
there are no results, then pressing down and enter will trigger the
first one-off button. To prevent that undesirable behavior, certain
keys are buffered and deferred until more results arrive, at which time
they're replayed.
-->
<property name="_shouldDeferNextKeyEvent">
<getter><![CDATA[
let waitedLongEnough =
this._searchStartDate + this._deferredKeyEventTimeoutMs < Date.now();
if (waitedLongEnough && !this._deferredKeyEventTimeout) {
return false;
}
if (!this.gotResultForCurrentQuery) {
return true; return true;
} }
let maxResultsRemaining = return this.handleKeyPress(aEvent);
this.popup.maxResults - this.popup._matchCount;
let lastResultSelected =
this.popup.selectedIndex + 1 == this.popup._matchCount;
return maxResultsRemaining > 0 && lastResultSelected;
]]></getter>
</property>
<!--
Adds a key event to the deferred event queue.
@param event
The key event to defer.
@param methodName
The name of the method on `this` to call. It's expected to take
a single argument, the event.
-->
<method name="_deferKeyEvent">
<parameter name="event"/>
<parameter name="methodName"/>
<body><![CDATA[
// Somehow event.defaultPrevented ends up true for deferred events.
// autocomplete ignores defaultPrevented events, which means it would
// ignore replayed deferred events if we didn't tell it to bypass
// defaultPrevented. That's the purpose of this expando. If we could
// figure out what's setting defaultPrevented and prevent it, then we
// could get rid of this.
event.urlbarDeferred = true;
this._deferredKeyEventQueue.push({
methodName,
event,
searchString: this.mController.searchString,
});
]]></body>
</method>
<!-- The enter key is always deferred, so it's not included here. -->
<field name="_keyCodesToDefer">new Set([
Ci.nsIDOMKeyEvent.DOM_VK_DOWN,
Ci.nsIDOMKeyEvent.DOM_VK_TAB,
])</field>
<field name="_deferredKeyEventQueue">[]</field>
<field name="_deferredKeyEventTimeout">null</field>
<field name="_deferredKeyEventTimeoutMs">200</field>
<field name="_searchStartDate">0</field>
<!--
Replays the next deferred key event if possible. Otherwise, this sets
up a timeout to replay the events, since more results may never arrive.
-->
<method name="maybeReplayDeferredKeyEvents">
<body><![CDATA[
if (!this._deferredKeyEventQueue.length) {
return;
}
if (this._shouldDeferNextKeyEvent) {
if (!this._deferredKeyEventTimeout) {
this._deferredKeyEventTimeout = setTimeout(() => {
this._deferredKeyEventTimeout = null;
this._replayAllDeferredKeyEvents();
}, this._deferredKeyEventTimeoutMs);
}
return;
}
if (this._deferredKeyEventTimeout) {
clearTimeout(this._deferredKeyEventTimeout);
this._deferredKeyEventTimeout = null;
}
this._replayNextDeferredKeyEvent();
]]></body>
</method>
<method name="_replayNextDeferredKeyEvent">
<body><![CDATA[
let instance = this._deferredKeyEventQueue.shift();
if (!instance) {
return;
}
// Safety check: handle only if the search string didn't change.
if (this.mController.searchString == instance.searchString) {
this[instance.methodName](instance.event);
}
]]></body>
</method>
<method name="_replayAllDeferredKeyEvents">
<body><![CDATA[
if (!this._deferredKeyEventQueue.length) {
return;
}
this._replayNextDeferredKeyEvent();
setTimeout(() => {
this._replayAllDeferredKeyEvents();
});
]]></body> ]]></body>
</method> </method>
@ -680,7 +550,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// this.textValue may be an autofilled string. Search only with the // this.textValue may be an autofilled string. Search only with the
// portion that the user typed, if any, by preferring the autocomplete // portion that the user typed, if any, by preferring the autocomplete
// controller's searchString (including handleEnterInstance.searchString). // controller's searchString (including handleEnterInstance.searchString).
return this.handleEnterSearchString || return (this.handleEnterInstance && this.handleEnterInstance.searchString) ||
this.mController.searchString || this.mController.searchString ||
this.textValue; this.textValue;
]]></getter> ]]></getter>
@ -1270,12 +1140,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// a new search and we won't get a result. // a new search and we won't get a result.
if (this.mController.handleText()) { if (this.mController.handleText()) {
this.gotResultForCurrentQuery = false; this.gotResultForCurrentQuery = false;
this._searchStartDate = Date.now();
this._deferredKeyEventQueue = [];
if (this._deferredKeyEventTimeout) {
clearTimeout(this._deferredKeyEventTimeout);
this._deferredKeyEventTimeout = null;
}
} }
} }
this.resetActionType(); this.resetActionType();
@ -1299,22 +1163,25 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// However, if the default result is automatically selected, we // However, if the default result is automatically selected, we
// ensure that it corresponds to the current input. // ensure that it corresponds to the current input.
// Store the current search string so it can be used in handleCommand, // Store the current search string so it can be used in
// which will be called as a result of mController.handleEnter(). // handleCommand, which will be called as a result of
this.handleEnterSearchString = this.mController.searchString; // mController.handleEnter().
// Note this is also used to detect if we should perform a delayed
// handleEnter, in such a case it won't have been cleared.
this.handleEnterInstance = {
searchString: this.mController.searchString,
event
};
if (!this._deferredKeyEventQueue.length && if (this.popup.selectedIndex != 0 || this.gotResultForCurrentQuery) {
(this.popup.selectedIndex != 0 || this.gotResultForCurrentQuery)) {
this.maybeCanonizeURL(event, this.value); this.maybeCanonizeURL(event, this.value);
let handled = this.mController.handleEnter(false, event); let rv = this.mController.handleEnter(false, event);
this.handleEnterSearchString = null; this.handleEnterInstance = null;
this.popup.overrideValue = null; this.popup.overrideValue = null;
return handled; return rv;
} }
// Defer the event until the first non-heuristic result comes in. return true;
this._deferKeyEvent(event, "handleEnter");
return false;
]]></body> ]]></body>
</method> </method>
@ -2026,7 +1893,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
this.oneOffSearchButtons.handleKeyPress(aEvent, this._matchCount, this.oneOffSearchButtons.handleKeyPress(aEvent, this._matchCount,
!this._isFirstResultHeuristic, !this._isFirstResultHeuristic,
gBrowser.userTypedValue); gBrowser.userTypedValue);
return aEvent.defaultPrevented && !aEvent.urlbarDeferred; return aEvent.defaultPrevented;
]]></body> ]]></body>
</method> </method>
@ -2104,7 +1971,23 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
} }
this.input.gotResultForCurrentQuery = true; this.input.gotResultForCurrentQuery = true;
this.input.maybeReplayDeferredKeyEvents();
// Check if we should perform a delayed handleEnter.
if (this.input.handleEnterInstance) {
let instance = this.input.handleEnterInstance;
this.input.handleEnterInstance = null;
// Don't handle this immediately or we could cause a recursive
// loop where the controller sets popupOpen and re-enters here.
setTimeout(() => {
// Safety check: handle only if the search string didn't change.
let { event, searchString } = instance;
if (this.input.mController.searchString == searchString) {
this.input.maybeCanonizeURL(event, searchString);
this.input.mController.handleEnter(false, event);
this.overrideValue = null;
}
}, 0);
}
]]> ]]>
</body> </body>
</method> </method>

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

@ -476,10 +476,9 @@
if (aEvent.target.localName != "textbox") if (aEvent.target.localName != "textbox")
return true; // Let child buttons of autocomplete take input return true; // Let child buttons of autocomplete take input
// Re: urlbarDeferred, see the comment in urlbarBindings.xml. // XXXpch this is so bogus...
if (aEvent.defaultPrevented && !aEvent.urlbarDeferred) { if (aEvent.defaultPrevented)
return false; return false;
}
var cancel = false; var cancel = false;