Title: [258380] trunk
Revision
258380
Author
za...@apple.com
Date
2020-03-12 20:47:55 -0700 (Thu, 12 Mar 2020)

Log Message

RenderTreeNeedsLayoutChecker asserts with imported/w3c/web-platform-tests/css/css-position/position-absolute-crash-chrome-005.html
https://bugs.webkit.org/show_bug.cgi?id=209022
<rdar://problem/60390647>

Reviewed by Simon Fraser.

Source/WebCore:

Fix the case when
1. the block level box is no longer the containing block for its out-of-flow descendants and
2. the new containing block does not get marked dirty because there's a re-layout boundary (overflow: hidden)
between the old and the new containing block.

Test: fast/block/containing-block-for-out-of-flow-becomes-static.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::removePositionedObjectsIfNeeded):
(WebCore::RenderBlock::removePositionedObjects):

LayoutTests:

* TestExpectations:
* fast/block/containing-block-for-out-of-flow-becomes-static-expected.html: Added.
* fast/block/containing-block-for-out-of-flow-becomes-static.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (258379 => 258380)


--- trunk/LayoutTests/ChangeLog	2020-03-13 03:09:44 UTC (rev 258379)
+++ trunk/LayoutTests/ChangeLog	2020-03-13 03:47:55 UTC (rev 258380)
@@ -1,3 +1,15 @@
+2020-03-12  Zalan Bujtas  <za...@apple.com>
+
+        RenderTreeNeedsLayoutChecker asserts with imported/w3c/web-platform-tests/css/css-position/position-absolute-crash-chrome-005.html
+        https://bugs.webkit.org/show_bug.cgi?id=209022
+        <rdar://problem/60390647>
+
+        Reviewed by Simon Fraser.
+
+        * TestExpectations:
+        * fast/block/containing-block-for-out-of-flow-becomes-static-expected.html: Added.
+        * fast/block/containing-block-for-out-of-flow-becomes-static.html: Added.
+
 2020-03-12  Chris Dumez  <cdu...@apple.com>
 
         http/tests/paymentrequest/page-cache-completed-payment-response.https.html is flaky failing.

Modified: trunk/LayoutTests/TestExpectations (258379 => 258380)


--- trunk/LayoutTests/TestExpectations	2020-03-13 03:09:44 UTC (rev 258379)
+++ trunk/LayoutTests/TestExpectations	2020-03-13 03:47:55 UTC (rev 258380)
@@ -3134,7 +3134,6 @@
 
 # wpt css-position failures
 webkit.org/b/203445 [ Debug ] imported/w3c/web-platform-tests/css/css-position/position-absolute-container-dynamic-002.html [ Skip ]
-webkit.org/b/203445 [ Debug ] imported/w3c/web-platform-tests/css/css-position/position-absolute-crash-chrome-005.html [ Skip ]
 webkit.org/b/203447 imported/w3c/web-platform-tests/css/css-position/position-absolute-dynamic-overflow-001.html [ ImageOnlyFailure ]
 webkit.org/b/203447 imported/w3c/web-platform-tests/css/css-position/position-absolute-dynamic-overflow-002.html [ ImageOnlyFailure ]
 webkit.org/b/203448 imported/w3c/web-platform-tests/css/css-position/position-absolute-dynamic-static-position-table-cell.html [ ImageOnlyFailure ]

Added: trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static-expected.html (0 => 258380)


--- trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static-expected.html	2020-03-13 03:47:55 UTC (rev 258380)
@@ -0,0 +1,8 @@
+<style>
+div {
+  width: 500px;
+  height: 200px;
+  background-color: green;
+}
+</style>
+<div>PASS if this text is at the top left corner of the green box.</div>

Added: trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static.html (0 => 258380)


--- trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/containing-block-for-out-of-flow-becomes-static.html	2020-03-13 03:47:55 UTC (rev 258380)
@@ -0,0 +1,29 @@
+<style>
+.boundary {
+  overflow: hidden;
+  width: 500px;
+  height: 200px;
+}
+
+#relpos {
+  position: relative;
+  border: 100px solid green;
+}
+
+#abspos {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+}
+</style>
+<div style="position: relative;">
+  <div class=boundary>
+    <div id=relpos>
+      <div id=abspos>PASS if this text is at the top left corner of the green box.</div>
+    </div>
+  </div>
+</div>
+<script>
+document.body.offsetHeight;
+relpos.style.position="static";
+</script>

Modified: trunk/LayoutTests/fast/repaint/absolute-position-change-containing-block-expected.txt (258379 => 258380)


--- trunk/LayoutTests/fast/repaint/absolute-position-change-containing-block-expected.txt	2020-03-13 03:09:44 UTC (rev 258379)
+++ trunk/LayoutTests/fast/repaint/absolute-position-change-containing-block-expected.txt	2020-03-13 03:47:55 UTC (rev 258380)
@@ -6,6 +6,7 @@
   (rect 16 5008 100 100)
   (rect 16 5008 100 100)
   (rect 8 8 100 100)
+  (rect 0 0 800 600)
   (rect 108 5100 100 100)
   (rect 100 100 100 100)
 )

Modified: trunk/Source/WebCore/ChangeLog (258379 => 258380)


--- trunk/Source/WebCore/ChangeLog	2020-03-13 03:09:44 UTC (rev 258379)
+++ trunk/Source/WebCore/ChangeLog	2020-03-13 03:47:55 UTC (rev 258380)
@@ -1,3 +1,22 @@
+2020-03-12  Zalan Bujtas  <za...@apple.com>
+
+        RenderTreeNeedsLayoutChecker asserts with imported/w3c/web-platform-tests/css/css-position/position-absolute-crash-chrome-005.html
+        https://bugs.webkit.org/show_bug.cgi?id=209022
+        <rdar://problem/60390647>
+
+        Reviewed by Simon Fraser.
+
+        Fix the case when
+        1. the block level box is no longer the containing block for its out-of-flow descendants and
+        2. the new containing block does not get marked dirty because there's a re-layout boundary (overflow: hidden)
+        between the old and the new containing block.
+
+        Test: fast/block/containing-block-for-out-of-flow-becomes-static.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::removePositionedObjectsIfNeeded):
+        (WebCore::RenderBlock::removePositionedObjects):
+
 2020-03-12  Ryosuke Niwa  <rn...@webkit.org>
 
         Crash in TextManipulationController::replace

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (258379 => 258380)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-03-13 03:09:44 UTC (rev 258379)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-03-13 03:47:55 UTC (rev 258380)
@@ -376,20 +376,14 @@
     if (oldStyle.position() == newStyle.position() && hadTransform == willHaveTransform)
         return;
 
-    // We are no longer the containing block for fixed descendants.
-    if (hadTransform && !willHaveTransform) {
-        // Our positioned descendants will be inserted into a new containing block's positioned objects list during the next layout.
+    // We are no longer the containing block for out-of-flow descendants.
+    bool outOfFlowDescendantsHaveNewContainingBlock = (hadTransform && !willHaveTransform) || (newStyle.position() == PositionType::Static && !willHaveTransform);
+    if (outOfFlowDescendantsHaveNewContainingBlock) {
+        // Our out-of-flow descendants will be inserted into a new containing block's positioned objects list during the next layout.
         removePositionedObjects(nullptr, NewContainingBlock);
         return;
     }
 
-    // We are no longer the containing block for absolute positioned descendants.
-    if (newStyle.position() == PositionType::Static && !willHaveTransform) {
-        // Our positioned descendants will be inserted into a new containing block's positioned objects list during the next layout.
-        removePositionedObjects(nullptr, NewContainingBlock);
-        return;
-    }
-
     // We are a new containing block.
     if (oldStyle.position() == PositionType::Static && !hadTransform) {
         // Remove our absolutely positioned descendants from their current containing block.
@@ -1782,12 +1776,24 @@
         if (containingBlockState == NewContainingBlock)
             renderer->setChildNeedsLayout(MarkOnlyThis);
         // It is the parent block's job to add positioned children to positioned objects list of its containing block.
-        // Dirty the parent to ensure this happens.
+        // Dirty the parent to ensure this happens. We also need to make sure the new containing block is dirty as well so
+        // that it gets to these new positioned objects.
         auto* parent = renderer->parent();
-        while (parent && !parent->isRenderBlock())
+        while (parent && !is<RenderBlock>(parent))
             parent = parent->parent();
         if (parent)
             parent->setChildNeedsLayout();
+
+        if (renderer->isFixedPositioned())
+            view().setNeedsLayout();
+        else if (auto* newContainingBlock = containingBlock()) {
+            // During style change, at this point the renderer's containing block is still "this" renderer, and "this" renderer is still positioned.
+            // FIXME: During subtree moving, this is mostly invalid but either the subtree is detached (we don't even get here) or renderers
+            // are already marked dirty.
+            for (; newContainingBlock && !newContainingBlock->canContainAbsolutelyPositionedObjects(); newContainingBlock = newContainingBlock->containingBlock()) { }
+            if (newContainingBlock)
+                newContainingBlock->setNeedsLayout();
+        }
     }
     for (auto* renderer : renderersToRemove)
         removePositionedObject(*renderer);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to