Bug 1460453 [wpt PR 10942] - Ignore preventDefault() for 'vertical-scroll', a=testonly
authorEhsan Karamad <ekaramad@chromium.org>
Wed, 06 Jun 2018 16:51:02 +0000
changeset 476442 52788d5f43f2184e0ec518c93c1d6f3a9749ab5e
parent 476441 1b34fe461447c5526598520d29eaddac8294ab7c
child 476443 cc6299605cfd1da0f219fda288f2a42837935a95
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1460453, 10942, 611982, 1053175, 562856
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1460453 [wpt PR 10942] - Ignore preventDefault() for 'vertical-scroll', a=testonly Automatic update from web-platform-testsIgnore preventDefault() for 'vertical-scroll' This CL adds the logic to ensure calling event.preventDefault() will not block vertical scrolling for frames which do not have the feature policy enabled. Essentially, the response from dispatching the dom event is overwritten by "not canceled" and the event is marked as not prevented. In line with this, and in order to make sure only vertical scroll is enforced, the allowed touch action is set to 'pan-y'; then any scrolling along the x-axis can still be blocked by prventDefault()-ing the event. Bug: 611982 Change-Id: Iba371be063bf064601ecce6e930424c4fb11ac26 Reviewed-on: https://chromium-review.googlesource.com/1053175 Commit-Queue: Ehsan Karamad <ekaramad@chromium.org> Reviewed-by: Robert Flack <flackr@chromium.org> Cr-Commit-Position: refs/heads/master@{#562856} -- wpt-commits: c2934c9ddd3c9c8e45b987dd75286e2793192306 wpt-pr: 10942
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/feature-policy/experimental-features/resources/vertical-scroll-touch-block.html
testing/web-platform/tests/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -11156,16 +11156,22 @@
     ]
    ],
    "feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html": [
     [
      "/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html",
      {}
     ]
    ],
+   "feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html": [
+    [
+     "/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html",
+     {}
+    ]
+   ],
    "fullscreen/api/document-exit-fullscreen-manual.html": [
     [
      "/fullscreen/api/document-exit-fullscreen-manual.html",
      {}
     ]
    ],
    "fullscreen/api/document-exit-fullscreen-nested-in-iframe-manual.html": [
     [
@@ -272873,16 +272879,21 @@
      {}
     ]
    ],
    "feature-policy/experimental-features/resources/vertical-scroll-touch-action.html": [
     [
      {}
     ]
    ],
+   "feature-policy/experimental-features/resources/vertical-scroll-touch-block.html": [
+    [
+     {}
+    ]
+   ],
    "feature-policy/experimental-features/resources/vertical-scroll.js": [
     [
      {}
     ]
    ],
    "feature-policy/experimental-features/resources/video.ogv": [
     [
      {}
@@ -558506,16 +558517,20 @@
   "feature-policy/experimental-features/resources/vertical-scroll-scrollintoview.html": [
    "7be60c6f51698ea1e63030bf94aad995881e0049",
    "support"
   ],
   "feature-policy/experimental-features/resources/vertical-scroll-touch-action.html": [
    "a85e54c23c9e055c959a86187d07f1c0d943f37d",
    "support"
   ],
+  "feature-policy/experimental-features/resources/vertical-scroll-touch-block.html": [
+   "b0574f00487af6997cbec51eed426bada4912bcf",
+   "support"
+  ],
   "feature-policy/experimental-features/resources/vertical-scroll.js": [
    "a62c440428fe22a7afd4d8174e47dfc483c7de90",
    "support"
   ],
   "feature-policy/experimental-features/resources/video.ogv": [
    "7c6d80135c0688eb5ef5e79351c8ebbd24cb7d77",
    "support"
   ],
@@ -558530,16 +558545,20 @@
   "feature-policy/experimental-features/vertical-scroll-scrollintoview.tentative.html": [
    "032bcf5ef253650570c3ded97090aab45da2661c",
    "testharness"
   ],
   "feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html": [
    "32f1b7eacf4de1d7d792bb27ca439636c242c29c",
    "manual"
   ],
+  "feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html": [
+   "ae88b77a9d913ee830fc4a84cf1e4007942c63fb",
+   "manual"
+  ],
   "feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html": [
    "a48c092204750e00c9aa167a9ef9d2d239445d22",
    "testharness"
   ],
   "feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html.sub.headers": [
    "bfcf350d87faae8e6cf4b2beb9fee84957cac449",
    "support"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/feature-policy/experimental-features/resources/vertical-scroll-touch-block.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<style>
+body, div, html {
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+}
+p {
+  margin-bottom: 1000px;
+  margin-right: 1000px;
+}
+</style>
+<body>
+  <div id="blocker">
+    <p>This page blocks 'touchstart' and 'touchmove'.</p>
+  </div>
+  <script>
+    function doSomethingUnimportant(e) {
+      return false !== e;
+    }
+
+    function preventDefault(e) {
+      e.preventDefault();
+    }
+
+    document.addEventListener("touchstart", doSomethingUnimportant, {passive: false});
+    document.addEventListener("touchmove", doSomethingUnimportant, {passive: false});
+
+    function messageHandler(e) {
+      let msg = e.data;
+      let element = document.querySelector(msg.query);
+      if (msg.prevent) {
+        element.addEventListener(msg.event_type, preventDefault, {passive: false});
+      } else {
+        element.addEventListener(msg.event_type, doSomethingUnimportant);
+      }
+      e.source.postMessage(msg, "*");
+    }
+
+    window.addEventListener("message", messageHandler);
+  </script>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html
@@ -0,0 +1,237 @@
+<!doctype html>
+<title>vertical-scroll test for touch-action</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/feature-policy/experimental-features/resources/common.js"></script>
+<script src="/feature-policy/experimental-features/resources/vertical-scroll.js"></script>
+<style>
+html, body {
+  height: 100%;
+  width: 100%;
+}
+
+iframe {
+  width: 90%;
+  height: 90%;
+  margin: 0;
+  padding: 0;
+}
+
+.spacer {
+  width: 100%;
+  height: 100%;
+  margin: 100%;
+}
+</style>
+<iframe></iframe>
+<br/>
+<p>Spacers below to make page scrollable</p>
+<br/>
+<div class="spacer"></div>
+<div class="spacer"></div>
+<p> EOF </p>
+
+<script>
+  "use strict";
+
+  let url = url_base + "vertical-scroll-touch-block.html";
+  let iframeElement = document.querySelector("iframe");
+
+  // Wait for the helper scripts to load.
+  promise_test(async() => {
+    if (window.touch_scroll_api_ready)
+      return Promise.resolve();
+    await new Promise( (r) => {
+      window.resolve_on_touch_scroll_api_ready = r;
+    });
+
+  }, "Make sure input injection API is ready.");
+
+  // Sanity-check: Verify we can scroll using the test-API. The <iframe> with no
+  // query arguments would not preventDefault() any events.
+  promise_test(async() => {
+    window.scrollTo(0, 0);
+    await loadUrlInIframe(iframeElement, url);
+
+    await inject_scroll("down");
+    assert_greater_than(window.scrollY, 0, "Page must have scrolled down.");
+
+    await inject_scroll("right");
+    assert_greater_than(window.scrollX, 0, "Page must have scrolled right.");
+  }, "Verify that the page normally scrolls.");
+
+  // Enable 'vertical-scroll': Blocking "touchstart" can block scrolling.
+  promise_test(async() => {
+    window.scrollTo(0, 0);
+    setFeatureState(iframeElement, "vertical-scroll", "*");
+    await loadUrlInIframe(iframeElement, url);
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+
+    await inject_scroll("down");
+    assert_equals(window.scrollY,
+                  0,
+                  "Main frame must not scroll vertically.");
+  }, "Calling 'preventDefault' on 'touchstart' blocks vertical scroll when " +
+     " the feature is enabled.");
+
+  // Disable 'vertical-scroll': Blocking "touchstart" cannot block vertical
+  // scroll.
+  promise_test(async() => {
+    window.scrollTo(0, 0);
+    setFeatureState(iframeElement, "vertical-scroll", "'none'");
+    await loadUrlInIframe(iframeElement, url);
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+
+    await inject_scroll("down");
+    assert_greater_than(window.scrollY,
+                        0,
+                        "Main frame must scroll vertically.");
+
+    // Horizontal scrolling must still be blocked.
+    window.scrollTo(0, 0);
+    await inject_scroll("right");
+    assert_equals(window.scrollX,
+                  0,
+                  "Main frame must not scroll horizontally.");
+  }, "When feature is disabled, calling 'preventDefault' on 'touchstart' does" +
+     " not block vertical scroll, but still bocks horizontal scroll.");
+
+  // Enable 'vertical-scroll': Blocking "touchmove" can block scrolling.
+  promise_test(async() => {
+    // Make sure <window> can scroll both towards right and bottom.
+    window.scrollTo(0, 0);
+    setFeatureState(iframeElement, "vertical-scroll", "*");
+    await loadUrlInIframe(iframeElement, url);
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchmove",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+
+    await inject_scroll("down");
+    assert_equals(window.scrollY,
+                  0,
+                  "Main frame must not scroll vertically");
+  }, "Calling 'preventDefault' on 'touchmove' blocks vertical scroll when " +
+     "the feature is enabled.");
+
+  // Disable 'vertical-scroll': Blocking "touchmove" cannot block vertical
+  // scroll.
+  promise_test(async() => {
+    window.scrollTo(0, 0);
+    setFeatureState(iframeElement, "vertical-scroll", "'none'");
+    await loadUrlInIframe(iframeElement, url);
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchmove",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+    await new Promise((r) => {
+      window.setTimeout(r, 100);
+    });
+
+    await inject_scroll("down");
+    assert_greater_than(window.scrollY,
+                        0,
+                        "Main frame must scroll vertically.");
+  }, "When feature is disabled, calling 'preventDefault' on 'touchmove' does" +
+     " not block vertical scroll.");
+
+  // Disable 'vertical-scroll': Add a non-preventing handler, and then a
+  // preventing handler and verify vertical scroll is possible and horizontal
+  // is blocked.
+  promise_test(async() => {
+    setFeatureState(iframeElement, "vertical-scroll", "'none'");
+    await loadUrlInIframe(iframeElement, url);
+
+    // Add a non-blocking handler.
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: false
+                                    });
+
+    window.scrollTo(0, 0);
+    await inject_scroll("down");
+    assert_greater_than(window.scrollY, 0, "Page must have scrolled down.");
+
+    window.scrollTo(0, 0);
+    await inject_scroll("right");
+    assert_greater_than(window.scrollX, 0, "Page must have scrolled right.");
+
+    // Add a blocking handler.
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+    window.scrollTo(0, 0);
+    await inject_scroll("down");
+    assert_greater_than(window.scrollY,
+                        0,
+                        "Page must have scrolled down (preventing handler).");
+
+    window.scrollTo(0, 0);
+    await inject_scroll("right");
+    assert_equals(window.scrollX,
+                  0,
+                  "Page must not have scrolled horizontally.");
+  }, "Verify that starting with a non-preventing listener and then switching" +
+     " to a preventing one works as intended.");
+
+  // Disable 'vertical-scroll': A preventing 'touchstart' handler does not allow
+  // other multi-touch actions such as 'pinch-zoom'.
+  promise_test(async() => {
+    assert_true(!!window.visualViewport,
+                "'visualViewport' is needed for this test.");
+
+    setFeatureState(iframeElement, "vertical-scroll", "'none'");
+    await loadUrlInIframe(iframeElement, url);
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: false
+                                    });
+
+    // Sanity check: Pinch zoom in should work since 'touchstart' is not
+    // preventing.
+    let current_scale_factor = window.visualViewport.scale;
+    await inject_zoom("in");
+    let new_scale_factor = window.visualViewport.scale;
+    assert_greater_than(
+        new_scale_factor,
+        current_scale_factor,
+        "Pinch zoom should work since 'touchstart' is not prevented.");
+
+    // Add a preventing handler and verify pinch zoom is now blocked.
+    await sendMessageAndGetResponse(iframeElement.contentWindow,
+                                    {
+                                      event_type: "touchstart",
+                                      query: "#blocker",
+                                      prevent: true
+                                    });
+    current_scale_factor = new_scale_factor;
+    await inject_zoom("out");
+    new_scale_factor = window.visualViewport.scale;
+    assert_equals(
+        new_scale_factor,
+        current_scale_factor,
+        "Pinch zoom must be blocked.")
+  }, "Verify that pinch zoom is blocked in frames with 'vertical-scroll' none'" +
+     " where 'touchstart' is prevent defaulted.");
+</script>