Content in <iframe> should override "touch-action" set in embedding document
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Aug 2019 08:50:13 +0000 (08:50 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Aug 2019 08:50:13 +0000 (08:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200204
<rdar://problem/54355249>

Reviewed by Antoine Quint.

Source/WebKit:

Subframes where content doesn't use any touch-action properties won't generate event region for their main layer.
As a result the touch-action property gets computed in UI process to the parent frames touch-action (instead of 'auto').

* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(WebKit::touchActionsForPoint):

If the topmost layer hit is a WKChildScrollView we know its content layer didn't have an event region.
This means we should return the default value 'auto'.

LayoutTests:

* pointerevents/ios/touch-action-none-with-frame-inside-expected.txt: Added.
* pointerevents/ios/touch-action-none-with-frame-inside.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside-expected.txt [new file with mode: 0644]
LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside.html [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm

index c9d6edf..e131a68 100644 (file)
@@ -1,3 +1,14 @@
+2019-08-17  Antti Koivisto  <antti@apple.com>
+
+        Content in <iframe> should override "touch-action" set in embedding document
+        https://bugs.webkit.org/show_bug.cgi?id=200204
+        <rdar://problem/54355249>
+
+        Reviewed by Antoine Quint.
+
+        * pointerevents/ios/touch-action-none-with-frame-inside-expected.txt: Added.
+        * pointerevents/ios/touch-action-none-with-frame-inside.html: Added.
+
 2019-08-16  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r248772.
diff --git a/LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside-expected.txt b/LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside-expected.txt
new file mode 100644 (file)
index 0000000..4011ed9
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+Scrolled
diff --git a/LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside.html b/LayoutTests/pointerevents/ios/touch-action-none-with-frame-inside.html
new file mode 100644 (file)
index 0000000..a5c2332
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<script src="../../resources/basic-gestures.js"></script>
+<style>
+body { touch-action:none }
+</style>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+
+function waitPromise(delay) {
+    return new Promise(resolve => setTimeout(resolve, delay));
+}
+
+async function runTest() {
+    if (!window.testRunner)
+        return;
+
+    await touchAndDragFromPointToPoint(100, 100, 100, 50);
+    await liftUpAtPoint(100, 50);
+    await waitPromise(1000);
+
+    testRunner.notifyDone();
+}
+</script>
+<body onload="runTest()">
+<iframe srcdoc="
+    <html>
+    <script>
+    function scroll() {
+        document.body.innerText = 'Scrolled';
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }
+    </script>
+    <body style='height:1000px' onscroll='scroll()'>
+    This document should be scrollable.
+    </body>
+    </html>
+" width=500 height=500>
+</iframe>
+</body>
+</html>
index 837b558..ce1bffd 100644 (file)
@@ -1,3 +1,20 @@
+2019-08-17  Antti Koivisto  <antti@apple.com>
+
+        Content in <iframe> should override "touch-action" set in embedding document
+        https://bugs.webkit.org/show_bug.cgi?id=200204
+        <rdar://problem/54355249>
+
+        Reviewed by Antoine Quint.
+
+        Subframes where content doesn't use any touch-action properties won't generate event region for their main layer.
+        As a result the touch-action property gets computed in UI process to the parent frames touch-action (instead of 'auto').
+
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+        (WebKit::touchActionsForPoint):
+
+        If the topmost layer hit is a WKChildScrollView we know its content layer didn't have an event region.
+        This means we should return the default value 'auto'.
+
 2019-08-16  Chris Dumez  <cdumez@apple.com>
 
         Use strongly typed identifiers for StorageArea / StorageAreaImpl
index 9800670..f613e1c 100644 (file)
@@ -106,6 +106,11 @@ OptionSet<WebCore::TouchAction> touchActionsForPoint(UIView *rootView, const Web
 
     UIView *hitView = nil;
     for (auto *view : WTF::makeReversedRange(viewsAtPoint)) {
+        // We only hit WKChildScrollView directly if its content layer doesn't have an event region.
+        // We don't generate the region if there is nothing interesting in it, meaning the touch-action is auto.
+        if ([view isKindOfClass:[WKChildScrollView class]])
+            return WebCore::TouchAction::Auto;
+
         if ([view isKindOfClass:[WKCompositingView class]]) {
             hitView = view;
             break;