tor-browser

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

helper_visual_scrollbars_pagescroll.html (5183B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <meta name="viewport" content="width=device-width">
      6  <title>Clicking on the scrollbar track in quick succession should scroll the right amount</title>
      7  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
      8  <script type="application/javascript" src="apz_test_utils.js"></script>
      9  <script src="/tests/SimpleTest/paint_listener.js"></script>
     10  <script src="/tests/SimpleTest/EventUtils.js"></script>
     11 
     12  <script type="application/javascript">
     13 
     14 // A helper to synthesize a native mouse click on a scrollbar track,
     15 // and wait long enough such that subsequent ticking of the refresh
     16 // driver will progress any resulting scroll animation.
     17 // In particular, just `await promiseNativeMouseEventWithApz(...)`
     18 // is not enough, it waits for the synthesization messages to arrive
     19 // in the parent process, but the native events may still be in the
     20 // OS event queue. Instead, we need to wait for a synthesized event
     21 // to arrive at content. While we're synthesizing a "click", if the
     22 // target is a scrollbar the window only gets the "mousedown" and
     23 // "mouseup", not a "click". Waiting for the "mousedown" is not enough
     24 // (the "mouseup" can still be stuck in the event queue), so we wait
     25 // for "mouseup".
     26 async function promiseNativeMouseClickOnScrollbarTrack(anchor, xOffset, yOffset) {
     27  await promiseNativeMouseEventWithAPZAndWaitForEvent({
     28    type: "click",
     29    target: anchor,
     30    offsetX: xOffset,
     31    offsetY: yOffset,
     32    eventTypeToWait: "mouseup"
     33  });
     34 }
     35 
     36 async function test() {
     37  var scroller = document.documentElement;
     38  var verticalScrollbarWidth = window.innerWidth - scroller.clientWidth;
     39 
     40  if (verticalScrollbarWidth == 0) {
     41    ok(true, "Scrollbar width is zero on this platform, test is useless here");
     42    return;
     43  }
     44 
     45  // The anchor is the fixed-pos div that we use to calculate coordinates to
     46  // click on the scrollbar. That way we don't have to recompute coordinates
     47  // as the page scrolls. The anchor is at the bottom-right corner of the
     48  // content area.
     49  var anchor = document.getElementById('anchor');
     50 
     51  var xoffset = (verticalScrollbarWidth / 2);
     52  // Get a y-coord near the bottom of the vertical scrollbar track. Assume the
     53  // vertical thumb is near the top of the scrollback track (since scroll
     54  // position starts off at zero) and won't get in the way. Also assume the
     55  // down arrow button, if there is one, is square.
     56  var yoffset = 0 - verticalScrollbarWidth - 5;
     57 
     58  // Take control of the refresh driver
     59  let utils = SpecialPowers.getDOMWindowUtils(window);
     60  utils.advanceTimeAndRefresh(0);
     61 
     62  // Click at the bottom of the scrollbar track to trigger a page-down kind of
     63  // scroll. This should use "desktop zooming" scrollbar code which should
     64  // trigger an APZ scroll animation.
     65  await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset);
     66 
     67  // Run 1000 frames, that should be enough to let the scroll animation start
     68  // and run to completion. We check that it scrolled at least half the visible
     69  // height, since we expect about a full screen height minus a few lines.
     70  for (let i = 0; i < 1000; i++) {
     71    utils.advanceTimeAndRefresh(16);
     72  }
     73  await promiseOnlyApzControllerFlushed();
     74 
     75  let pageScrollAmount = scroller.scrollTop;
     76  ok(pageScrollAmount > scroller.clientHeight / 2,
     77     `Scroll offset is ${pageScrollAmount}, should be near clientHeight ${scroller.clientHeight}`);
     78 
     79  // Now we do two clicks in quick succession, but with a few frames in between
     80  // to verify the scroll animation from the first click is active before the
     81  // second click happens.
     82  await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset);
     83  for (let i = 0; i < 5; i++) {
     84    utils.advanceTimeAndRefresh(16);
     85  }
     86  await promiseOnlyApzControllerFlushed();
     87  let curPos = scroller.scrollTop;
     88  ok(curPos > pageScrollAmount, `Scroll offset has increased to ${curPos}`);
     89  ok(curPos < pageScrollAmount * 2, "Second page-scroll is not yet complete");
     90  await promiseNativeMouseClickOnScrollbarTrack(anchor, xoffset, yoffset);
     91 
     92  // Run to completion and check that we are around 3x pageScrollAmount, with
     93  // some allowance for fractional rounding.
     94  for (let i = 0; i < 1000; i++) {
     95    utils.advanceTimeAndRefresh(16);
     96  }
     97  await promiseOnlyApzControllerFlushed();
     98  curPos = scroller.scrollTop;
     99  ok(Math.abs(curPos - (pageScrollAmount * 3)) < 3,
    100     `Final scroll offset ${curPos} is close to 3x${pageScrollAmount}`);
    101 
    102  utils.restoreNormalRefresh();
    103 }
    104 
    105 waitUntilApzStable()
    106 .then(test)
    107 .then(subtestDone, subtestFailed);
    108 
    109  </script>
    110 </head>
    111 <body>
    112 <div style="position:fixed; bottom: 0; right: 0; width: 1px; height: 1px" id="anchor"></div>
    113 <div style="height: 300vh; margin-bottom: 10000px; background-image: linear-gradient(red,blue)"></div>
    114  The above div is sized to 3x screen height so the linear gradient is more steep in terms of
    115  color/pixel. We only scroll a few pages worth so we don't need the gradient all the way down.
    116  And then we use a bottom-margin to make the page really big so the scrollthumb is
    117  relatively small, giving us lots of space to click on the scrolltrack.
    118 </body>
    119 </html>