Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions screen-orientation/fullscreen-exit-unlocks-orientation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Screen Orientation: exiting fullscreen unlocks the orientation and aborts a pending lock</title>
<link rel="help" href="https://w3c.github.io/screen-orientation/#fullscreen-interaction" />
<link rel="help" href="https://fullscreen.spec.whatwg.org/#fully-exit-fullscreen" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<body>
<script type="module">
import {
getOppositeOrientation,
attachIframe,
} from "./resources/orientation-utils.js";

// A throwing cleanup becomes a harness error, so guard each step.
function cleanup(t, iframe) {
t.add_cleanup(async () => {
if (iframe) iframe.remove();
try { screen.orientation.unlock(); } catch (e) {}
try {
if (document.fullscreenElement) await document.exitFullscreen();
} catch (e) {}
});
}

async function lockToOpposite() {
// false when locking is unsupported (e.g. desktop: lock() rejects NotSupportedError).
try {
await screen.orientation.lock(getOppositeOrientation());
return true;
} catch (e) {
if (e.name === "NotSupportedError") return false;
throw e;
}
}

promise_test(async (t) => {
cleanup(t);
await test_driver.bless("enter fullscreen");
await document.documentElement.requestFullscreen();
// Do not await the lock: it must still be pending when fullscreen exits.
const lockPromise = screen.orientation.lock(getOppositeOrientation());
await document.exitFullscreen();
let outcome;
try {
await lockPromise;
outcome = "resolved";
} catch (e) {
outcome = e.name;
}
assert_implements_optional(
outcome !== "NotSupportedError",
"screen.orientation.lock() is supported on this device"
);
assert_equals(
outcome,
"AbortError",
"a pending lock() is rejected with AbortError when the document exits fullscreen"
);
}, "Exiting fullscreen aborts a pending screen.orientation.lock() with AbortError");

promise_test(async (t) => {
cleanup(t);
const initial = {
type: screen.orientation.type,
angle: screen.orientation.angle,
};
await test_driver.bless("enter fullscreen");
await document.documentElement.requestFullscreen();
assert_implements_optional(
await lockToOpposite(),
"screen.orientation.lock() is supported on this device"
);
assert_not_equals(
screen.orientation.type,
initial.type,
"precondition: the lock changed the orientation"
);
const reverted = new Promise((resolve) =>
screen.orientation.addEventListener("change", resolve, { once: true })
);
await document.exitFullscreen();
await reverted;
assert_equals(screen.orientation.type, initial.type,
"orientation type reverts after exiting fullscreen");
assert_equals(screen.orientation.angle, initial.angle,
"orientation angle reverts after exiting fullscreen");
}, "Exiting fullscreen releases the screen orientation lock");

// The lock applies to the top-level document, so a subframe that locks and then
// exits fullscreen must release the top document's lock.
promise_test(async (t) => {
const iframe = await attachIframe();
cleanup(t, iframe);
const initial = {
type: screen.orientation.type,
angle: screen.orientation.angle,
};
await test_driver.bless("enter fullscreen", null, iframe.contentWindow);
await iframe.contentDocument.documentElement.requestFullscreen();
let supported = true;
try {
await iframe.contentWindow.screen.orientation.lock(getOppositeOrientation());
} catch (e) {
if (e.name === "NotSupportedError") supported = false;
else throw e;
}
assert_implements_optional(
supported,
"screen.orientation.lock() is supported on this device"
);
assert_not_equals(
screen.orientation.type,
initial.type,
"precondition: the subframe's lock changed the top orientation"
);
const reverted = new Promise((resolve) =>
screen.orientation.addEventListener("change", resolve, { once: true })
);
await iframe.contentDocument.exitFullscreen();
await reverted;
assert_equals(screen.orientation.type, initial.type,
"top orientation type reverts after the subframe exits fullscreen");
assert_equals(screen.orientation.angle, initial.angle,
"top orientation angle reverts after the subframe exits fullscreen");
}, "Exiting fullscreen in a subframe releases the top document's orientation lock");
</script>
</body>
Loading