tor-browser

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

helper_overscroll_in_subscroller.html (4889B)


      1 <!DOCTYPE HTML>
      2 <meta charset="utf-8">
      3 <meta name="viewport" content="width=device-width, minimum-scale=1.0">
      4 <title>
      5  Tests that the overscroll gutter in a sub scroll container is restored if it's
      6  no longer target scroll container
      7 </title>
      8 <script src="apz_test_utils.js"></script>
      9 <script src="apz_test_native_event_utils.js"></script>
     10 <script src="/tests/SimpleTest/paint_listener.js"></script>
     11 <style>
     12  html {
     13    overflow: scroll;
     14  }
     15 
     16  .content {
     17    height: 500px;
     18    width: 300px;
     19    overflow-y: scroll;
     20    background-color: red;
     21  }
     22 </style>
     23 <!-- a sub scroll container -->
     24 <div class="content">
     25  <div style="height:100vh; background-color: white;"></div>
     26 </div>
     27 <div style="height:200vh"></div>
     28 <script>
     29  document.documentElement.addEventListener(
     30    "wheel",
     31    e => {
     32      if (!e.target.closest(`div[class="content"]`)) {
     33        e.preventDefault();
     34      }
     35    },
     36    {
     37      passive: false,
     38    }
     39  );
     40 
     41  const subScroller = document.querySelector(`div[class="content"]`);
     42  // Make the sub scroll container overscrollable at the top edge.
     43  // A `waitUntilApzStable()` call below ensures that this scroll position
     44  // has been informed into APZ before starting this test.
     45  subScroller.scrollTop = 1;
     46 
     47  // A utility function to collect overscrolled scroll container information.
     48  function collectOverscrolledData() {
     49    const apzData = SpecialPowers.DOMWindowUtils.getCompositorAPZTestData().additionalData;
     50    return apzData.filter(data => {
     51      return SpecialPowers.wrap(data).value.split(",").includes("overscrolled");
     52    });
     53  }
     54 
     55  async function test() {
     56    const oneScrollPromise = new Promise(resolve => {
     57      subScroller.addEventListener("scroll", () => {
     58        resolve();
     59      }, { once: true });
     60    });
     61 
     62    // Start a pan upward gesture to try oversrolling on the sub scroll
     63    // container.
     64    await NativePanHandler.promiseNativePanEvent(
     65      subScroller,
     66      100,
     67      100,
     68      0,
     69      -NativePanHandler.delta,
     70      NativePanHandler.beginPhase
     71    );
     72 
     73    const rootScrollId =
     74      SpecialPowers.DOMWindowUtils.getViewId(document.scrollingElement);
     75    const subScrollId =
     76      SpecialPowers.DOMWindowUtils.getViewId(subScroller);
     77 
     78    await promiseApzFlushedRepaints();
     79    await oneScrollPromise;
     80 
     81    let overscrolledData = collectOverscrolledData();
     82    ok(overscrolledData.length >= 1,
     83       "There should be at least one overscrolled scroll container");
     84    ok(overscrolledData.every(data => SpecialPowers.wrap(data).key == subScrollId),
     85       "The overscrolled scroll container should be the sub scroll container");
     86 
     87    let oneScrollEndPromise = new Promise(resolve => {
     88      subScroller.addEventListener("scrollend", () => {
     89        info("Received scrollend event");
     90        resolve();
     91      }, { once: true });
     92    });
     93 
     94    // Finish the pan upward gesture.
     95    await NativePanHandler.promiseNativePanEvent(
     96      subScroller,
     97      100,
     98      100,
     99      0,
    100      0,
    101      NativePanHandler.endPhase
    102    );
    103 
    104    await promiseApzFlushedRepaints();
    105 
    106    // Now do another pan upward gesture again.
    107    await NativePanHandler.promiseNativePanEvent(
    108      subScroller,
    109      100,
    110      100,
    111      0,
    112      -NativePanHandler.delta,
    113      NativePanHandler.beginPhase
    114    );
    115 
    116    // Wait two `apz-repaints-flushed`s to give a chance to overscroll the root
    117    // scroll container.
    118    await promiseApzFlushedRepaints();
    119    await promiseApzFlushedRepaints();
    120 
    121    overscrolledData = collectOverscrolledData();
    122    ok(overscrolledData.length >= 2,
    123       "There should be at least two overscrolled scroll containers");
    124    ok(overscrolledData.some(data => SpecialPowers.wrap(data).key == rootScrollId),
    125       "The root scroll container should be overscrolled");
    126    ok(overscrolledData.some(data => SpecialPowers.wrap(data).key == subScrollId),
    127       "The sub scroll container should also be overscrolled");
    128 
    129    // While the root scroll container is still being overscrolled because the
    130    // new pan gesture is still on-going, the sub scroll container should be
    131    // restored.
    132    // Wait for a scrollend event indicating that the subscroller's overscroll
    133    // animation has completed.
    134    await oneScrollEndPromise;
    135    info("Got a scroll end event on the sub scroll container");
    136 
    137    await promiseApzFlushedRepaints();
    138 
    139    overscrolledData = collectOverscrolledData();
    140    ok(overscrolledData.length >= 1,
    141       "There should be at least one overscrolled scroll container");
    142    ok(overscrolledData.every(data => SpecialPowers.wrap(data).key == rootScrollId),
    143       "The root scroll container should still be overscrolled");
    144 
    145    // Finish the pan upward gesture.
    146    await NativePanHandler.promiseNativePanEvent(
    147      subScroller,
    148      100,
    149      100,
    150      0,
    151      0,
    152      NativePanHandler.endPhase
    153    );
    154  }
    155 
    156  waitUntilApzStable()
    157  .then(test)
    158  .then(subtestDone, subtestFailed);
    159 </script>