Diff
Modified: trunk/LayoutTests/ChangeLog (246366 => 246367)
--- trunk/LayoutTests/ChangeLog 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/LayoutTests/ChangeLog 2019-06-12 18:27:35 UTC (rev 246367)
@@ -1,3 +1,22 @@
+2019-06-12 Antti Koivisto <[email protected]>
+
+ (Async scrolling) Handle 'position:fixed' inside 'position:sticky' correctly.
+ https://bugs.webkit.org/show_bug.cgi?id=198788
+ <rdar://problem/51589759>
+
+ Reviewed by Simon Fraser.
+
+ * scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-frame-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-frame.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-stacking-context-expected.html: Added.
+ * scrollingcoordinator/ios/fixed-inside-sticky-stacking-context.html: Added.
+
2019-06-12 Youenn Fablet <[email protected]>
Update WPT service workers test up to 0df7c68
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed-expected.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed-expected.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,71 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .fixed-outer {
+ position: fixed;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ await UIHelper.ensurePresentationUpdate();
+ document.querySelector('.scroller').scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="fixed-outer">
+ <div class="scroller">
+ <div class="container">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,70 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .fixed-outer {
+ position: fixed;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="fixed-outer">
+ <div class="scroller">
+ <div class="container">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame-expected.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame-expected.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,70 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ await UIHelper.ensurePresentationUpdate();
+ window.scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-frame.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,68 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2-expected.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2-expected.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,71 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ will-change: transform;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ await UIHelper.ensurePresentationUpdate();
+ document.querySelector('.scroller').scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,70 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ will-change: transform;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-expected.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-expected.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,71 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ await UIHelper.ensurePresentationUpdate();
+ document.querySelector('.scroller').scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,69 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context-expected.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context-expected.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context-expected.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,71 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ await UIHelper.ensurePresentationUpdate();
+ document.querySelector('.scroller').scrollTo(0, 200);
+ await UIHelper.ensurePresentationUpdate();
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context.html (0 => 246367)
--- trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/fixed-inside-sticky-stacking-context.html 2019-06-12 18:27:35 UTC (rev 246367)
@@ -0,0 +1,70 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true internal:AsyncOverflowScrollingEnabled=true internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <style>
+ .scroller {
+ margin: 10px;
+ height: 300px;
+ width: 300px;
+ border: 1px solid black;
+ overflow: scroll;
+ z-index: 0;
+ position: relative;
+ }
+
+ .sticky {
+ position: -webkit-sticky;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ }
+
+ .fixed {
+ position: fixed;
+ top: 100px;
+ left: 100px;
+ width: 50px;
+ height: 50px;
+ background-color: blue;
+ }
+
+ .container {
+ margin: 40px;
+ border: 2px solid red;
+ height: 5000px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ async function doTest()
+ {
+ if (!window.testRunner)
+ return;
+
+ if (!testRunner.runUIScript)
+ return;
+
+ const scrollUpdatesDisabled = true;
+ await UIHelper.immediateScrollElementAtContentPointToOffset(50, 50, 0, 200, scrollUpdatesDisabled);
+ testRunner.notifyDone();
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="container">
+ <div class="sticky">
+ <div class="fixed">
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (246366 => 246367)
--- trunk/Source/WebCore/ChangeLog 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/Source/WebCore/ChangeLog 2019-06-12 18:27:35 UTC (rev 246367)
@@ -1,3 +1,41 @@
+2019-06-12 Antti Koivisto <[email protected]>
+
+ (Async scrolling) Handle 'position:fixed' inside 'position:sticky' correctly.
+ https://bugs.webkit.org/show_bug.cgi?id=198788
+ <rdar://problem/51589759>
+
+ Reviewed by Simon Fraser.
+
+ Handle 'position:fixed' inside 'position:sticky' correctly.
+
+ Also fix nested 'position:fixed' in case where there is an overflow scroller between them.
+
+ Tests: scrollingcoordinator/ios/fixed-inside-overflow-inside-fixed.html
+ scrollingcoordinator/ios/fixed-inside-sticky-frame.html
+ scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context-2.html
+ scrollingcoordinator/ios/fixed-inside-sticky-no-stacking-context.html
+ scrollingcoordinator/ios/fixed-inside-sticky-stacking-context.html
+
+ * page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
+ (WebCore::ScrollingTreeFixedNode::applyLayerPositions):
+
+ Take offsets from sticky nodes into account.
+
+ * page/scrolling/cocoa/ScrollingTreeStickyNode.h:
+ (WebCore::ScrollingTreeStickyNode::layer):
+ * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
+ (WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
+
+ Factor into a function.
+
+ (WebCore::ScrollingTreeStickyNode::applyLayerPositions):
+ (WebCore::ScrollingTreeStickyNode::scrollDeltaSinceLastCommit const):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::isViewportConstrainedFixedOrStickyLayer const):
+
+ We need to generate a scrolling tree node for position:fixed in nested case if there is an overflow scroller
+ between the layers.
+
2019-06-12 Truitt Savell <[email protected]>
Unreviewed, rolling out r246350.
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm (246366 => 246367)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm 2019-06-12 18:27:35 UTC (rev 246367)
@@ -34,6 +34,7 @@
#import "ScrollingTreeFrameScrollingNode.h"
#import "ScrollingTreeOverflowScrollingNode.h"
#import "ScrollingTreePositionedNode.h"
+#import "ScrollingTreeStickyNode.h"
#import "WebCoreCALayerExtras.h"
#import <wtf/text/TextStream.h>
@@ -70,13 +71,8 @@
{
auto computeLayerPosition = [&] {
FloatSize overflowScrollDelta;
+ ScrollingTreeStickyNode* lastStickyNode = nullptr;
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
- if (is<ScrollingTreePositionedNode>(*ancestor)) {
- auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
- if (positioningAncestor.layer() != m_layer)
- overflowScrollDelta -= positioningAncestor.scrollDeltaSinceLastCommit();
- }
-
if (is<ScrollingTreeFrameScrollingNode>(*ancestor)) {
// Fixed nodes are positioned relative to the containing frame scrolling node.
// We bail out after finding one.
@@ -88,7 +84,31 @@
// To keep the layer still during async scrolling we adjust by how much the position has changed since layout.
auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*ancestor);
overflowScrollDelta -= overflowNode.scrollDeltaSinceLastCommit();
+ continue;
}
+
+ if (is<ScrollingTreePositionedNode>(*ancestor)) {
+ auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
+ // See if sticky node already handled this positioning node.
+ // FIXME: Include positioning node information to sticky/fixed node to avoid these tests.
+ if (lastStickyNode && lastStickyNode->layer() == positioningAncestor.layer())
+ continue;
+ if (positioningAncestor.layer() != m_layer)
+ overflowScrollDelta -= positioningAncestor.scrollDeltaSinceLastCommit();
+ continue;
+ }
+
+ if (is<ScrollingTreeStickyNode>(*ancestor)) {
+ auto& stickyNode = downcast<ScrollingTreeStickyNode>(*ancestor);
+ overflowScrollDelta += stickyNode.scrollDeltaSinceLastCommit();
+ lastStickyNode = &stickyNode;
+ continue;
+ }
+
+ if (is<ScrollingTreeFixedNode>(*ancestor)) {
+ // The ancestor fixed node has already applied the needed corrections to say put.
+ return m_constraints.layerPositionAtLastLayout() - overflowScrollDelta;
+ }
}
ASSERT_NOT_REACHED();
return FloatPoint();
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h (246366 => 246367)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h 2019-06-12 18:27:35 UTC (rev 246367)
@@ -41,6 +41,10 @@
virtual ~ScrollingTreeStickyNode();
+ FloatSize scrollDeltaSinceLastCommit() const;
+
+ CALayer *layer() { return m_layer.get(); }
+
private:
ScrollingTreeStickyNode(ScrollingTree&, ScrollingNodeID);
@@ -47,6 +51,8 @@
void commitStateBeforeChildren(const ScrollingStateNode&) override;
void applyLayerPositions() override;
+ FloatPoint computeLayerPosition() const;
+
void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
StickyPositionViewportConstraints m_constraints;
Modified: trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm (246366 => 246367)
--- trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm 2019-06-12 18:27:35 UTC (rev 246367)
@@ -66,7 +66,7 @@
m_constraints = stickyStateNode.viewportConstraints();
}
-void ScrollingTreeStickyNode::applyLayerPositions()
+FloatPoint ScrollingTreeStickyNode::computeLayerPosition() const
{
auto computeLayerPositionForScrollingNode = [&](ScrollingTreeNode& scrollingNode) {
FloatRect constrainingRect;
@@ -80,41 +80,42 @@
return m_constraints.layerPositionForConstrainingRect(constrainingRect);
};
- auto computeLayerPosition = [&] {
- for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
- if (is<ScrollingTreePositionedNode>(*ancestor)) {
- auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
+ for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
+ if (is<ScrollingTreePositionedNode>(*ancestor)) {
+ auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
- // FIXME: Do we need to do anything for ScrollPositioningBehavior::Stationary?
- if (positioningAncestor.scrollPositioningBehavior() == ScrollPositioningBehavior::Moves) {
- if (positioningAncestor.relatedOverflowScrollingNodes().isEmpty())
- break;
- auto overflowNode = scrollingTree().nodeForID(positioningAncestor.relatedOverflowScrollingNodes()[0]);
- if (!overflowNode)
- break;
+ // FIXME: Do we need to do anything for ScrollPositioningBehavior::Stationary?
+ if (positioningAncestor.scrollPositioningBehavior() == ScrollPositioningBehavior::Moves) {
+ if (positioningAncestor.relatedOverflowScrollingNodes().isEmpty())
+ break;
+ auto overflowNode = scrollingTree().nodeForID(positioningAncestor.relatedOverflowScrollingNodes()[0]);
+ if (!overflowNode)
+ break;
- auto position = computeLayerPositionForScrollingNode(*overflowNode);
+ auto position = computeLayerPositionForScrollingNode(*overflowNode);
- if (positioningAncestor.layer() == m_layer) {
- // We'll also do the adjustment the positioning node would do.
- position -= positioningAncestor.scrollDeltaSinceLastCommit();
- }
-
- return position;
+ if (positioningAncestor.layer() == m_layer) {
+ // We'll also do the adjustment the positioning node would do.
+ position -= positioningAncestor.scrollDeltaSinceLastCommit();
}
- }
- if (is<ScrollingTreeScrollingNode>(*ancestor))
- return computeLayerPositionForScrollingNode(*ancestor);
- if (is<ScrollingTreeFixedNode>(*ancestor) || is<ScrollingTreeStickyNode>(*ancestor)) {
- // FIXME: Do we need scrolling tree nodes at all for nested cases?
- return m_constraints.layerPositionAtLastLayout();
+ return position;
}
}
- ASSERT_NOT_REACHED();
- return m_constraints.layerPositionAtLastLayout();
- };
+ if (is<ScrollingTreeScrollingNode>(*ancestor))
+ return computeLayerPositionForScrollingNode(*ancestor);
+ if (is<ScrollingTreeFixedNode>(*ancestor) || is<ScrollingTreeStickyNode>(*ancestor)) {
+ // FIXME: Do we need scrolling tree nodes at all for nested cases?
+ return m_constraints.layerPositionAtLastLayout();
+ }
+ }
+ ASSERT_NOT_REACHED();
+ return m_constraints.layerPositionAtLastLayout();
+}
+
+void ScrollingTreeStickyNode::applyLayerPositions()
+{
auto layerPosition = computeLayerPosition();
LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition);
@@ -122,6 +123,12 @@
[m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()];
}
+FloatSize ScrollingTreeStickyNode::scrollDeltaSinceLastCommit() const
+{
+ auto layerPosition = computeLayerPosition();
+ return layerPosition - m_constraints.layerPositionAtLastLayout();
+}
+
void ScrollingTreeStickyNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
{
ts << "sticky node";
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (246366 => 246367)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2019-06-12 18:17:26 UTC (rev 246366)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2019-06-12 18:27:35 UTC (rev 246367)
@@ -3052,8 +3052,10 @@
return false;
// FIXME: Handle fixed inside of a transform, which should not behave as fixed.
- for (auto* stackingContext = layer.stackingContext(); stackingContext; stackingContext = stackingContext->stackingContext()) {
- if (stackingContext->isComposited() && stackingContext->renderer().isFixedPositioned())
+ for (auto* ancestor = layer.parent(); ancestor; ancestor = ancestor->parent()) {
+ if (ancestor->hasCompositedScrollableOverflow())
+ return true;
+ if (ancestor->isStackingContext() && ancestor->isComposited() && ancestor->renderer().isFixedPositioned())
return false;
}