tor-browser

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

helper_zoom_out_with_mainthread_clamping.html (4428B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <meta name="viewport" content="width=device-width, minimum-scale=1.0">
      6  <title>Tests that zooming out in a way that triggers main-thread scroll re-clamping works properly</title>
      7  <script src="/tests/SimpleTest/EventUtils.js"></script>
      8  <script type="application/javascript" src="apz_test_utils.js"></script>
      9  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
     10  <script src="/tests/SimpleTest/paint_listener.js"></script>
     11 </head>
     12 <body>
     13  <div style="width: 200vw; height: 2000px; background-color: linear-gradient(green,blue)"></div>
     14  <script type="application/javascript">
     15    const utils = SpecialPowers.getDOMWindowUtils(window);
     16 
     17    async function test() {
     18      // Initial state
     19      is(await getResolution(), 1.0, "should not be zoomed");
     20 
     21      // Zoom in and go to the bottom-right corner. This ensures the layout
     22      // and visual scroll offsets are nonzero, which increases the chances
     23      // that the scroll position layer alignment code will mutate the scroll
     24      // position (see comment below).
     25      utils.setResolutionAndScaleTo(5.0);
     26      await promiseApzFlushedRepaints();
     27      utils.scrollToVisual(document.scrollingElement.clientWidth * 5,
     28                           document.scrollingElement.clientHeight * 5,
     29                           utils.UPDATE_TYPE_MAIN_THREAD,
     30                           utils.SCROLL_MODE_INSTANT);
     31      await promiseApzFlushedRepaints();
     32 
     33      // Check that we're at the right place
     34      is(await getResolution(), 5.0, "should be zoomed to 5.0");
     35      is(window.scrollX, window.scrollMaxX, "layout x-coord should be maxed");
     36      is(window.scrollY, window.scrollMaxY, "layout y-coord should be maxed");
     37      ok(visualViewport.offsetLeft > 0, "visual x-coord should be even further");
     38      ok(visualViewport.offsetTop > 0, "visual y-coord should be even further");
     39 
     40      // Zoom out. This will trigger repaint requests to the main thread,
     41      // at various intermediate resolutions. The repaint requests will
     42      // trigger reflows, which will trigger the root scrollframe to re-clamp
     43      // and layer-align the scroll position as part of the post-reflow action.
     44      // The test is checking that these mutations don't end up sending a scroll
     45      // position update to APZ that interrupts the zoom action (see bug 1671284
     46      // comment 9 for the exact mechanism). In order to maximize the chances of
     47      // catching the bug, we wait for the main thread repaint after each of the
     48      // pinch inputs.
     49 
     50      let zoom_out = pinchZoomOutTouchSequenceAtCenter();
     51      // Do coordinate conversion up-front using the current resolution and
     52      // visual viewport.
     53      for (let entry of zoom_out) {
     54        for (let i = 0; i < entry.length; i++) {
     55          entry[i] = await coordinatesRelativeToScreen({
     56            offsetX: entry[i].x,
     57            offsetY: entry[i].y,
     58            target: document.body,
     59          });
     60        }
     61      }
     62      // Dispatch the touch events, waiting for paints after each row in
     63      // zoom_out.
     64      let touchIds = [0, 1];
     65      for (let i = 0; i < zoom_out.length; i++) {
     66        let entry = zoom_out[i];
     67        for (let j = 0; j < entry.length; j++) {
     68          await new Promise(resolve => {
     69            utils.sendNativeTouchPoint(
     70              touchIds[j],
     71              utils.TOUCH_CONTACT,
     72              entry[j].x,
     73              entry[j].y,
     74              1,
     75              90,
     76              resolve
     77            );
     78          });
     79        }
     80        await promiseAllPaintsDone();
     81 
     82        // On the last row also do the touch-up events
     83        if (i == zoom_out.length - 1) {
     84          for (let j = 0; j < entry.length; j++) {
     85            await new Promise(resolve => {
     86              utils.sendNativeTouchPoint(
     87                touchIds[j],
     88                utils.TOUCH_REMOVE,
     89                entry[j].x,
     90                entry[j].y,
     91                1,
     92                90,
     93                resolve
     94              );
     95            });
     96          }
     97        }
     98      }
     99 
    100      // Wait for everything to stabilize
    101      await promiseApzFlushedRepaints();
    102 
    103      // Verify that the zoom completed and we're back at 1.0 resolution
    104      isfuzzy(await getResolution(), 1.0, 0.0001, "should be back at initial resolution");
    105    }
    106 
    107    waitUntilApzStable().then(test).then(subtestDone, subtestFailed);
    108  </script>
    109 </body>
    110 </html>