/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// List of key codes which should exit full-screen mode.
const kKeyList = [
{ key:
"Escape", keyCode:
"VK_ESCAPE", suppressed:
true },
{ key:
"F11", keyCode:
"VK_F11", suppressed:
false },
];
function receiveExpectedKeyEvents(aBrowser, aKeyCode, aTrusted) {
return SpecialPowers.spawn(
aBrowser,
[aKeyCode, aTrusted],
(keyCode, trusted) => {
return
new Promise(resolve => {
let events = trusted
? [
"keydown",
"keyup"]
: [
"keydown",
"keypress",
"keyup"];
if (trusted && keyCode == content.wrappedJSObject.KeyEvent.DOM_VK_F11) {
// trusted `F11` key shouldn't be fired because of reserved when it's
// a shortcut key for exiting from the full screen mode.
events.shift();
}
function listener(event) {
let expected = events.shift();
Assert.equal(
event.type,
expected,
`Should receive a ${expected} event`
);
Assert.equal(
event.keyCode,
keyCode,
`Should receive the event with key code ${keyCode}`
);
if (!events.length) {
content.document.removeEventListener(
"keydown", listener,
true);
content.document.removeEventListener(
"keyup", listener,
true);
content.document.removeEventListener(
"keypress", listener,
true);
resolve();
}
}
content.document.addEventListener(
"keydown", listener,
true);
content.document.addEventListener(
"keyup", listener,
true);
content.document.addEventListener(
"keypress", listener,
true);
});
}
);
}
async
function requestFullscreenAndWait(aBrowser) {
await SimpleTest.promiseFocus(aBrowser);
await SpecialPowers.spawn(aBrowser, [], async () => {
// Wait for the document being activated, so that
// fullscreen request won't be denied.
await ContentTaskUtils.waitForCondition(
() => content.browsingContext.isActive && content.document.hasFocus(),
"document is active"
);
await
new Promise(resolve => {
content.document.addEventListener(
"fullscreenchange", resolve, {
once:
true,
});
content.document.body.requestFullscreen();
});
});
}
const kPage =
"https://example.org/browser/" +
"dom/base/test/fullscreen/file_fullscreen-api-keys.html";
add_setup(async
function init() {
await pushPrefs(
[
"full-screen-api.transition-duration.enter",
"0 0"],
[
"full-screen-api.transition-duration.leave",
"0 0"]
);
});
for (let { key, keyCode, suppressed } of kKeyList) {
/** Test for Bug 545812 */
add_task(async
function testExitFullscreenByKeyboard() {
let keyCodeValue = KeyEvent[
"DOM_" + keyCode];
info(`Test keycode ${key} (${keyCodeValue})`);
let tab = BrowserTestUtils.addTab(gBrowser, kPage);
let browser = tab.linkedBrowser;
gBrowser.selectedTab = tab;
await waitForDocLoadComplete();
// Wait for the document being activated, so that
// fullscreen request won't be denied.
await SimpleTest.promiseFocus(browser);
await SpecialPowers.spawn(browser, [], () => {
return ContentTaskUtils.waitForCondition(
() => content.browsingContext.isActive && content.document.hasFocus(),
"document is active"
);
});
// Register listener to capture unexpected events
let keyEventsCount =
0;
let fullScreenEventsCount =
0;
let removeFullScreenListener = BrowserTestUtils.addContentEventListener(
browser,
"fullscreenchange",
() => fullScreenEventsCount++
);
let removeKeyDownListener = BrowserTestUtils.addContentEventListener(
browser,
"keydown",
() => keyEventsCount++,
{ wantUntrusted:
true }
);
let removeKeyPressListener = BrowserTestUtils.addContentEventListener(
browser,
"keypress",
() => keyEventsCount++,
{ wantUntrusted:
true }
);
let removeKeyUpListener = BrowserTestUtils.addContentEventListener(
browser,
"keyup",
() => keyEventsCount++,
{ wantUntrusted:
true }
);
let expectedFullScreenEventsCount =
0;
let expectedKeyEventsCount =
0;
info(
"Enter fullscreen");
let state =
new Promise(resolve => {
let removeFun = BrowserTestUtils.addContentEventListener(
browser,
"fullscreenchange",
async () => {
removeFun();
resolve(
await SpecialPowers.spawn(browser, [], () => {
return !!content.document.fullscreenElement;
})
);
}
);
});
// request fullscreen
SpecialPowers.spawn(browser, [], () => {
content.document.body.requestFullscreen();
});
ok(await state,
"The content should have entered fullscreen");
ok(document.fullscreenElement,
"The chrome should also be in fullscreen");
is(
fullScreenEventsCount,
++expectedFullScreenEventsCount,
"correct number of fullscreen events occurred"
);
info(
"Dispatch untrusted key events from content");
let promiseExpectedKeyEvents = receiveExpectedKeyEvents(
browser,
keyCodeValue,
false
);
SpecialPowers.spawn(browser, [keyCode], keyCodeChild => {
var evt =
new content.CustomEvent(
"Test:DispatchKeyEvents", {
detail: Cu.cloneInto({ code: keyCodeChild }, content),
});
content.dispatchEvent(evt);
});
await promiseExpectedKeyEvents;
expectedKeyEventsCount +=
3;
is(
keyEventsCount,
expectedKeyEventsCount,
"correct number of key events occurred"
);
info(
"Send trusted key events");
state =
new Promise(resolve => {
let removeFun = BrowserTestUtils.addContentEventListener(
browser,
"fullscreenchange",
async () => {
removeFun();
resolve(
await SpecialPowers.spawn(browser, [], () => {
return !!content.document.fullscreenElement;
})
);
}
);
});
promiseExpectedKeyEvents = suppressed
? Promise.resolve()
: receiveExpectedKeyEvents(browser, keyCodeValue,
true);
await SpecialPowers.spawn(browser, [], () => {});
EventUtils.synthesizeKey(
"KEY_" + key);
await promiseExpectedKeyEvents;
ok(!(await state),
"The content should have exited fullscreen");
ok(
!document.fullscreenElement,
"The chrome should also have exited fullscreen"
);
is(
fullScreenEventsCount,
++expectedFullScreenEventsCount,
"correct number of fullscreen events occurred"
);
if (!suppressed) {
expectedKeyEventsCount += keyCode ==
"VK_F11" ?
1 :
3;
}
is(
keyEventsCount,
expectedKeyEventsCount,
"correct number of key events occurred"
);
info(
"Cleanup");
removeFullScreenListener();
removeKeyDownListener();
removeKeyPressListener();
removeKeyUpListener();
gBrowser.removeTab(tab);
});
/** Test for Bug 1621736 */
// macOS places fullscreen windows in their own virtual desktop, and it is not
// possible to programmatically move focus to another chrome window in a different
// virtual desktop, so this test doesn't work on macOS.
if (AppConstants.platform !=
"macosx") {
add_task(async
function testMultipleFullscreenExitByKeyboard() {
let keyCodeValue = KeyEvent[
"DOM_" + keyCode];
info(`Test keycode ${key} (${keyCodeValue})`);
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: kPage,
},
async
function (browser) {
info(
"Enter fullscreen");
await requestFullscreenAndWait(browser);
info(
"Open new browser window");
const win = await BrowserTestUtils.openNewBrowserWindow();
const tab = await BrowserTestUtils.openNewForegroundTab(
win.gBrowser,
kPage
);
info(
"Enter fullscreen on new browser window");
const newBrowser = tab.linkedBrowser;
await requestFullscreenAndWait(newBrowser);
let removeFullScreenListener;
let promiseFullscreenExit =
new Promise(resolve => {
removeFullScreenListener = BrowserTestUtils.addContentEventListener(
newBrowser,
"fullscreenchange",
resolve,
{},
event => {
return !event.target.fullscreenElement;
}
);
});
info(
"Send key event to new browser window");
EventUtils.synthesizeKey(
"KEY_" + key, {}, win);
await promiseFullscreenExit;
ok(
await SpecialPowers.spawn(browser, [], () => {
return (
content.document.fullscreenElement == content.document.body
);
}),
"First browser window should still in fullscreen mode"
);
info(
"Cleanup");
removeFullScreenListener();
// Close opened tab
let tabClosed = BrowserTestUtils.waitForTabClosing(tab);
await BrowserTestUtils.removeTab(tab);
await tabClosed;
// Close opened window
await BrowserTestUtils.closeWindow(win);
}
);
});
}
}