summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html')
-rw-r--r--gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html129
1 files changed, 129 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html b/gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html
new file mode 100644
index 0000000000..8aff3103dd
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_hittest_overscroll_contextmenu.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test APZ hit-testing while overscrolled</title>
+ <script type="application/javascript" src="apz_test_utils.js"></script>
+ <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+ <script src="/tests/SimpleTest/paint_listener.js"></script>
+ <meta name="viewport" content="width=device-width"/>
+ <style>
+ html, body {
+ margin: 0;
+ padding: 0;
+ }
+ .spacer {
+ height: 5000px;
+ }
+ #target {
+ margin-left: 100px;
+ margin-top: 2px;
+ height: 4px;
+ width: 4px;
+ background: red;
+ }
+ </style>
+</head>
+<body>
+ <div id="target"></div>
+ <div class="spacer"></div>
+</body>
+<script type="application/javascript">
+
+// Some helper functions for listening for contextmenu events in the browser chrome.
+
+// A handle used to interact with the chrome script used to implement
+// [start|stop]ListeningForContextmenuEventsInChrome().
+let chromeScriptHandle = null;
+
+function startListeningForContextmenuEventsInChrome() {
+ function chromeScript() {
+ /* eslint-env mozilla/chrome-script */
+ let topWin = Services.wm.getMostRecentWindow("navigator:browser");
+ if (!topWin) {
+ topWin = Services.wm.getMostRecentWindow("navigator:geckoview");
+ }
+ let chromeReceivedContextmenu = false;
+ function chromeListener(e) {
+ chromeReceivedContextmenu = true;
+ }
+ topWin.addEventListener("contextmenu", chromeListener);
+ function queryContextmenu() {
+ sendAsyncMessage("query-contextmenu-response", { chromeReceivedContextmenu });
+ }
+ function cleanup() {
+ topWin.removeEventListener("contextmenu", chromeListener);
+ removeMessageListener("query-contextmenu", queryContextmenu);
+ removeMessageListener("cleanup", cleanup);
+ }
+ addMessageListener("query-contextmenu", queryContextmenu);
+ addMessageListener("cleanup", cleanup);
+ }
+ chromeScriptHandle = SpecialPowers.loadChromeScript(chromeScript);
+}
+
+async function didChromeReceiveContextmenu() {
+ chromeScriptHandle.sendAsyncMessage("query-contextmenu", null);
+ let response = await chromeScriptHandle.promiseOneMessage("query-contextmenu-response");
+ ok(response && ("chromeReceivedContextmenu" in response),
+ "Received a well-formed response from chrome script");
+ return response.chromeReceivedContextmenu;
+}
+
+function stopListeningForContextmenuEventsInChrome() {
+ chromeScriptHandle.sendAsyncMessage("cleanup", null);
+ chromeScriptHandle.destroy();
+}
+
+async function test() {
+ var config = getHitTestConfig();
+ var utils = config.utils;
+
+ // Overscroll the root scroll frame at the top, creating a gutter.
+ // Note that the size of the gutter will only be 8px, because
+ // setAsyncScrollOffset() applies the overscroll as a single delta,
+ // and current APZ logic that transforms a delta into an overscroll
+ // amount limits each delta to at most 8px.
+ utils.setAsyncScrollOffset(document.documentElement, 0, -200);
+
+ // Now, perform a right-click in the gutter and check that APZ prevents
+ // the contextevent from reaching Gecko.
+ // To be sure that no event was dispatched to Gecko, install listeners
+ // on both the browser chrome window and the content window.
+ // This makes sure we catch the case where the overscroll transform causes
+ // the event to incorrectly target the browser chrome.
+ let deviceScale = window.devicePixelRatio;
+ let midGutter = 4 / deviceScale; // gutter is 8 *screen* pixels
+ startListeningForContextmenuEventsInChrome();
+ let contentReceivedContextmenu = false;
+ let contentListener = function(e) {
+ contentReceivedContextmenu = true;
+ };
+ document.addEventListener("contextmenu", contentListener);
+ await synthesizeNativeMouseEventWithAPZ({
+ type: "click",
+ button: 2, // eSecondary (= "right mouse button")
+ target: window,
+ offsetX: 100,
+ offsetY: midGutter
+ });
+ // Wait 10 frames for the event to maybe arrive, and if it
+ // hasn't, assume it won't.
+ for (let i = 0; i < 10; i++) {
+ await promiseFrame();
+ }
+ info("Finished waiting around for contextmenu event");
+ let chromeReceivedContextmenu = await didChromeReceiveContextmenu();
+ ok(!chromeReceivedContextmenu,
+ "Gecko received contextmenu event in browser chrome when it shouldn't have");
+ ok(!contentReceivedContextmenu,
+ "Gecko received contextmenu event targeting web content when it shouldn't have");
+ stopListeningForContextmenuEventsInChrome();
+ document.removeEventListener("contextmenu", contentListener);
+}
+
+waitUntilApzStable()
+.then(test)
+.then(subtestDone, subtestFailed);
+
+</script>
+</html>