зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1669990 - SubDialog: Use system event listener for escape key. r=Gijs
If a <select> in a SubDialog closes its popup when the user hits the esc key, it calls `preventDefault()` on the event. The SubDialog code didn't see this preventDefault, because it was using a normal event listener, while the select code uses a system event listener. https://searchfox.org/mozilla-central/rev/c2e3ac11be4837718c2604e58085fbc8252b69dd/layout/forms/nsListControlFrame.cpp#925,2058,2068-2069,2075-2076 Differential Revision: https://phabricator.services.mozilla.com/D93253
This commit is contained in:
Родитель
de79a8a3ce
Коммит
13ef0eb48a
|
@ -54,3 +54,65 @@ add_task(async function test_subdialog_esc_does_not_cancel_load() {
|
|||
ok(true, "Load completed");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that ESC on a SubDialog with an open dropdown doesn't close the dialog.
|
||||
*/
|
||||
add_task(async function test_subdialog_esc_on_dropdown_does_not_close_dialog() {
|
||||
await BrowserTestUtils.withNewTab("http://example.com", async function(
|
||||
browser
|
||||
) {
|
||||
// Open the test dialog
|
||||
let dialogBox = gBrowser.getTabDialogBox(browser);
|
||||
let dialogClose = dialogBox.open(TEST_DIALOG_PATH, {
|
||||
keepOpenSameOriginNav: true,
|
||||
});
|
||||
|
||||
let dialogs = dialogBox._dialogManager._dialogs;
|
||||
|
||||
is(dialogs.length, 1, "Dialog manager has a dialog.");
|
||||
|
||||
let dialog = dialogs[0];
|
||||
|
||||
info("Waiting for dialog to open.");
|
||||
await dialog._dialogReady;
|
||||
|
||||
// Open dropdown
|
||||
let select = dialog._frame.contentDocument.getElementById("select");
|
||||
let shownPromise = BrowserTestUtils.waitForEvent(
|
||||
select,
|
||||
"popupshowing",
|
||||
true
|
||||
);
|
||||
|
||||
info("Opening dropdown");
|
||||
select.focus();
|
||||
EventUtils.synthesizeKey("VK_SPACE", {}, dialog._frame.contentWindow);
|
||||
|
||||
await shownPromise;
|
||||
|
||||
let hiddenPromise = BrowserTestUtils.waitForEvent(
|
||||
select,
|
||||
"popuphiding",
|
||||
true
|
||||
);
|
||||
|
||||
// Race dropdown closing vs SubDialog close
|
||||
let race = Promise.race([
|
||||
hiddenPromise.then(() => true),
|
||||
dialogClose.then(() => false),
|
||||
]);
|
||||
|
||||
// Close the dropdown with esc key
|
||||
info("Hitting escape key.");
|
||||
await EventUtils.synthesizeKey("KEY_Escape");
|
||||
|
||||
let result = await race;
|
||||
ok(result, "Select closed first");
|
||||
|
||||
await new Promise(resolve => executeSoon(resolve));
|
||||
|
||||
ok(!dialog._isClosing, "Dialog is not closing");
|
||||
ok(dialog._openedURL, "Dialog is open");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
title="Sample sub-dialog" style="width: 32em; height: 5em;"
|
||||
onload="document.getElementById('textbox').focus();">
|
||||
title="Sample sub-dialog">
|
||||
<dialog id="subDialog">
|
||||
<script>
|
||||
document.addEventListener("dialogaccept", acceptSubdialog);
|
||||
|
@ -21,6 +20,11 @@
|
|||
|
||||
<html:input id="textbox" value="Default text" />
|
||||
|
||||
<html:select id="select">
|
||||
<html:option>Foo</html:option>
|
||||
<html:option>Bar</html:option>
|
||||
</html:select>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<button oncommand="window.close();" label="Close" />
|
||||
|
|
|
@ -772,7 +772,9 @@ SubDialog.prototype = {
|
|||
|
||||
_trapFocus() {
|
||||
this.focus();
|
||||
this._box.addEventListener("keydown", this, true);
|
||||
// Attach a system event listener so the dialog can cancel keydown events.
|
||||
// See Bug 1669990.
|
||||
this._box.addEventListener("keydown", this, { mozSystemGroup: true });
|
||||
this._closeButton?.addEventListener("keydown", this);
|
||||
|
||||
if (!this._window.isChromeWindow) {
|
||||
|
@ -781,7 +783,7 @@ SubDialog.prototype = {
|
|||
},
|
||||
|
||||
_untrapFocus() {
|
||||
this._box.removeEventListener("keydown", this, true);
|
||||
this._box.removeEventListener("keydown", this, { mozSystemGroup: true });
|
||||
this._closeButton?.removeEventListener("keydown", this);
|
||||
this._window.removeEventListener("focus", this, true);
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче