Update touch event tracking type on every touch
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 May 2018 23:50:19 +0000 (23:50 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 May 2018 23:50:19 +0000 (23:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184250
<rdar://problem/39145092>

Patch by Tadeu Zagallo <tzagallo@apple.com> on 2018-05-15
Reviewed by Geoffrey Garen.

The tracking type for touch events were only update on touchstart, which meant that event
listeners added after the touchstart would always be treated as passive, even if explicitly
setting passive to false.

Source/WebKit:

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleTouchEventSynchronously):
(WebKit::WebPageProxy::handleTouchEvent):

LayoutTests:

* fast/events/touch/ios/touchmove-cancelable-after-touchstart-expected.txt: Added.
* fast/events/touch/ios/touchmove-cancelable-after-touchstart.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart.html [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/WebPageProxy.cpp

index 20fe42c..8990cd7 100644 (file)
@@ -1,3 +1,18 @@
+2018-05-15  Tadeu Zagallo  <tzagallo@apple.com>
+
+        Update touch event tracking type on every touch
+        https://bugs.webkit.org/show_bug.cgi?id=184250
+        <rdar://problem/39145092>
+
+        Reviewed by Geoffrey Garen.
+
+        The tracking type for touch events were only update on touchstart, which meant that event
+        listeners added after the touchstart would always be treated as passive, even if explicitly
+        setting passive to false.
+
+        * fast/events/touch/ios/touchmove-cancelable-after-touchstart-expected.txt: Added.
+        * fast/events/touch/ios/touchmove-cancelable-after-touchstart.html: Added.
+
 2018-05-15  Jer Noble  <jer.noble@apple.com>
 
         Media continues loading after rendered invisible (removed from DOM; scrolled off screen)
diff --git a/LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart-expected.txt b/LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart-expected.txt
new file mode 100644 (file)
index 0000000..bdc35c1
--- /dev/null
@@ -0,0 +1,12 @@
+Test that touchmove can be cancelled from event listeners dynamically added after touchstart
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS event.cancelable is true
+PASS event.defaultPrevented is true
+PASS document.body.scrollTop is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart.html b/LayoutTests/fast/events/touch/ios/touchmove-cancelable-after-touchstart.html
new file mode 100644 (file)
index 0000000..c84a16d
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <script src="../../../../resources/js-test-pre.js"></script>
+    <style>
+    #square {
+        position: absolute;
+        left: 100px;
+        top: 100px;
+        width: 150px;
+        height: 2000px;
+        background: red;
+        opacity: 0.5;
+    }
+    </style>
+</head>
+
+<body>
+<div id="square" style=""></div>
+
+<script>
+description("Test that touchmove can be cancelled from event listeners dynamically added after touchstart");
+window.jsTestIsAsync = true;
+
+const getUIScript = (startX, startY, endX, endY) => `
+(function() {
+     var eventStream = {
+         events : [{
+            interpolate: "linear",
+            timestep: 0.025,
+            startEvent: {
+                inputType: "hand",
+                timeOffset: 0,
+                touches: [{
+                    inputType: "finger",
+                    phase: "began",
+                    id: 1,
+                    x: ${startX},
+                    y: ${startY},
+                    pressure: 0
+                }]
+            },
+            endEvent: {
+                inputType: "hand",
+                timeOffset: 3.0,
+                touches: [{
+                    inputType: "finger",
+                    phase: "stationary",
+                    id: 1,
+                    x: ${endX},
+                    y: ${endY},
+                    pressure : 500
+                }]
+            }
+        }]
+    };
+
+    uiController.sendEventStream(JSON.stringify(eventStream), function() {
+        uiController.uiScriptComplete();
+    });
+})();
+`;
+
+function runTest()
+{
+    function touchmoveEventHandler(event)
+    {
+        shouldBe("event.cancelable", "true");
+        event.preventDefault();
+        shouldBe("event.defaultPrevented", "true");
+    }
+
+    const square = document.querySelector('#square');
+    document.addEventListener("touchstart", event => {
+        // NOTE: For some reason, if we don't interact with the DOM here, the first few touchmove events we see will be passive (not cancelable)
+        // See https://bugs.webkit.org/show_bug.cgi?id=185656
+        document.body.appendChild(document.createElement('p'));
+        if (event.target === square)
+            window.addEventListener("touchmove", touchmoveEventHandler, { passive: false, once: true });
+    }, { passive: false, once: true });
+
+    if (window.testRunner) {
+        let clientRect = square.getBoundingClientRect();
+        testRunner.runUIScript(getUIScript(clientRect.left + 50, clientRect.top + 200, clientRect.left + 50, clientRect.top + 10), () => {
+            shouldBe("document.body.scrollTop", "0");
+            finishJSTest();
+        });
+    }
+}
+
+window.addEventListener('load', runTest, false);
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 0c9ec66..19c413c 100644 (file)
@@ -1,3 +1,19 @@
+2018-05-15  Tadeu Zagallo  <tzagallo@apple.com>
+
+        Update touch event tracking type on every touch
+        https://bugs.webkit.org/show_bug.cgi?id=184250
+        <rdar://problem/39145092>
+
+        Reviewed by Geoffrey Garen.
+
+        The tracking type for touch events were only update on touchstart, which meant that event
+        listeners added after the touchstart would always be treated as passive, even if explicitly
+        setting passive to false.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleTouchEventSynchronously):
+        (WebKit::WebPageProxy::handleTouchEvent):
+
 2018-05-15  Per Arne Vollan  <pvollan@apple.com>
 
         Pause display links when window is not visible.
index 8a9acf2..cde1000 100644 (file)
@@ -2300,8 +2300,7 @@ void WebPageProxy::handleTouchEventSynchronously(NativeWebTouchEvent& event)
 
     TraceScope scope(SyncTouchEventStart, SyncTouchEventEnd);
 
-    if (event.type() == WebEvent::TouchStart)
-        updateTouchEventTracking(event);
+    updateTouchEventTracking(event);
 
     TrackingType touchEventsTrackingType = touchEventTrackingType(event);
     if (touchEventsTrackingType == TrackingType::NotTracking)
@@ -2355,8 +2354,7 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
     if (!isValid())
         return;
 
-    if (event.type() == WebEvent::TouchStart)
-        updateTouchEventTracking(event);
+    updateTouchEventTracking(event);
 
     if (touchEventTrackingType(event) == TrackingType::NotTracking)
         return;