Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 53126bb

Browse files
authoredAug 5, 2022
Add tests for viewport dependent media queries inside iframe (#35349)
This was written for WebKit: https://commits.webkit.org/253123@main
1 parent f734196 commit 53126bb

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<link rel="help" href="https://drafts.csswg.org/mediaqueries-4/#mf-dimensions">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
<script>
8+
9+
async function createFrameAndUpdateLayout(test) {
10+
const iframe = await new Promise((resolve) => {
11+
const iframe = document.createElement('iframe');
12+
iframe.style.width = '100px';
13+
iframe.style.height = '100px';
14+
iframe.onload = () => resolve(iframe);
15+
document.body.appendChild(iframe);
16+
test.add_cleanup(() => iframe.remove());
17+
});
18+
iframe.contentDocument.body.innerHTML = '<span>some content</span>';
19+
window.preventOptimization1 = iframe.getBoundingClientRect();
20+
window.preventOptimization2 = iframe.contentDocument.querySelector('span').getBoundingClientRect();
21+
return iframe;
22+
}
23+
24+
for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
25+
promise_test(async function () {
26+
const iframe = await createFrameAndUpdateLayout(this);
27+
const mediaQuery = iframe.contentWindow.matchMedia(query);
28+
assert_true(mediaQuery.matches);
29+
iframe.style.width = '200px';
30+
assert_false(mediaQuery.matches);
31+
}, `matchMedia('${query}').matches should update immediately`);
32+
}
33+
34+
for (const query of ['(height: 100px)', '(max-height: 150px)', '(min-aspect-ratio: 3/4)']) {
35+
promise_test(async function () {
36+
const iframe = await createFrameAndUpdateLayout(this);
37+
const mediaQuery = iframe.contentWindow.matchMedia(query);
38+
assert_true(mediaQuery.matches);
39+
iframe.style.height = '200px';
40+
assert_false(mediaQuery.matches);
41+
}, `matchMedia('${query}').matches should update immediately`);
42+
}
43+
44+
for (const query of ['(min-height: 150px)', '(aspect-ratio: 1/2)']) {
45+
promise_test(async function () {
46+
const iframe = await createFrameAndUpdateLayout(this);
47+
const mediaQuery = iframe.contentWindow.matchMedia(query);
48+
assert_false(mediaQuery.matches);
49+
iframe.style.height = '200px';
50+
assert_true(mediaQuery.matches);
51+
}, `matchMedia('${query}').matches should update immediately`);
52+
}
53+
54+
for (const query of ['(min-width: 150px)', '(min-aspect-ratio: 4/3)']) {
55+
promise_test(async function () {
56+
const iframe = await createFrameAndUpdateLayout(this);
57+
const mediaQuery = iframe.contentWindow.matchMedia(query);
58+
assert_false(mediaQuery.matches);
59+
iframe.style.width = '200px';
60+
assert_true(mediaQuery.matches);
61+
}, `matchMedia('${query}').matches should update immediately`);
62+
}
63+
64+
for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
65+
promise_test(async function () {
66+
const iframe = await createFrameAndUpdateLayout(this);
67+
const mediaQuery = iframe.contentWindow.matchMedia(query);
68+
let changes = 0;
69+
mediaQuery.addEventListener('change', () => ++changes);
70+
assert_true(mediaQuery.matches);
71+
assert_equals(changes, 0);
72+
iframe.style.width = '200px';
73+
assert_false(mediaQuery.matches);
74+
assert_equals(changes, 0);
75+
await new Promise(requestAnimationFrame);
76+
assert_false(mediaQuery.matches);
77+
assert_equals(changes, 1);
78+
}, `matchMedia('${query}') should not receive a change event until update the rendering step of HTML5 event loop`);
79+
}
80+
81+
for (const query of ['(max-width: 150px)', '(width: 100px)', '(orientation: portrait)', '(aspect-ratio: 1/1)', '(max-aspect-ratio: 4/3)']) {
82+
promise_test(async function () {
83+
const iframe = await createFrameAndUpdateLayout(this);
84+
const mediaQuery = iframe.contentWindow.matchMedia(query);
85+
const events = [];
86+
iframe.contentWindow.addEventListener('resize', () => {
87+
assert_array_equals(events, []);
88+
events.push('resize');
89+
});
90+
mediaQuery.addEventListener('change', () => events.push('change'));
91+
assert_true(mediaQuery.matches);
92+
assert_array_equals(events, []);
93+
iframe.style.width = '200px';
94+
assert_false(mediaQuery.matches);
95+
assert_array_equals(events, []);
96+
await new Promise(requestAnimationFrame);
97+
assert_false(mediaQuery.matches);
98+
assert_array_equals(events, ['resize', 'change']);
99+
}, `matchMedia('${query}') should receive a change event after resize event on the window but before a requestAnimationFrame callback is called`);
100+
}
101+
102+
</script>
103+
</body>
104+
</html>

0 commit comments

Comments
 (0)