tor-browser

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

mismatched-snapshot-containing-block-size-skips.html (4586B)


      1 <!DOCTYPE html>
      2 <title>
      3 View transitions: mismatched snapshot containing block size skips transition.
      4 </title>
      5 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
      6 <link rel="author" href="mailto:bokan@chromium.org">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script src="/resources/testdriver.js"></script>
     10 <script src="/resources/testdriver-vendor.js"></script>
     11 <script src="/common/utils.js"></script>
     12 <script src="resources/common.js"></script>
     13 <style>
     14 @view-transition {
     15  navigation: auto;
     16 }
     17 ::view-transition-group(root) {
     18  animation-duration: 3s;
     19 }
     20 </style>
     21 <script>
     22 const params = new URLSearchParams(location.search);
     23 const is_harness_page = !params.has('popup');
     24 const is_old_page = params.has('popup') && params.get('popup') == 'old';
     25 const is_new_page = params.has('popup') && params.get('popup') == 'new';
     26 
     27 const uuid = token();
     28 
     29 const popup_old_size = 300;
     30 const popup_new_size = 200;
     31 
     32 // This test opens a popup to its own URL but using a param to execute different
     33 // script between the initial "harness" and popup. It then navigates the popup
     34 // to a new page to start a view transition. Popup script is below.
     35 
     36 if (is_harness_page) {
     37  // ========= Test Harness Script =============
     38 
     39  const popup_old_url = `${location.href.split('?')[0]}?popup=old`;
     40  const popup_new_url = `${location.href.split('?')[0]}?popup=new`;
     41 
     42  async function popupEventPromise(event_name) {
     43    return new Promise(resolve => {
     44      addEventListener('message', e => {
     45        if (e.data === event_name)
     46          resolve();
     47      }, {once: true});
     48    });
     49  }
     50 
     51  promise_test(async t => {
     52    assertViewTransitionOnNavigationImplemented();
     53 
     54    addEventListener('message', e => {
     55        if (e.data.startsWith('FAIL:')) {
     56          const message = e.data.substring(5);
     57          t.step(() => assert_unreached(`Failure in test code: ${message}`));
     58        }
     59    });
     60 
     61    let popup = null;
     62 
     63    const load_event_in_popup = popupEventPromise('load');
     64    await test_driver.bless('Open a popup in a new window', () => {
     65        const features = `width=${popup_old_size},height=${popup_old_size}`;
     66        popup = window.open(popup_old_url, 'popup', features);
     67    });
     68    await load_event_in_popup;
     69 
     70    t.add_cleanup(() => popup.close());
     71 
     72    // Pagehide is fired after capturing the outgoing state.
     73    popup.onpagehide = () => popup.resizeTo(popup_new_size, popup_new_size);
     74 
     75    // Navigate the popup to the new page and wait for pagereveal.
     76    const pagereveal_in_popup = popupEventPromise('pagereveal');
     77    popup.location = popup_new_url;
     78    await pagereveal_in_popup;
     79 
     80    // Ensure the transition is skipped and `ready` rejected.
     81    let did_finish = false;
     82    popup.viewTransition.finished.then(() => { did_finish = true; });
     83 
     84    await promise_rejects_dom(t, "InvalidStateError", popup.DOMException,
     85        popup.viewTransition.ready, 'Resize must reject `ready`.');
     86    assert_true(did_finish, "Transition must be skipped by window resize.");
     87  });
     88 
     89 } else {
     90 
     91  // ========= Popup Script =============
     92 
     93  if (is_old_page) {
     94    addEventListener('load', () => window.opener.postMessage('load'));
     95  } else  if (is_new_page) {
     96    function errorHandler(e) {
     97      window.opener.postMessage(`FAIL: ${e}`);
     98    }
     99    // Hold rendering until the asynchronous resize from `resizeTo` above has
    100    // been received.
    101    const rendering_blocked_promise = blockRendering();
    102    rendering_blocked_promise.catch(errorHandler);
    103 
    104    let rendering_unblocked_promise = null;
    105 
    106    const interval_id = setInterval(() => {
    107      // Since rendering is blocked - the resize event isn't fired. The
    108      // innerWidth is also not updated (at least in Chrome) so use the
    109      // outerWidth to wait on the size change. allow a bit of slop in case of
    110      // window decorations.
    111      if (window.outerWidth < popup_new_size + 15) {
    112        rendering_unblocked_promise = unblockRendering();
    113        rendering_unblocked_promise.catch(errorHandler);
    114        clearInterval(interval_id);
    115      }
    116    }, 100);
    117 
    118    addEventListener('pagereveal', e => {
    119      // This simply ensures the test only runs if render blocking was
    120      // successful since a fetch failure looks the same as never blocking
    121      // rendering.
    122      Promise.all([rendering_blocked_promise, rendering_unblocked_promise]).then(async () => {
    123        window.viewTransition = e.viewTransition;
    124        window.opener.postMessage('pagereveal');
    125        await Promise.allSettled([e.viewTransition.ready]);
    126      }, () => {});
    127    });
    128  }
    129 }
    130 </script>