зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset e53686543601 (bug 1303781) for timing out in browser_popupNotification_no_anchors.js
MozReview-Commit-ID: LbBFgw1LN9t
This commit is contained in:
Родитель
da09631fd3
Коммит
72740149e6
|
@ -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;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче