tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>