Files
ladybird/Tests/LibWeb/Text/input/wpt-import/fullscreen/api/element-request-fullscreen-timing.html
Zaggy1024 2e54c18fb3 LibWeb: Use a queue to process fullscreen request completions
Instead of immediately firing fullscreenchange, defer that until
WebContent's client has confirmed that it is in fullscreen for the
content. The fullscreenchange is fired by the viewport change, so in
cases where the fullscreen transition is instantaneous (i.e. the
fullscreen state is entered at the exact moment the viewport expands),
the resize event should precede the fullscreenchange event, as the spec
requires.

This fixes the WPT element-request-fullscreen-timing.html test, which
was previously succeeding by accident because we were immediately
fullscreenchange upon requestFullscreen() being called, instead of
following spec and doing the viewport (window) resize in parallel. The
WPT test was actually initially intended to assert that the
fullscreenchange event follows the resize event, but the WPT runner
didn't actually have a different resolution for normal vs fullscreen
viewports, so the resize event doesn't actually fire in their setup. In
our headless mode, the default viewport is 800x600, and the fullscreen
viewport is 1920x1080, so we do fire a resize event when entering
fullscreen. Therefore, that imported test is reverted to assert that
the resize precedes the fullscreenchange.
2026-03-17 18:58:37 -05:00

55 lines
2.2 KiB
HTML

<!DOCTYPE html>
<title>Element#requestFullscreen() timing</title>
<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>
<script src="../trusted-click.js"></script>
<div id="log"></div>
<script>
promise_test(async t => {
const div = document.querySelector('div');
// If fullscreenchange is an animation frame event, then animation frame
// callbacks should be run after it is fired, before the timer callback.
// The resize event should fire before the fullscreenchange event.
const events = [];
const p = new Promise(resolve => {
const callback = t.step_func(event => {
// fullscreenElement should have changed before either event is fired.
assert_equals(document.fullscreenElement, div, `fullscreenElement in {event.type} event`);
events.push(event.type);
if (event.type == 'fullscreenchange') {
step_timeout(t.unreached_func('timer callback'));
requestAnimationFrame(t.step_func_done(() => {
assert_array_equals(events, ['resize', 'fullscreenchange'], 'event order');
resolve();
}));
}
});
document.onfullscreenchange = window.onresize = callback;
});
await trusted_request(div);
await p;
// so the user doesn't have to exit for themselves
document.exitFullscreen();
}, 'Timing of fullscreenchange and resize events');
async_test(t => {
// Gecko throttles requestAnimationFrame before the first paint, so
// wrap the test to work around that.
requestAnimationFrame(t.step_func(() => {
var promise = document.createElement('a').requestFullscreen();
var promise_executed = false;
promise.catch(()=>{promise_executed = true; });
// If fullscreenerror is an animation frame event, then animation frame
// callbacks should be run after it is fired, before the timer callback.
document.onfullscreenerror = t.step_func(() => {
assert_true(promise_executed, "promise executed");
step_timeout(t.unreached_func('timer callback'));
requestAnimationFrame(t.step_func_done());
});
}));
}, 'Timing of fullscreenerror event');
</script>