Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

"use strict";
add_setup(async () => {
await SpecialPowers.pushPrefEnv({
set: [
["dom.fullscreen.keyboard_lock.enabled", true],
["dom.fullscreen.keyboard_lock.long_press_interval", 0],
],
});
});
/**
* With keyboard lock
* - ctrl+N should reach the web content
* - ctrl+T should reach the web content
* And because e.preventDefault()
* - with ctrl+N not get a new window
* - with ctrl+T not get a new tab
*/
add_task(async function test_reserved_shortcuts_prevented_by_content() {
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
await DOMFullscreenTestUtils.changeFullscreen(browser, true, {
keyboardLock: "browser",
});
// Ctrl+T: content prevents default → no new tab should open.
await SpecialPowers.spawn(browser, [], () => {
content.window.reservedKeyReceived = null;
content.addEventListener(
"keydown",
e => {
content.window.reservedKeyReceived = e.key;
e.preventDefault();
},
{ once: true }
);
});
let initialTabCount = gBrowser.tabs.length;
let newTabOpened = false;
let tabOpenListener = () => {
newTabOpened = true;
};
gBrowser.tabContainer.addEventListener("TabOpen", tabOpenListener);
EventUtils.synthesizeKey("t", { accelKey: true }, browser.ownerGlobal);
// Waiting for content to confirm receipt also ensures the keyboard IPC
// reply has been processed by chrome (it is enqueued before this spawn's
// completion message reaches the parent).
let keyReceived = await SpecialPowers.spawn(browser, [], async () => {
const { ContentTaskUtils } = ChromeUtils.importESModule(
);
await ContentTaskUtils.waitForCondition(
() => content.window.reservedKeyReceived !== null,
"Waiting for Ctrl+T to reach content"
);
return content.window.reservedKeyReceived;
});
await TestUtils.waitForTick();
gBrowser.tabContainer.removeEventListener("TabOpen", tabOpenListener);
is(keyReceived, "t", "Ctrl+T keydown was dispatched to content");
ok(
!newTabOpened,
"Ctrl+T with keyboard lock and preventDefault() did not open a new tab"
);
is(
gBrowser.tabs.length,
initialTabCount,
"Tab count unchanged after Ctrl+T prevented by content"
);
await SpecialPowers.spawn(browser, [], () => {
content.window.reservedKeyReceived = null;
content.addEventListener(
"keydown",
e => {
content.window.reservedKeyReceived = e.key;
e.preventDefault();
},
{ once: true }
);
});
let initialWindowCount = BrowserWindowTracker.orderedWindows.length;
let newWindowOpened = false;
let windowOpenListener = () => {
newWindowOpened = true;
};
Services.obs.addObserver(windowOpenListener, "domwindowopened");
EventUtils.synthesizeKey("n", { accelKey: true }, browser.ownerGlobal);
keyReceived = await SpecialPowers.spawn(browser, [], async () => {
const { ContentTaskUtils } = ChromeUtils.importESModule(
);
await ContentTaskUtils.waitForCondition(
() => content.window.reservedKeyReceived !== null,
"Waiting for Ctrl+N to reach content"
);
return content.window.reservedKeyReceived;
});
await TestUtils.waitForTick();
Services.obs.removeObserver(windowOpenListener, "domwindowopened");
is(keyReceived, "n", "Ctrl+N keydown was dispatched to content");
ok(
!newWindowOpened,
"Ctrl+N with keyboard lock and preventDefault() did not open a new window"
);
is(
BrowserWindowTracker.orderedWindows.length,
initialWindowCount,
"Window count unchanged after Ctrl+N prevented by content"
);
let fullScreenExited = BrowserTestUtils.waitForEvent(
document,
"fullscreenchange",
false,
() => !document.fullscreenElement
);
await SpecialPowers.spawn(browser, [], () =>
content.document.exitFullscreen()
);
await fullScreenExited;
});
});
/**
* With keyboard lock
* - ctrl+T should reach the web content
* And because web content does not e.preventDefault()
* - with ctrl+T produces a new tab
*/
add_task(async function test_reserved_shortcuts_not_prevented_by_content() {
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
await DOMFullscreenTestUtils.changeFullscreen(browser, true, {
keyboardLock: "browser",
});
await SpecialPowers.spawn(browser, [], () => {
content.window.reservedKeyReceived = null;
content.addEventListener(
"keydown",
e => {
content.window.reservedKeyReceived = e.key;
},
{ once: true }
);
});
let fullScreenExited = BrowserTestUtils.waitForEvent(
document,
"fullscreenchange",
false,
() => !document.fullscreenElement
);
// No prevent default, should give us an opened tab
let tabOpened = BrowserTestUtils.waitForEvent(
gBrowser.tabContainer,
"TabOpen"
);
EventUtils.synthesizeKey("t", { accelKey: true }, browser.ownerGlobal);
let newTab = (await tabOpened).target;
await fullScreenExited;
let keyReceived = await SpecialPowers.spawn(browser, [], () => {
return content.window.reservedKeyReceived;
});
is(keyReceived, "t", "Ctrl+T keydown was dispatched to content");
ok(newTab, "Ctrl+T without preventDefault() still opened a new tab");
await BrowserTestUtils.removeTab(newTab);
});
});
/**
* The platform's exit-fullscreen shortcut must remain unconditionally reserved
* even with keyboard lock active — it must exit fullscreen immediately and must
* NOT be dispatched to content.
* On macOS the shortcut is Cmd+Ctrl+F; on other platforms it is F11.
*/
add_task(async function test_fullscreen_exit_key_is_unconditionally_reserved() {
const { AppConstants } = ChromeUtils.importESModule(
"resource://gre/modules/AppConstants.sys.mjs"
);
const isMac = AppConstants.platform === "macosx";
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
await DOMFullscreenTestUtils.changeFullscreen(browser, true, {
keyboardLock: "browser",
});
await SpecialPowers.spawn(browser, [isMac], mac => {
content.window.exitKeyReceived = false;
content.addEventListener(
"keydown",
e => {
e.preventDefault();
const key = mac ? e.key === "f" || e.key === "F" : e.key === "F11";
if (key) {
content.window.exitKeyReceived = true;
}
},
{ once: true }
);
});
let fullScreenExited = BrowserTestUtils.waitForEvent(
document,
"fullscreenchange",
false,
() => !document.fullscreenElement
);
if (isMac) {
EventUtils.synthesizeKey(
"f",
{ accelKey: true, ctrlKey: true },
browser.ownerGlobal
);
} else {
EventUtils.synthesizeKey("KEY_F11", {}, browser.ownerGlobal);
}
await fullScreenExited;
await TestUtils.waitForTick();
let exitKeyReceived = await SpecialPowers.spawn(browser, [], () => {
return content.window.exitKeyReceived;
});
ok(
!exitKeyReceived,
"Fullscreen exit shortcut was not dispatched to content (it is unconditionally reserved)"
);
});
});
/**
* Without keyboard lock, reserved shortcuts execute their default action
* without being dispatched to content first.
* ctrl+t should have no effect, but also it should not be seen by content.
*/
add_task(async function test_reserved_shortcuts_without_keyboard_lock() {
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
await DOMFullscreenTestUtils.changeFullscreen(browser, true, {
keyboardLock: "none",
});
await SpecialPowers.spawn(browser, [], () => {
content.window.reservedKeyReceived = false;
content.addEventListener(
"keydown",
e => {
e.preventDefault();
if (e.key === "t") {
content.window.reservedKeyReceived = true;
}
},
{ once: true }
);
});
let fullScreenExited = BrowserTestUtils.waitForEvent(
document,
"fullscreenchange",
false,
() => !document.fullscreenElement
);
let tabOpened = BrowserTestUtils.waitForEvent(
gBrowser.tabContainer,
"TabOpen"
);
EventUtils.synthesizeKey("t", { accelKey: true }, browser.ownerGlobal);
let newTab = (await tabOpened).target;
await fullScreenExited;
await TestUtils.waitForTick();
let keyReceived = await SpecialPowers.spawn(browser, [], () => {
return content.window.reservedKeyReceived;
});
ok(newTab, "Ctrl+T without keyboard lock opened a new tab");
ok(
!keyReceived,
"Ctrl+T without keyboard lock was not dispatched to content"
);
await BrowserTestUtils.removeTab(newTab);
});
});