Title: [271651] trunk
Revision
271651
Author
simon.fra...@apple.com
Date
2021-01-20 10:34:10 -0800 (Wed, 20 Jan 2021)

Log Message

REGRESSION (Big Sur): position:absolute elements inside nested overflow:scroll don't track scrolling
https://bugs.webkit.org/show_bug.cgi?id=220761
<rdar://problem/69075263>

Reviewed by Antti Koivisto.
Source/WebCore:

When a position:absolute element is inside nested overflow scroll, and its containing block is the outer
scroller, then we failed to make a positioning scrolling tree node for it, so it would fail
to track during async scrolling.

The bug was that RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor() failed
to deal with nested scrollers. The correct question to ask when determining if we need a "Moves" node
is "is there an overflow scroll layer between this layer and its composited ancestor". Previously,
we would just find the enclosing scroller (with the same scrolling scope) and assume we didn't need
a node.

We can also simplify the "Stationary" code path to just ask about scrolling scopes.

Tests: scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html
       scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html
       scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html
       scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor):
(WebCore::isScrolledByOverflowScrollLayer): Deleted.
(WebCore::enclosingCompositedScrollingLayer): Deleted.

LayoutTests:

Add a scrolling tree dump test, and three iOS interactive tests, since testing scrolling-tree-only
behaviors is easier on iOS than macOS. absolute-in-nested-overflow-scroll.html is the basic test.
The two "stacking" variants have an opacity layer below and above the inner scroller to test some
more layer configurations.

* platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-expected.html: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2-expected.html: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-expected.html: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html: Added.
* scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html: Added.
* scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt: Added.
* scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (271650 => 271651)


--- trunk/LayoutTests/ChangeLog	2021-01-20 17:44:15 UTC (rev 271650)
+++ trunk/LayoutTests/ChangeLog	2021-01-20 18:34:10 UTC (rev 271651)
@@ -1,3 +1,26 @@
+2021-01-19  Simon Fraser  <simon.fra...@apple.com>
+
+        REGRESSION (Big Sur): position:absolute elements inside nested overflow:scroll don't track scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=220761
+        <rdar://problem/69075263>
+
+        Reviewed by Antti Koivisto.
+        
+        Add a scrolling tree dump test, and three iOS interactive tests, since testing scrolling-tree-only
+        behaviors is easier on iOS than macOS. absolute-in-nested-overflow-scroll.html is the basic test.
+        The two "stacking" variants have an opacity layer below and above the inner scroller to test some
+        more layer configurations.
+
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-expected.html: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2-expected.html: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-expected.html: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html: Added.
+        * scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html: Added.
+        * scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt: Added.
+        * scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html: Added.
+
 2021-01-20  Sam Weinig  <wei...@apple.com>
 
         Remove remaining non-standard CMYKA support from canvas

Added: trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt (0 => 271651)


--- trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,43 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 1021)
+  (scrollable area parameters
+    (horizontal scroll elasticity 1)
+    (vertical scroll elasticity 1)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,421))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scrollable area size 310 310)
+      (contents size 310 1112)
+      (scrollable area parameters
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 1)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (allows vertical scrolling 1))
+      (children 1
+        (Overflow scrolling node
+          (scrollable area size 298 100)
+          (contents size 596 100)
+          (scrollable area parameters
+            (horizontal scroll elasticity 1)
+            (vertical scroll elasticity 1)
+            (horizontal scrollbar mode 0)
+            (vertical scrollbar mode 0)
+            (allows horizontal scrolling 1))
+        )
+      )
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+  )
+)
+
+

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-expected.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-expected.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-expected.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,79 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            border: 1px solid black;
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 100px;
+            border: 1px solid black;
+        }
+        
+        .content {
+            width: 200%;
+            height: 300%;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+            let scroller = document.querySelector('.scroller');
+            scroller.scrollTo(0, 100);
+            await UIHelper.ensurePresentationUpdate();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="filler"></div>
+        <div class="inner-scroller">
+            <div class="wide"></div>
+            <div class="absolute"></div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2-expected.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2-expected.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2-expected.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,78 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 400px;
+            border: 1px solid black;
+        }
+        
+        .stacking {
+            opacity: 0.8;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+            let scroller = document.querySelector('.scroller');
+            scroller.scrollTo(0, 100);
+            await UIHelper.ensurePresentationUpdate();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="inner-scroller">
+            <div class="wide"></div>
+            <div class="stacking">
+                <div class="absolute"></div>
+            </div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,76 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 400px;
+            border: 1px solid black;
+        }
+        
+        .stacking {
+            opacity: 0.8;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            const scrollUpdatesDisabled = true;
+            await UIHelper.immediateScrollElementAtContentPointToOffset(10, 10, 0, 100, scrollUpdatesDisabled);
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="inner-scroller">
+            <div class="wide"></div>
+            <div class="stacking">
+                <div class="absolute"></div>
+            </div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-expected.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-expected.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-expected.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,79 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 100px;
+            border: 1px solid black;
+        }
+
+        .stacking {
+            opacity: 0.8;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            await UIHelper.ensurePresentationUpdate(); // Not sure why this is necessary, but it is.
+            let scroller = document.querySelector('.scroller');
+            scroller.scrollTo(0, 100);
+            await UIHelper.ensurePresentationUpdate();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="filler"></div>
+        <div class="stacking">
+            <div class="inner-scroller">
+                <div class="wide"></div>
+                <div class="absolute"></div>
+            </div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,77 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 100px;
+            border: 1px solid black;
+        }
+
+        .stacking {
+            opacity: 0.8;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            const scrollUpdatesDisabled = true;
+            await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 100, scrollUpdatesDisabled);
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="filler"></div>
+        <div class="stacking">
+            <div class="inner-scroller">
+                <div class="wide"></div>
+                <div class="absolute"></div>
+            </div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,72 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            border: 1px solid black;
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 100px;
+            border: 1px solid black;
+        }
+        
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script src=""
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        async function doTest()
+        {
+            const scrollUpdatesDisabled = true;
+            await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 100, scrollUpdatesDisabled);
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="filler"></div>
+        <div class="inner-scroller">
+            <div class="wide"></div>
+            <div class="absolute"></div>
+        </div>
+        <div class="filler"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll-expected.txt	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,44 @@
+
+(Frame scrolling node
+  (scrollable area size 785 600)
+  (contents size 785 1021)
+  (scrollable area parameters
+    (horizontal scroll elasticity 2)
+    (vertical scroll elasticity 2)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0)
+    (allows vertical scrolling 1))
+  (layout viewport at (0,0) size 785x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,421))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scrollable area size 295 295)
+      (contents size 295 1112)
+      (scrollable area parameters
+        (horizontal scroll elasticity 0)
+        (vertical scroll elasticity 0)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (allows vertical scrolling 1))
+      (children 1
+        (Overflow scrolling node
+          (scrollable area size 283 85)
+          (contents size 566 85)
+          (scrollable area parameters
+            (horizontal scroll elasticity 0)
+            (vertical scroll elasticity 1)
+            (horizontal scrollbar mode 0)
+            (vertical scrollbar mode 0)
+            (allows horizontal scrolling 1))
+        )
+      )
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+  )
+)
+
+

Added: trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html (0 => 271651)


--- trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html	                        (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html	2021-01-20 18:34:10 UTC (rev 271651)
@@ -0,0 +1,66 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+
+        .scroller {
+            position: absolute;
+            height: 300px;
+            width: 300px;
+            border: 2px solid gray;
+            padding: 5px;
+            overflow: scroll;
+        }
+        
+        .inner-scroller {
+            border: 1px solid black;
+            overflow-x: scroll;
+            overflow-y: hidden;
+            height: 100px;
+            border: 1px solid black;
+        }
+
+        .filler {
+            height: 500px;
+            width: 10px;
+        }
+
+        .wide {
+            width: 200%;
+            height: 10px;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 50px;
+            height: 200px;
+            width: 200px;
+            background-color: green;
+        }
+    </style>
+    <script>
+	    if (window.testRunner)
+	        testRunner.dumpAsText();
+
+	    window.addEventListener('load', () => {
+	        if (window.internals)
+	            document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
+	    }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="filler"></div>
+        <div class="inner-scroller">
+            <div class="wide"></div>
+            <div class="absolute"></div>
+        </div>
+        <div class="filler"></div>
+    </div>
+<pre id="scrollingTree"></pre>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (271650 => 271651)


--- trunk/Source/WebCore/ChangeLog	2021-01-20 17:44:15 UTC (rev 271650)
+++ trunk/Source/WebCore/ChangeLog	2021-01-20 18:34:10 UTC (rev 271651)
@@ -1,3 +1,33 @@
+2021-01-19  Simon Fraser  <simon.fra...@apple.com>
+
+        REGRESSION (Big Sur): position:absolute elements inside nested overflow:scroll don't track scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=220761
+        <rdar://problem/69075263>
+
+        Reviewed by Antti Koivisto.
+
+        When a position:absolute element is inside nested overflow scroll, and its containing block is the outer
+        scroller, then we failed to make a positioning scrolling tree node for it, so it would fail
+        to track during async scrolling.
+
+        The bug was that RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor() failed
+        to deal with nested scrollers. The correct question to ask when determining if we need a "Moves" node
+        is "is there an overflow scroll layer between this layer and its composited ancestor". Previously,
+        we would just find the enclosing scroller (with the same scrolling scope) and assume we didn't need
+        a node.
+
+        We can also simplify the "Stationary" code path to just ask about scrolling scopes.
+
+        Tests: scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking-2.html
+               scrollingcoordinator/ios/absolute-in-nested-overflow-scroll-intermediate-stacking.html
+               scrollingcoordinator/ios/absolute-in-nested-overflow-scroll.html
+               scrollingcoordinator/scrolling-tree/absolute-in-nested-overflow-scroll.html
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor):
+        (WebCore::isScrolledByOverflowScrollLayer): Deleted.
+        (WebCore::enclosingCompositedScrollingLayer): Deleted.
+
 2021-01-20  Kate Cheney  <katherine_che...@apple.com>
 
         Safari says "Blocked Plug-in" instead showing a PDF

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (271650 => 271651)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-01-20 17:44:15 UTC (rev 271650)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2021-01-20 18:34:10 UTC (rev 271651)
@@ -160,7 +160,7 @@
         // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
         // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
         // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
-        auto canReenableOverlapTesting = [&layer]() {
+        auto canReenableOverlapTesting = [&layer] {
             return layer.isComposited() && RenderLayerCompositor::clipsCompositingDescendants(layer);
         };
         if ((!childState.testingOverlap && !canReenableOverlapTesting()) || layerExtent.knownToBeHaveExtentUncertainty())
@@ -3387,46 +3387,35 @@
     return false;
 }
 
-static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer)
+ScrollPositioningBehavior RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor)
 {
-    return layer.boxScrollingScope() == overflowScrollLayer.contentsScrollingScope();
-}
+    if (!layer.hasCompositedScrollingAncestor())
+        return ScrollPositioningBehavior::None;
 
-static RenderLayer* enclosingCompositedScrollingLayer(const RenderLayer& layer, const RenderLayer& intermediateLayer, bool& sawIntermediateLayer)
-{
-    const auto* ancestorLayer = layer.parent();
-    while (ancestorLayer) {
-        if (ancestorLayer == &intermediateLayer)
-            sawIntermediateLayer = true;
+    auto needsMovesNode = [&] {
+        bool result = false;
+        traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool isContainingBlockChain, bool /* isPaintOrderAncestor */) {
+            if (&ancestorLayer == &compositedAncestor)
+                return AncestorTraversal::Stop;
 
-        if (ancestorLayer->hasCompositedScrollableOverflow())
-            return const_cast<RenderLayer*>(ancestorLayer);
+            if (isContainingBlockChain && ancestorLayer.hasCompositedScrollableOverflow()) {
+                result = true;
+                return AncestorTraversal::Stop;
+            }
 
-        ancestorLayer = ancestorLayer->parent();
-    }
+            return AncestorTraversal::Continue;
+        });
 
-    return nullptr;
-}
+        return result;
+    };
 
-ScrollPositioningBehavior RenderLayerCompositor::layerScrollBehahaviorRelativeToCompositedAncestor(const RenderLayer& layer, const RenderLayer& compositedAncestor)
-{
-    if (!layer.hasCompositedScrollingAncestor())
-        return ScrollPositioningBehavior::None;
+    if (needsMovesNode())
+        return ScrollPositioningBehavior::Moves;
 
-    bool compositedAncestorIsInsideScroller = false;
-    auto* scrollingAncestor = enclosingCompositedScrollingLayer(layer, compositedAncestor, compositedAncestorIsInsideScroller);
-    if (!scrollingAncestor) {
-        ASSERT_NOT_REACHED(); // layer.hasCompositedScrollingAncestor() should guarantee we have one.
-        return ScrollPositioningBehavior::None;
-    }
-    
-    bool ancestorMovedByScroller = &compositedAncestor == scrollingAncestor || (compositedAncestorIsInsideScroller && isScrolledByOverflowScrollLayer(compositedAncestor, *scrollingAncestor));
-    bool layerMovedByScroller = isScrolledByOverflowScrollLayer(layer, *scrollingAncestor);
+    if (layer.boxScrollingScope() != compositedAncestor.contentsScrollingScope())
+        return ScrollPositioningBehavior::Stationary;
 
-    if (ancestorMovedByScroller == layerMovedByScroller)
-        return ScrollPositioningBehavior::None;
-
-    return layerMovedByScroller ? ScrollPositioningBehavior::Moves : ScrollPositioningBehavior::Stationary;
+    return ScrollPositioningBehavior::None;
 }
 
 static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, const RenderLayer&, Vector<ScrollingNodeID>& scrollingNodes)
@@ -4853,7 +4842,7 @@
     for (auto key : m_scrollingNodeToLayerMap.keys())
         nodesToClear.add(key);
     
-    auto clearSynchronousReasonsOnNodes = [&]() {
+    auto clearSynchronousReasonsOnNodes = [&] {
         for (auto nodeID : nodesToClear) {
             // ScrollingCoordinator handles updating synchronous scrolling reasons for the FrameView.
             if (nodeID == rootScrollingNodeID)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to