Bug 1446551 - "too much recursion" when pressing enter in location bar. r=mak

MozReview-Commit-ID: C8xhlyXOVC2

--HG--
extra : rebase_source : ec83c04cbc59d4bedb159747bb263390a4602dd5
This commit is contained in:
Drew Willcoxon 2018-04-18 16:21:18 -07:00
Родитель 69a70b3ac2
Коммит 338f448862
1 изменённых файлов: 43 добавлений и 35 удалений

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

@ -255,6 +255,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="onKeyPress">
<parameter name="aEvent"/>
<parameter name="aNoDefer"/>
<body><![CDATA[
switch (aEvent.keyCode) {
case KeyEvent.DOM_VK_LEFT:
@ -276,7 +277,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
break;
}
if (!this.popup.disableKeyNavigation) {
if (this._shouldDeferKeyEvent(aEvent)) {
if (!aNoDefer && this._shouldDeferKeyEvent(aEvent)) {
this._deferKeyEvent(aEvent, "onKeyPress");
return false;
}
@ -309,9 +310,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<body><![CDATA[
// If any event has been deferred for this search, then defer all
// subsequent events so that the user does not experience any
// keypresses out of order. All events will be replayed when this
// timeout fires.
if (this._deferredKeyEventTimeout) {
// keypresses out of order. All events will be replayed when
// _deferredKeyEventTimeout fires.
if (this._deferredKeyEventQueue.length) {
return true;
}
@ -356,6 +357,11 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="_safeToPlayDeferredKeyEvent">
<parameter name="event"/>
<body><![CDATA[
if (event.keyCode == KeyEvent.DOM_VK_RETURN) {
return this.popup.selectedIndex != 0 ||
this.gotResultForCurrentQuery;
}
if (!this.gotResultForCurrentQuery || !this.popupOpen) {
// We're still waiting on the first result, or the popup hasn't
// opened yet, so not safe.
@ -390,7 +396,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
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.
two arguments: the event, and a noDefer bool. If the bool is
true, then the event is being replayed and it should not be
deferred.
-->
<method name="_deferKeyEvent">
<parameter name="event"/>
@ -402,6 +410,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// 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.
if (event.urlbarDeferred) {
throw new Error("Key event already deferred!");
}
event.urlbarDeferred = true;
this._deferredKeyEventQueue.push({
@ -419,20 +430,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// the user's input.
let elapsed = Cu.now() - this._searchStartDate;
let remaining = this._deferredKeyEventTimeoutMs - elapsed;
if (remaining <= 0) {
this._deferredKeyEventTimeout = setTimeout(() => {
this.replayAllDeferredKeyEvents();
} else {
this._deferredKeyEventTimeout = setTimeout(() => {
this.replayAllDeferredKeyEvents();
this._deferredKeyEventTimeout = null;
}, remaining);
}
this._deferredKeyEventTimeout = null;
}, Math.max(0, remaining));
}
]]></body>
</method>
<!-- The enter key is always deferred, so it's not included here. -->
<field name="_keyCodesToDefer">new Set([
KeyboardEvent.DOM_VK_RETURN,
KeyboardEvent.DOM_VK_DOWN,
KeyboardEvent.DOM_VK_TAB,
])</field>
@ -482,7 +490,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<body><![CDATA[
// Safety check: handle only if the search string didn't change.
if (this.mController.searchString == instance.searchString) {
this[instance.methodName](instance.event);
this[instance.methodName](instance.event, true);
}
]]></body>
</method>
@ -1481,6 +1489,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<method name="handleEnter">
<parameter name="event"/>
<parameter name="noDefer"/>
<body><![CDATA[
// We need to ensure we're using a selected autocomplete result.
// A result should automatically be selected by default,
@ -1500,30 +1509,29 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
// which will be called as a result of mController.handleEnter().
this.handleEnterSearchString = this.mController.searchString;
if (!this._deferredKeyEventQueue.length &&
(this.popup.selectedIndex != 0 || this.gotResultForCurrentQuery)) {
let canonizeValue = this.value;
if (event.shiftKey || (AppConstants.platform === "macosx" ?
event.metaKey :
event.ctrlKey)) {
let action = this._parseActionUrl(canonizeValue);
if (action && "searchSuggestion" in action.params) {
canonizeValue = action.params.searchSuggestion;
} else if (this.popup.selectedIndex === 0 &&
this.mController.getStyleAt(0).includes("autofill")) {
canonizeValue = this.handleEnterSearchString;
}
}
this.maybeCanonizeURL(event, canonizeValue);
let handled = this.mController.handleEnter(false, event);
this.handleEnterSearchString = null;
this.popup.overrideValue = null;
return handled;
if (!noDefer && this._shouldDeferKeyEvent(event)) {
// Defer the event until the first non-heuristic result comes in.
this._deferKeyEvent(event, "handleEnter");
return false;
}
// Defer the event until the first non-heuristic result comes in.
this._deferKeyEvent(event, "handleEnter");
return false;
let canonizeValue = this.value;
if (event.shiftKey || (AppConstants.platform === "macosx" ?
event.metaKey :
event.ctrlKey)) {
let action = this._parseActionUrl(canonizeValue);
if (action && "searchSuggestion" in action.params) {
canonizeValue = action.params.searchSuggestion;
} else if (this.popup.selectedIndex === 0 &&
this.mController.getStyleAt(0).includes("autofill")) {
canonizeValue = this.handleEnterSearchString;
}
}
this.maybeCanonizeURL(event, canonizeValue);
let handled = this.mController.handleEnter(false, event);
this.handleEnterSearchString = null;
this.popup.overrideValue = null;
return handled;
]]></body>
</method>