Title: [264031] trunk
Revision
264031
Author
[email protected]
Date
2020-07-07 11:16:27 -0700 (Tue, 07 Jul 2020)

Log Message

Unable to scroll elcomerico.pe page until the page finishes loading
https://bugs.webkit.org/show_bug.cgi?id=214027
<rdar://problem/64646259>

Reviewed by Antti Koivisto.
Source/WebCore:

<https://elcomercio.pe/mundo/eeuu/que-visas-para-estados-unidos-fueron-suspendidas-por-orden-de-donald-trump-hasta-fin-de-ano-y-a-quien-afecta-la-medida-noticia/>
had a scaleX(0) element as an ancestor of an overflow:scroll. The CALayer hit-testing code failed to take
non-invertible transforms into account, causing the overflow:scroll to intercept scrolling events.

Fix by explicitly testing for non-invertible transforms, and, when found, bailing from the
sublayer walk. A non-invertible layer transform makes all its descendants non hit-testable.

Tests: fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html
       fast/scrolling/mac/non-invertible-transform-hit-testing.html

* page/scrolling/mac/ScrollingTreeMac.mm:
(collectDescendantLayersAtPoint):
* platform/graphics/transforms/TransformationMatrix.h:

Source/WebKit:

The same issue with non-invertible transforms existed on iOS. r248015 attempted to
fix some instances of this, but failed to take into account the fact that a non-invertible
transfrom should also prevent hit-testing of descendant views.

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

LayoutTests:

macOS and iOS tests with non-invertible transforms.

* fast/scrolling/ios/non-invertible-transformed-scroller-ancestor-expected.txt: Added.
* fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html: Added.
* fast/scrolling/mac/non-invertible-transform-hit-testing-expected.txt: Added.
* fast/scrolling/mac/non-invertible-transform-hit-testing.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264030 => 264031)


--- trunk/LayoutTests/ChangeLog	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/LayoutTests/ChangeLog	2020-07-07 18:16:27 UTC (rev 264031)
@@ -1,3 +1,18 @@
+2020-07-07  Simon Fraser  <[email protected]>
+
+        Unable to scroll elcomerico.pe page until the page finishes loading
+        https://bugs.webkit.org/show_bug.cgi?id=214027
+        <rdar://problem/64646259>
+
+        Reviewed by Antti Koivisto.
+
+        macOS and iOS tests with non-invertible transforms.
+
+        * fast/scrolling/ios/non-invertible-transformed-scroller-ancestor-expected.txt: Added.
+        * fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html: Added.
+        * fast/scrolling/mac/non-invertible-transform-hit-testing-expected.txt: Added.
+        * fast/scrolling/mac/non-invertible-transform-hit-testing.html: Added.
+
 2020-07-07  Tim Horton  <[email protected]>
 
         <attachment> layout does not scale with Dynamic Type size changes

Added: trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor-expected.txt (0 => 264031)


--- trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor-expected.txt	2020-07-07 18:16:27 UTC (rev 264031)
@@ -0,0 +1,11 @@
+An overflow scrolling inside a scale(0) layer should not hit-test
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS windowScrollTop > 0 is true
+PASS overflowScrollTop is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html (0 => 264031)


--- trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html	2020-07-07 18:16:27 UTC (rev 264031)
@@ -0,0 +1,60 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+        
+        .scale0 {
+            width: 100px;
+            height: 100px;
+            border: 1px solid black;
+            transform: scaleX(0);
+        }
+        
+        #scroller {
+            width: 200px;
+            height: 200px;
+            overflow-y: scroll;
+            border: 1px solid black;
+        }
+        
+        .contents {
+            height: 300%;
+        }
+        
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        var jsTestIsAsync = true;
+
+        var windowScrollTop;
+        var overflowScrollTop;
+        
+        window.addEventListener('load', async () => {
+            description('An overflow scrolling inside a scale(0) layer should not hit-test');
+
+            await UIHelper.immediateScrollElementAtContentPointToOffset(20, 20, 0, 100);
+
+            windowScrollTop = document.scrollingElement.scrollTop;
+            overflowScrollTop = scroller.scrollTop;
+
+            shouldBe('windowScrollTop > 0', 'true');
+            shouldBe('overflowScrollTop', '0');
+
+            finishJSTest();
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scale0">
+        <div id="scroller">
+            <div class="contents"></div>
+        </div>
+    </div>
+    <div id="console"></div>
+    <script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing-expected.txt (0 => 264031)


--- trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing-expected.txt	2020-07-07 18:16:27 UTC (rev 264031)
@@ -0,0 +1,8 @@
+
+Test scroll over content
+PASS overflowScrollEventCount is 0
+PASS windowScrollEventCount > 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing.html (0 => 264031)


--- trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/non-invertible-transform-hit-testing.html	2020-07-07 18:16:27 UTC (rev 264031)
@@ -0,0 +1,72 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+        }
+        
+        .scale0 {
+            width: 100px;
+            height: 100px;
+            border: 1px solid black;
+            transform: scaleX(0);
+        }
+        
+        .scroller {
+            width: 200px;
+            height: 200px;
+            overflow-y: scroll;
+            border: 1px solid black;
+        }
+        
+        .contents {
+            height: 300%;
+        }
+        
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        var jsTestIsAsync = true;
+
+        var scroller;
+        var overflowScrollEventCount = 0;
+        var windowScrollEventCount = 0;
+
+        async function scrollTest()
+        {
+            debug('');
+            debug('Test scroll over content');
+            await UIHelper.mouseWheelScrollAt(20, 20);
+
+            shouldBe('overflowScrollEventCount', '0');
+            shouldBe('windowScrollEventCount > 0', 'true');
+
+            finishJSTest();
+        }
+
+        window.addEventListener('load', () => {
+            scroller = document.querySelector('.scroller');
+            scroller.addEventListener('scroll', () => {
+                ++overflowScrollEventCount;
+            }, false);
+
+            window.addEventListener('scroll', () => {
+                ++windowScrollEventCount;
+            }, false);
+
+            setTimeout(scrollTest, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scale0">
+        <div class="scroller">
+            <div class="contents"></div>
+        </div>
+    </div>
+    <div id="console"></div>
+    <script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (264030 => 264031)


--- trunk/Source/WebCore/ChangeLog	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/Source/WebCore/ChangeLog	2020-07-07 18:16:27 UTC (rev 264031)
@@ -1,3 +1,25 @@
+2020-07-07  Simon Fraser  <[email protected]>
+
+        Unable to scroll elcomerico.pe page until the page finishes loading
+        https://bugs.webkit.org/show_bug.cgi?id=214027
+        <rdar://problem/64646259>
+
+        Reviewed by Antti Koivisto.
+        
+        <https://elcomercio.pe/mundo/eeuu/que-visas-para-estados-unidos-fueron-suspendidas-por-orden-de-donald-trump-hasta-fin-de-ano-y-a-quien-afecta-la-medida-noticia/>
+        had a scaleX(0) element as an ancestor of an overflow:scroll. The CALayer hit-testing code failed to take
+        non-invertible transforms into account, causing the overflow:scroll to intercept scrolling events.
+
+        Fix by explicitly testing for non-invertible transforms, and, when found, bailing from the
+        sublayer walk. A non-invertible layer transform makes all its descendants non hit-testable.
+
+        Tests: fast/scrolling/ios/non-invertible-transformed-scroller-ancestor.html
+               fast/scrolling/mac/non-invertible-transform-hit-testing.html
+
+        * page/scrolling/mac/ScrollingTreeMac.mm:
+        (collectDescendantLayersAtPoint):
+        * platform/graphics/transforms/TransformationMatrix.h:
+
 2020-07-07  Peng Liu  <[email protected]>
 
         Function didCleanupFullscreencreen() should be called at the end of VideoFullscreenInterfaceAVKit::cleanupFullscreen()

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm (264030 => 264031)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeMac.mm	2020-07-07 18:16:27 UTC (rev 264031)
@@ -89,6 +89,10 @@
         if ([[layer animationKeys] count])
             layerWithResolvedAnimations = [layer presentationLayer];
 
+        auto transform = TransformationMatrix { [layerWithResolvedAnimations transform] };
+        if (!transform.isInvertible())
+            continue;
+
         CGPoint subviewPoint = [layerWithResolvedAnimations convertPoint:point fromLayer:parent];
 
         auto handlesEvent = [&] {

Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h (264030 => 264031)


--- trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h	2020-07-07 18:16:27 UTC (rev 264031)
@@ -279,7 +279,7 @@
     // Returns a transformation that maps a rect to a rect.
     WEBCORE_EXPORT static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&);
 
-    bool isInvertible() const; // If you call this this, you're probably doing it wrong.
+    WEBCORE_EXPORT bool isInvertible() const;
     WEBCORE_EXPORT Optional<TransformationMatrix> inverse() const;
 
     // Decompose the matrix into its component parts.

Modified: trunk/Source/WebKit/ChangeLog (264030 => 264031)


--- trunk/Source/WebKit/ChangeLog	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/Source/WebKit/ChangeLog	2020-07-07 18:16:27 UTC (rev 264031)
@@ -1,3 +1,18 @@
+2020-07-07  Simon Fraser  <[email protected]>
+
+        Unable to scroll elcomerico.pe page until the page finishes loading
+        https://bugs.webkit.org/show_bug.cgi?id=214027
+        <rdar://problem/64646259>
+
+        Reviewed by Antti Koivisto.
+
+        The same issue with non-invertible transforms existed on iOS. r248015 attempted to
+        fix some instances of this, but failed to take into account the fact that a non-invertible
+        transfrom should also prevent hit-testing of descendant views.
+
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+        (WebKit::collectDescendantViewsAtPoint):
+
 2020-07-07  Alex Christensen  <[email protected]>
 
         Add WebCoreNSURLSession SPI to send HTTP/2 ping

Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm (264030 => 264031)


--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2020-07-07 18:03:15 UTC (rev 264030)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm	2020-07-07 18:16:27 UTC (rev 264031)
@@ -35,6 +35,7 @@
 #import "WKDeferringGestureRecognizer.h"
 #import "WKDrawingView.h"
 #import <WebCore/Region.h>
+#import <WebCore/TransformationMatrix.h>
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
 #import <wtf/SoftLinking.h>
 
@@ -48,6 +49,10 @@
     for (UIView *view in [parent subviews]) {
         CGPoint subviewPoint = [view convertPoint:point fromView:parent];
 
+        auto transform = WebCore::TransformationMatrix { [view.layer transform] };
+        if (!transform.isInvertible())
+            continue;
+
         auto handlesEvent = [&] {
             // FIXME: isUserInteractionEnabled is mostly redundant with event regions for web content layers.
             //        It is currently only needed for scroll views.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to