tor-browser

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

new-scroll-event-dispatched-at-next-updating-rendering-time.html (4080B)


      1 <!doctype html>
      2 <meta charset="utf-8">
      3 <link rel="help" href="https://html.spec.whatwg.org/#event-loop-processing-model">
      4 <link rel="help" href="https://issues.chromium.org/issues/397737222">
      5 <meta name="viewport" content="width=device-width,initial-scale=1">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <style>
      9 </style>
     10 <iframe width="300" height="300" srcdoc="
     11  <style>
     12    html {
     13      transition: color 1s step-start;
     14    }
     15    .scroller {
     16      overflow: auto;
     17      width: 100%;
     18      height: 100px;
     19    }
     20    .spacer {
     21      height: 500px;
     22    }
     23  </style>
     24  <div class='scroller'>
     25    <div class='spacer'></div>
     26  </div>
     27  <div class='scroller'>
     28    <div class='spacer'></div>
     29  </div>
     30  "></iframe>
     31 <script>
     32 promise_test(async function() {
     33  await new Promise(resolve => window.addEventListener("load", resolve, { once: true }));
     34 
     35  const iframe = document.querySelector("iframe");
     36  const mql = iframe.contentWindow.matchMedia("(max-width: 300px)");
     37  assert_true(mql.matches, "");
     38 
     39  // Set up a MQL change event listener to receive the event in between
     40  // scroll and transitionrun events.
     41  let timeOnMQLChange = null;
     42  iframe.width = "400";
     43  const mqlChangeEvent = new Promise(resolve => {
     44    mql.addEventListener("change", () => {
     45      timeOnMQLChange = performance.now();
     46      resolve();
     47    }, { once: true });
     48  });
     49 
     50  // There are two scroll containers, setup a scroll event listener for one
     51  // of them.
     52  const scrollers = iframe.contentDocument.querySelectorAll(".scroller");
     53  let timeOnScrollEventOnAnotherScroller = null;
     54  scrollers[1].addEventListener("scroll", () => {
     55    timeOnScrollEventOnAnotherScroller = performance.now();
     56  }, { once: true });
     57 
     58  // Setup another scroll event listener for the other scroll container.
     59  const scrollEventPromise = new Promise(resolve => {
     60    scrollers[0].addEventListener("scroll", resolve, { once: true });
     61  });
     62  // And scroll the scroller.
     63  scrollers[0].scrollTop = 10;
     64 
     65  // Await the scroll event.
     66  await scrollEventPromise;
     67 
     68  const timeOnScrollEvent = performance.now();
     69 
     70  // Scroll the other scroller.
     71  scrollers[1].scrollTop = 10;
     72 
     73  assert_equals(timeOnScrollEventOnAnotherScroller, null,
     74    "The new scroll event should not yet have been dispatched");
     75 
     76  // Trigger a CSS transition.
     77  let timeOnTransitionRun = null;
     78  const transitionrunEventPromise = new Promise(resolve => {
     79    iframe.contentDocument.documentElement.addEventListener("transitionrun", () => {
     80      timeOnTransitionRun = performance.now();
     81      resolve();
     82    }, { once: true });
     83  });
     84  iframe.contentDocument.documentElement.style.color = "blue";
     85  getComputedStyle(iframe.contentDocument.documentElement).color;
     86 
     87  // Now it's time to receive the MQL change event.
     88  await mqlChangeEvent;
     89  assert_less_than(timeOnScrollEvent, timeOnMQLChange,
     90    "The MQL change event should have been dispatched after the first scroll event");
     91  assert_equals(timeOnScrollEventOnAnotherScroller, null,
     92    "The new scroll event should not yet have been dispatched");
     93 
     94  // Await the transitionrun event.
     95  await transitionrunEventPromise;
     96 
     97  assert_less_than(timeOnScrollEvent, timeOnTransitionRun,
     98    "The transitionrun event should have been dispatched after the first scroll event");
     99  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    100    "The new scroll event should not yet have been dispatched");
    101 
    102  // Await a requestAnimationFrame callback.
    103  await new Promise(resolve => requestAnimationFrame(resolve));
    104 
    105  assert_equals(timeOnScrollEventOnAnotherScroller, null,
    106    "The new scroll event should not yet have been dispatched");
    107 
    108  // Await one more requestAnimationFrame callback.
    109  await new Promise(resolve => requestAnimationFrame(resolve));
    110 
    111  assert_not_equals(timeOnScrollEventOnAnotherScroller, null,
    112    "The new scroll event should now have been dispatched");
    113  assert_less_than(timeOnTransitionRun, timeOnScrollEventOnAnotherScroller,
    114    "The new scroll event should have been dispatched after the transitionrun event");
    115 });
    116 </script>