From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../content/test/general/browser_accesskeys.js | 202 +++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 browser/base/content/test/general/browser_accesskeys.js (limited to 'browser/base/content/test/general/browser_accesskeys.js') diff --git a/browser/base/content/test/general/browser_accesskeys.js b/browser/base/content/test/general/browser_accesskeys.js new file mode 100644 index 0000000000..c8b27d6307 --- /dev/null +++ b/browser/base/content/test/general/browser_accesskeys.js @@ -0,0 +1,202 @@ +add_task(async function () { + await pushPrefs(["ui.key.contentAccess", 5], ["ui.key.chromeAccess", 5]); + + const gPageURL1 = + "data:text/html,

" + + "" + + "Checkbox" + + "

"; + let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL1); + + Services.focus.clearFocus(window); + + // Press an accesskey in the child document while the chrome is focused. + let focusedId = await performAccessKey(tab1.linkedBrowser, "y"); + is(focusedId, "button", "button accesskey"); + + // Press an accesskey in the child document while the content document is focused. + focusedId = await performAccessKey(tab1.linkedBrowser, "z"); + is(focusedId, "checkbox", "checkbox accesskey"); + + // Add an element with an accesskey to the chrome and press its accesskey while the chrome is focused. + let newButton = document.createXULElement("button"); + newButton.id = "chromebutton"; + newButton.setAttribute("accesskey", "z"); + document.documentElement.appendChild(newButton); + + Services.focus.clearFocus(window); + + newButton.getBoundingClientRect(); // Accesskey registration happens during frame construction. + + focusedId = await performAccessKeyForChrome("z"); + is(focusedId, "chromebutton", "chromebutton accesskey"); + + // Add a second tab and ensure that accesskey from the first tab is not used. + const gPageURL2 = + "data:text/html," + + "" + + ""; + let tab2 = await BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL2); + + Services.focus.clearFocus(window); + + focusedId = await performAccessKey(tab2.linkedBrowser, "y"); + is(focusedId, "tab2button", "button accesskey in tab2"); + + // Press the accesskey for the chrome element while the content document is focused. + focusedId = await performAccessKeyForChrome("z"); + is(focusedId, "chromebutton", "chromebutton accesskey"); + + gBrowser.removeTab(tab1); + gBrowser.removeTab(tab2); + + // Test whether access key for the newButton isn't available when content + // consumes the key event. + + // When content in the tab3 consumes all keydown events. + const gPageURL3 = + "data:text/html," + + "" + + ""; + let tab3 = await BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL3); + + Services.focus.clearFocus(window); + + focusedId = await performAccessKey(tab3.linkedBrowser, "y"); + is(focusedId, "tab3button", "button accesskey in tab3 should be focused"); + + newButton.onfocus = () => { + ok(false, "chromebutton shouldn't get focus during testing with tab3"); + }; + + // Press the accesskey for the chrome element while the content document is focused. + focusedId = await performAccessKey(tab3.linkedBrowser, "z"); + is( + focusedId, + "tab3body", + "button accesskey in tab3 should keep having focus" + ); + + newButton.onfocus = null; + + gBrowser.removeTab(tab3); + + // When content in the tab4 consumes all keypress events. + const gPageURL4 = + "data:text/html," + + "" + + ""; + let tab4 = await BrowserTestUtils.openNewForegroundTab(gBrowser, gPageURL4); + + Services.focus.clearFocus(window); + + focusedId = await performAccessKey(tab4.linkedBrowser, "y"); + is(focusedId, "tab4button", "button accesskey in tab4 should be focused"); + + newButton.onfocus = () => { + // EventStateManager handles accesskey before dispatching keypress event + // into the DOM tree, therefore, chrome accesskey always wins focus from + // content. However, this is different from shortcut keys. + todo(false, "chromebutton shouldn't get focus during testing with tab4"); + }; + + // Press the accesskey for the chrome element while the content document is focused. + focusedId = await performAccessKey(tab4.linkedBrowser, "z"); + is( + focusedId, + "tab4body", + "button accesskey in tab4 should keep having focus" + ); + + newButton.onfocus = null; + + gBrowser.removeTab(tab4); + + newButton.remove(); +}); + +function performAccessKey(browser, key) { + return new Promise(resolve => { + let removeFocus, removeKeyDown, removeKeyUp; + function callback(eventName, result) { + removeFocus(); + removeKeyUp(); + removeKeyDown(); + + SpecialPowers.spawn(browser, [], () => { + let oldFocusedElement = content._oldFocusedElement; + delete content._oldFocusedElement; + return oldFocusedElement.id; + }).then(oldFocus => resolve(oldFocus)); + } + + removeFocus = BrowserTestUtils.addContentEventListener( + browser, + "focus", + callback, + { capture: true }, + event => { + if (!HTMLElement.isInstance(event.target)) { + return false; // ignore window and document focus events + } + + event.target.ownerGlobal._sent = true; + let focusedElement = event.target.ownerGlobal.document.activeElement; + event.target.ownerGlobal._oldFocusedElement = focusedElement; + focusedElement.blur(); + return true; + } + ); + + removeKeyDown = BrowserTestUtils.addContentEventListener( + browser, + "keydown", + () => {}, + { capture: true }, + event => { + event.target.ownerGlobal._sent = false; + return true; + } + ); + + removeKeyUp = BrowserTestUtils.addContentEventListener( + browser, + "keyup", + callback, + {}, + event => { + if (!event.target.ownerGlobal._sent) { + event.target.ownerGlobal._sent = true; + let focusedElement = event.target.ownerGlobal.document.activeElement; + event.target.ownerGlobal._oldFocusedElement = focusedElement; + focusedElement.blur(); + return true; + } + + return false; + } + ); + + // Spawn an no-op content task to better ensure that the messages + // for adding the event listeners above get handled. + SpecialPowers.spawn(browser, [], () => {}).then(() => { + EventUtils.synthesizeKey(key, { altKey: true, shiftKey: true }); + }); + }); +} + +// This version is used when a chrome element is expected to be found for an accesskey. +async function performAccessKeyForChrome(key, inChild) { + let waitFocusChangePromise = BrowserTestUtils.waitForEvent( + document, + "focus", + true + ); + EventUtils.synthesizeKey(key, { altKey: true, shiftKey: true }); + await waitFocusChangePromise; + return document.activeElement.id; +} -- cgit v1.2.3