tor-browser

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

helper_hittest_overscroll_contextmenu.html (4598B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Test APZ hit-testing while overscrolled</title>
      5  <script type="application/javascript" src="apz_test_utils.js"></script>
      6  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
      7  <script src="/tests/SimpleTest/paint_listener.js"></script>
      8  <meta name="viewport" content="width=device-width"/>
      9  <style>
     10    html, body {
     11      margin: 0;
     12      padding: 0;
     13    }
     14    .spacer {
     15      height: 5000px;
     16    }
     17    #target {
     18      margin-left: 100px;
     19      margin-top: 2px;
     20      height: 4px;
     21      width: 4px;
     22      background: red;
     23    }
     24  </style>
     25 </head>
     26 <body>
     27 <div id="target"></div>
     28 <div class="spacer"></div>
     29 </body>
     30 <script type="application/javascript">
     31 
     32 // Some helper functions for listening for contextmenu events in the browser chrome.
     33 
     34 // A handle used to interact with the chrome script used to implement
     35 // [start|stop]ListeningForContextmenuEventsInChrome().
     36 let chromeScriptHandle = null;
     37 
     38 function startListeningForContextmenuEventsInChrome() {
     39  function chromeScript() {
     40    /* eslint-env mozilla/chrome-script */
     41    let topWin = Services.wm.getMostRecentWindow("navigator:browser");
     42    if (!topWin) {
     43      topWin = Services.wm.getMostRecentWindow("navigator:geckoview");
     44    }
     45    let chromeReceivedContextmenu = false;
     46    function chromeListener() {
     47      chromeReceivedContextmenu = true;
     48    }
     49    topWin.addEventListener("contextmenu", chromeListener);
     50    function queryContextmenu() {
     51      sendAsyncMessage("query-contextmenu-response", { chromeReceivedContextmenu });
     52    }
     53    function cleanup() {
     54      topWin.removeEventListener("contextmenu", chromeListener);
     55      removeMessageListener("query-contextmenu", queryContextmenu);
     56      removeMessageListener("cleanup", cleanup);
     57    }
     58    addMessageListener("query-contextmenu", queryContextmenu);
     59    addMessageListener("cleanup", cleanup);
     60  }
     61  chromeScriptHandle = SpecialPowers.loadChromeScript(chromeScript);
     62 }
     63 
     64 async function didChromeReceiveContextmenu() {
     65  chromeScriptHandle.sendAsyncMessage("query-contextmenu", null);
     66  let response = await chromeScriptHandle.promiseOneMessage("query-contextmenu-response");
     67  ok(response && ("chromeReceivedContextmenu" in response),
     68     "Received a well-formed response from chrome script");
     69  return response.chromeReceivedContextmenu;
     70 }
     71 
     72 function stopListeningForContextmenuEventsInChrome() {
     73  chromeScriptHandle.sendAsyncMessage("cleanup", null);
     74  chromeScriptHandle.destroy();
     75 }
     76 
     77 async function test() {
     78  var config = getHitTestConfig();
     79  var utils = config.utils;
     80 
     81  // Overscroll the root scroll frame at the top, creating a gutter.
     82  // Note that the size of the gutter will only be 8px, because
     83  // setAsyncScrollOffset() applies the overscroll as a single delta,
     84  // and current APZ logic that transforms a delta into an overscroll
     85  // amount limits each delta to at most 8px.
     86  utils.setAsyncScrollOffset(document.documentElement, 0, -200);
     87 
     88  // Now, perform a right-click in the gutter and check that APZ prevents
     89  // the contextevent from reaching Gecko.
     90  // To be sure that no event was dispatched to Gecko, install listeners
     91  // on both the browser chrome window and the content window.
     92  // This makes sure we catch the case where the overscroll transform causes
     93  // the event to incorrectly target the browser chrome.
     94  let deviceScale = window.devicePixelRatio;
     95  let midGutter = 4 / deviceScale;  // gutter is 8 *screen* pixels
     96  startListeningForContextmenuEventsInChrome();
     97  let contentReceivedContextmenu = false;
     98  let contentListener = function() {
     99    contentReceivedContextmenu = true;
    100  };
    101  document.addEventListener("contextmenu", contentListener);
    102  await synthesizeNativeMouseEventWithAPZ({
    103    type: "click",
    104    button: 2,  // eSecondary (= "right mouse button")
    105    target: window,
    106    offsetX: 100,
    107    offsetY: midGutter
    108  });
    109  // Wait 10 frames for the event to maybe arrive, and if it
    110  // hasn't, assume it won't.
    111  for (let i = 0; i < 10; i++) {
    112    await promiseFrame();
    113  }
    114  info("Finished waiting around for contextmenu event");
    115  let chromeReceivedContextmenu = await didChromeReceiveContextmenu();
    116  ok(!chromeReceivedContextmenu,
    117     "Gecko received contextmenu event in browser chrome when it shouldn't have");
    118  ok(!contentReceivedContextmenu,
    119     "Gecko received contextmenu event targeting web content when it shouldn't have");
    120  stopListeningForContextmenuEventsInChrome();
    121  document.removeEventListener("contextmenu", contentListener);
    122 }
    123 
    124 waitUntilApzStable()
    125 .then(test)
    126 .then(subtestDone, subtestFailed);
    127 
    128 </script>
    129 </html>