tor-browser

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

helper_tap_passive.html (2822B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <meta name="viewport" content="width=device-width; initial-scale=1.0">
      6  <title>Ensure APZ doesn't wait for passive listeners</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 type="application/javascript">
     11 
     12 var touchdownTime;
     13 
     14 async function longPressLink() {
     15  await synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, function() {
     16    dump("Finished synthesizing touch-start, waiting for events...\n");
     17  });
     18 }
     19 
     20 var touchstartReceived = false;
     21 function recordEvent(e) {
     22  if (!touchstartReceived) {
     23    touchstartReceived = true;
     24    is(e.type, "touchstart", "Got a touchstart");
     25    e.preventDefault(); // should be a no-op because it's a passive listener
     26    return;
     27  }
     28 
     29  // If APZ decides to wait for the content response on a particular input block,
     30  // it needs to wait until both the touchstart and touchmove event are handled
     31  // by the main thread. In this case there is no touchmove at all, so APZ would
     32  // end up waiting indefinitely and time out the test. The fact that we get this
     33  // contextmenu event (mouselongtap on Windows) at all means that APZ decided
     34  // not to wait for the content response, which is the desired behaviour, since
     35  // the touchstart listener was registered as a passive listener.
     36  if (getPlatform() == "windows") {
     37    is(e.type, "mouselongtap", "Got a mouselongtap");
     38  } else {
     39    is(e.type, "contextmenu", "Got a contextmenu");
     40  }
     41  e.preventDefault();
     42 
     43  setTimeout(async () => {
     44    // On Windows below TOUCH_REMOVE event triggers opening a context menu, we
     45    // need to prevent it.
     46    const contextmenuPromise = promiseOneEvent(window, "contextmenu", event => {
     47      event.preventDefault();
     48      return true;
     49    });
     50    const touchendPromise = promiseOneEvent(window, "touchend", () => {
     51      return true;
     52    });
     53    await synthesizeNativeTouch(document.getElementById("b"), 5, 5, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, function() {
     54      dump("Finished synthesizing touch-end to clear state; finishing test...\n");
     55    });
     56 
     57    await touchendPromise;
     58    if (getPlatform() == "windows") {
     59      await contextmenuPromise;
     60    }
     61    subtestDone();
     62  }, 0);
     63 }
     64 
     65 window.addEventListener("touchstart", recordEvent, { passive: true, capture: true });
     66 if (getPlatform() == "windows") {
     67  SpecialPowers.addChromeEventListener("mouselongtap", recordEvent, true);
     68 } else {
     69  window.addEventListener("contextmenu", recordEvent, true);
     70 }
     71 
     72 waitUntilApzStable()
     73 .then(longPressLink);
     74 
     75  </script>
     76 </head>
     77 <body>
     78 <a id="b" href="#">Link to nowhere</a>
     79 </body>
     80 </html>