зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1641287: Focus on browser after keyup. r=mak
Differential Revision: https://phabricator.services.mozilla.com/D92561
This commit is contained in:
Родитель
aa2ac69761
Коммит
df57cd5036
|
@ -698,7 +698,11 @@ function openLinkIn(url, where, params) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!focusUrlBar && targetBrowser == w.gBrowser.selectedBrowser) {
|
||||
if (
|
||||
!params.avoidBrowserFocus &&
|
||||
!focusUrlBar &&
|
||||
targetBrowser == w.gBrowser.selectedBrowser
|
||||
) {
|
||||
// Focus the content, but only if the browser used for the load is selected.
|
||||
targetBrowser.focus();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
ExtensionSearchHandler: "resource://gre/modules/ExtensionSearchHandler.jsm",
|
||||
ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
|
||||
ReaderMode: "resource://gre/modules/ReaderMode.jsm",
|
||||
PartnerLinkAttribution: "resource:///modules/PartnerLinkAttribution.jsm",
|
||||
SearchUtils: "resource://gre/modules/SearchUtils.jsm",
|
||||
|
@ -557,7 +558,7 @@ class UrlbarInput {
|
|||
isValidUrl = true;
|
||||
} catch (ex) {}
|
||||
if (isValidUrl) {
|
||||
this._loadURL(url, where, openParams);
|
||||
this._loadURL(url, event, where, openParams);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -613,7 +614,7 @@ class UrlbarInput {
|
|||
browser.lastLocationChange == lastLocationChange
|
||||
) {
|
||||
openParams.postData = postData;
|
||||
this._loadURL(uri.spec, where, openParams, null, browser);
|
||||
this._loadURL(uri.spec, event, where, openParams, null, browser);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -696,7 +697,7 @@ class UrlbarInput {
|
|||
selType: "canonized",
|
||||
provider: result.providerName,
|
||||
});
|
||||
this._loadURL(this.value, where, openParams, browser);
|
||||
this._loadURL(this.value, event, where, openParams, browser);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -950,6 +951,7 @@ class UrlbarInput {
|
|||
|
||||
this._loadURL(
|
||||
url,
|
||||
event,
|
||||
where,
|
||||
openParams,
|
||||
{
|
||||
|
@ -2266,6 +2268,8 @@ class UrlbarInput {
|
|||
*
|
||||
* @param {string} url
|
||||
* The URL to open.
|
||||
* @param {Event} event
|
||||
* The event that triggered to load the url.
|
||||
* @param {string} openUILinkWhere
|
||||
* Where we expect the result to be opened.
|
||||
* @param {object} params
|
||||
|
@ -2287,6 +2291,7 @@ class UrlbarInput {
|
|||
*/
|
||||
_loadURL(
|
||||
url,
|
||||
event,
|
||||
openUILinkWhere,
|
||||
params,
|
||||
resultDetails = null,
|
||||
|
@ -2345,10 +2350,19 @@ class UrlbarInput {
|
|||
params.initiatingDoc = this.window.document;
|
||||
}
|
||||
|
||||
if (event?.keyCode === KeyEvent.DOM_VK_RETURN) {
|
||||
if (openUILinkWhere === "current") {
|
||||
params.avoidBrowserFocus = true;
|
||||
this._keyDownEnterDeferred?.resolve(browser);
|
||||
}
|
||||
}
|
||||
|
||||
// Focus the content area before triggering loads, since if the load
|
||||
// occurs in a new tab, we want focus to be restored to the content
|
||||
// area when the current tab is re-selected.
|
||||
browser.focus();
|
||||
if (!params.avoidBrowserFocus) {
|
||||
browser.focus();
|
||||
}
|
||||
|
||||
if (openUILinkWhere != "current") {
|
||||
this.handleRevert();
|
||||
|
@ -2704,6 +2718,13 @@ class UrlbarInput {
|
|||
this.window.UpdatePopupNotificationsVisibility();
|
||||
}
|
||||
|
||||
// If user move the focus to another component while pressing Enter key,
|
||||
// then keyup at that component, as we can't get the event, clear the promise.
|
||||
if (this._keyDownEnterDeferred) {
|
||||
this._keyDownEnterDeferred.resolve();
|
||||
this._keyDownEnterDeferred = null;
|
||||
}
|
||||
|
||||
Services.obs.notifyObservers(null, "urlbar-blur");
|
||||
}
|
||||
|
||||
|
@ -3030,6 +3051,13 @@ class UrlbarInput {
|
|||
}
|
||||
|
||||
_on_keydown(event) {
|
||||
if (event.keyCode === KeyEvent.DOM_VK_RETURN) {
|
||||
if (this._keyDownEnterDeferred) {
|
||||
this._keyDownEnterDeferred.reject();
|
||||
}
|
||||
this._keyDownEnterDeferred = PromiseUtils.defer();
|
||||
}
|
||||
|
||||
// Due to event deferring, it's possible preventDefault() won't be invoked
|
||||
// soon enough to actually prevent some of the default behaviors, thus we
|
||||
// have to handle the event "twice". This first immediate call passes false
|
||||
|
@ -3046,7 +3074,25 @@ class UrlbarInput {
|
|||
});
|
||||
}
|
||||
|
||||
_on_keyup(event) {
|
||||
async _on_keyup(event) {
|
||||
if (
|
||||
event.keyCode === KeyEvent.DOM_VK_RETURN &&
|
||||
this._keyDownEnterDeferred
|
||||
) {
|
||||
try {
|
||||
const loadingBrowser = await this._keyDownEnterDeferred.promise;
|
||||
// Ensure the selected browser didn't change in the meanwhile.
|
||||
if (this.window.gBrowser.selectedBrowser === loadingBrowser) {
|
||||
loadingBrowser.focus();
|
||||
}
|
||||
} catch (ex) {
|
||||
// Not all the Enter actions in the urlbar will cause a navigation, then it
|
||||
// is normal for this to be rejected.
|
||||
}
|
||||
this._keyDownEnterDeferred = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this._toggleActionOverride(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,19 @@
|
|||
const TEST_VALUE = "example.com/\xF7?\xF7";
|
||||
const START_VALUE = "example.com/%C3%B7?%C3%B7";
|
||||
|
||||
add_task(async function setup() {
|
||||
const engine = await SearchTestUtils.promiseNewSearchEngine(
|
||||
getRootDirectory(gTestPath) + "searchSuggestionEngine.xml"
|
||||
);
|
||||
|
||||
const defaultEngine = Services.search.defaultEngine;
|
||||
Services.search.defaultEngine = engine;
|
||||
|
||||
registerCleanupFunction(async function() {
|
||||
Services.search.defaultEngine = defaultEngine;
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function returnKeypress() {
|
||||
info("Simple return keypress");
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, START_VALUE);
|
||||
|
@ -82,11 +95,7 @@ add_task(async function altGrReturnKeypress() {
|
|||
|
||||
add_task(async function searchOnEnterNoPick() {
|
||||
info("Search on Enter without picking a urlbar result");
|
||||
let engine = await SearchTestUtils.promiseNewSearchEngine(
|
||||
getRootDirectory(gTestPath) + "searchSuggestionEngine.xml"
|
||||
);
|
||||
let defaultEngine = Services.search.defaultEngine;
|
||||
Services.search.defaultEngine = engine;
|
||||
|
||||
// Why is BrowserTestUtils.openNewForegroundTab not causing the bug?
|
||||
let promiseTabOpened = BrowserTestUtils.waitForEvent(
|
||||
gBrowser.tabContainer,
|
||||
|
@ -95,10 +104,6 @@ add_task(async function searchOnEnterNoPick() {
|
|||
EventUtils.synthesizeMouseAtCenter(gBrowser.tabContainer.newTabButton, {});
|
||||
let openEvent = await promiseTabOpened;
|
||||
let tab = openEvent.target;
|
||||
registerCleanupFunction(async function() {
|
||||
Services.search.defaultEngine = defaultEngine;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
let loadPromise = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
|
@ -120,4 +125,77 @@ add_task(async function searchOnEnterNoPick() {
|
|||
gURLBar.untrimmedValue,
|
||||
"The location should have changed"
|
||||
);
|
||||
|
||||
// Cleanup.
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function searchOnEnterSoon() {
|
||||
info("Search on Enter as soon as typing a char");
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
START_VALUE
|
||||
);
|
||||
|
||||
const onLoad = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
const onBeforeUnload = SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[],
|
||||
() => {
|
||||
return new Promise(resolve => {
|
||||
content.window.addEventListener("beforeunload", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
const onResult = SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
|
||||
return new Promise(resolve => {
|
||||
content.window.addEventListener("keyup", () => {
|
||||
resolve("keyup");
|
||||
});
|
||||
content.window.addEventListener("unload", () => {
|
||||
resolve("unload");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Focus on the input field in urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {});
|
||||
const ownerDocument = gBrowser.selectedBrowser.ownerDocument;
|
||||
is(
|
||||
ownerDocument.activeElement,
|
||||
gURLBar.inputField,
|
||||
"The input field in urlbar has focus"
|
||||
);
|
||||
|
||||
info("Keydown a char and Enter");
|
||||
EventUtils.synthesizeKey("x", { type: "keydown" });
|
||||
EventUtils.synthesizeKey("KEY_Enter", { type: "keydown" });
|
||||
|
||||
// Wait for beforeUnload event in the content.
|
||||
await onBeforeUnload;
|
||||
is(
|
||||
ownerDocument.activeElement,
|
||||
gURLBar.inputField,
|
||||
"The input field in urlbar still has focus"
|
||||
);
|
||||
|
||||
// Keyup both key as soon as beforeUnload event happens.
|
||||
EventUtils.synthesizeKey("x", { type: "keyup" });
|
||||
EventUtils.synthesizeKey("KEY_Enter", { type: "keyup" });
|
||||
|
||||
// Wait for moving the focus.
|
||||
await TestUtils.waitForCondition(
|
||||
() => ownerDocument.activeElement === gBrowser.selectedBrowser
|
||||
);
|
||||
info("The focus is moved to the browser");
|
||||
|
||||
// Check whether keyup event is not captured before unload event happens.
|
||||
const result = await onResult;
|
||||
is(result, "unload", "Keyup event is not captured.");
|
||||
|
||||
// Cleanup.
|
||||
await onLoad;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче