media-query-matches-in-iframe.html (4628B)
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>