Skip to content

Commit 3f8841c

Browse files
theIDinsidemoz-wptsync-bot
authored andcommitted
Update keyboard lock appropriately
Update keyboard lock state only when chrome document enters fullscreen, and in the case where an optimization is performed when a content process already sees itself to be in DOM fullscreen, then it should update kblock state of the chrome document as well, so that the correct warning is displayed. Added web platform tests that test for this specific scenario. Differential Revision: https://phabricator.services.mozilla.com/D295315 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=2033397 gecko-commit: fb53180f47a19543ded530b29bf0ef11d6f4b3e2 gecko-commit-git: c42d01ef9b2d0a5d86989d772f81ef6ee4da30bd gecko-reviewers: edgar, avandolder
1 parent 27267cd commit 3f8841c

2 files changed

Lines changed: 191 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="timeout" content="long">
6+
<title>Fullscreen keyboardLock option with cross-origin iframe</title>
7+
<script src="/resources/testharness.js"></script>
8+
<script src="/resources/testharnessreport.js"></script>
9+
<script src="/resources/testdriver.js"></script>
10+
<script src="/resources/testdriver-actions.js"></script>
11+
<script src="/resources/testdriver-vendor.js"></script>
12+
<style>
13+
#outer {
14+
background-color: green;
15+
width: 300px;
16+
height: 300px;
17+
display: flex;
18+
flex-direction: column;
19+
align-items: center;
20+
justify-content: center;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<div id="outer">
26+
<iframe
27+
id="cross-origin-iframe"
28+
src="http://{{hosts[alt][]}}:{{ports[http][0]}}/fullscreen/api/resources/keyboard-lock-inner.sub.html"
29+
allowfullscreen
30+
></iframe>
31+
</div>
32+
<button id="fullscreen-btn">Enter fullscreen (keyboardLock: none)</button>
33+
<div id="log"></div>
34+
<script>
35+
function waitForFullscreenChange() {
36+
let { promise, resolve } = Promise.withResolvers();
37+
document.addEventListener("fullscreenchange", resolve, { once: true });
38+
return promise;
39+
}
40+
41+
async function request(type) {
42+
const iframe = document.getElementById("cross-origin-iframe");
43+
let { promise, resolve, reject } = Promise.withResolvers();
44+
switch(type) {
45+
case "requestFullscreen": {
46+
function onMessage(e) {
47+
if (e.data.action !== "fullscreenResult") {
48+
return;
49+
}
50+
window.removeEventListener("message", onMessage);
51+
e.data.error ? reject(new Error(e.data.error)) : resolve();
52+
}
53+
window.addEventListener("message", onMessage);
54+
break;
55+
}
56+
case "singlePressEsc":
57+
case "holdPressEsc": {
58+
function onMessage(e) {
59+
if (e.data.action !== "keyDownResult") {
60+
return;
61+
}
62+
window.removeEventListener("message", onMessage);
63+
e.data.error ? reject(new Error(e.data.error)) : resolve();
64+
}
65+
window.addEventListener("message", onMessage);
66+
break;
67+
}
68+
}
69+
iframe.contentWindow.postMessage({ action: type }, "*");
70+
await promise;
71+
}
72+
73+
promise_test(async t => {
74+
t.add_cleanup(() => document.exitFullscreen().catch(() => {}));
75+
76+
const iframe = document.getElementById("cross-origin-iframe");
77+
78+
let enterPromise = waitForFullscreenChange();
79+
await new Promise(r => t.step_timeout(r, 500));
80+
await request("requestFullscreen");
81+
await enterPromise;
82+
assert_equals(document.fullscreenElement, iframe,
83+
"iframe should be the fullscreen element");
84+
85+
await request("singlePressEsc");
86+
assert_equals(document.fullscreenElement, iframe,
87+
"single Escape should not exit fullscreen when keyboardLock is browser");
88+
89+
await Promise.all([waitForFullscreenChange(), request("holdPressEsc")])
90+
assert_equals(document.fullscreenElement, null,
91+
"holding Escape should exit fullscreen when keyboardLock is browser");
92+
}, "Cross-origin iframe fullscreen with keyboardLock:browser — hold Escape exits");
93+
94+
promise_test(async t => {
95+
t.add_cleanup(() => document.exitFullscreen().catch(() => {}));
96+
97+
const iframe = document.getElementById("cross-origin-iframe");
98+
99+
let enterTopPromise = waitForFullscreenChange();
100+
await test_driver.bless("requestFullscreen with keyboardLock:none", () =>
101+
document.getElementById("outer").requestFullscreen({ keyboardLock: "none" })
102+
);
103+
await enterTopPromise;
104+
assert_equals(document.fullscreenElement, document.getElementById("outer"),
105+
"outer should be the fullscreen element");
106+
107+
await Promise.all([waitForFullscreenChange(), request("requestFullscreen")]);
108+
109+
assert_equals(document.fullscreenElement, iframe,
110+
"iframe should be the fullscreen element after nested fullscreen request");
111+
112+
await request("singlePressEsc");
113+
114+
assert_equals(document.fullscreenElement, iframe,
115+
"single Escape should not exit nested keyboardLock:browser fullscreen");
116+
117+
await Promise.all([waitForFullscreenChange(), request("holdPressEsc")]);
118+
assert_not_equals(document.fullscreenElement, iframe,
119+
"iframe should no longer be the fullscreen element after holding Escape");
120+
}, "Nested fullscreen: top-level keyboardLock:none then cross-origin iframe keyboardLock:browser — hold Escape exits iframe fullscreen");
121+
</script>
122+
</body>
123+
</html>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<script src="/resources/testdriver.js"></script>
6+
<script src="/resources/testdriver-actions.js"></script>
7+
<script src="/resources/testdriver-vendor.js"></script>
8+
<script src="../../trusted-click.js"></script>
9+
<style>
10+
#inner {
11+
background-color: red;
12+
width: 200px;
13+
height: 200px;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<div id="inner"></div>
19+
<button id="fullscreen-btn">Enter fullscreen (keyboardLock: browser)</button>
20+
<script>
21+
// Keyboard lock + preventDefault() to prevent keys from UA specific behavior.
22+
addEventListener("keydown", ev => ev.preventDefault());
23+
24+
async function respondWith(action, cb) {
25+
let error = null;
26+
try {
27+
await cb();
28+
} catch(err) {
29+
error = err.message;
30+
} finally {
31+
window.top.postMessage({ action, error }, "*");
32+
}
33+
}
34+
35+
window.addEventListener("message", async e => {
36+
if (e.data.action === "requestFullscreen") {
37+
await respondWith("fullscreenResult", async () => {
38+
await trusted_click();
39+
await document.getElementById("inner").requestFullscreen({ keyboardLock: "browser" });
40+
})
41+
} else if (e.data.action === "singlePressEsc") {
42+
await respondWith("keyDownResult", async () => {
43+
await new test_driver.Actions()
44+
.keyDown("\uE00C")
45+
.addTick(1)
46+
.keyUp("\uE00C").send();
47+
// Wait a little before responding.
48+
await new test_driver.Actions().addTick(250).send();
49+
})
50+
} else if(e.data.action === "holdPressEsc") {
51+
await respondWith("keyDownResult", async () => {
52+
await new test_driver.Actions()
53+
.keyDown("\uE00C")
54+
.addTick(1000)
55+
.keyDown("\uE00C")
56+
.addTick(1000)
57+
.keyDown("\uE00C")
58+
.addTick(1000)
59+
.keyDown("\uE00C")
60+
.addTick(1000)
61+
.keyDown("\uE00C")
62+
.keyUp("\uE00C").send();
63+
});
64+
}
65+
});
66+
</script>
67+
</body>
68+
</html>

0 commit comments

Comments
 (0)