Title: [210669] trunk
Revision
210669
Author
jfernan...@igalia.com
Date
2017-01-12 10:41:28 -0800 (Thu, 12 Jan 2017)

Log Message

[css-grid] Make the grid sizing data persistent through layouts
https://bugs.webkit.org/show_bug.cgi?id=166883

Reviewed by Darin Adler and Manuel Rego Casasnovas.

Source/WebCore:

We want to keep the grid sizing data structures through different
layouts. This will allow to optimize some operations, reusing
these data while still valid. Additionally, operations like
determining the baseline position when the grid container is under
an inline formatting context need these data once the grid has
been laid out.

This patch controls the sizing data validity and make the data
structures persistent after layout.

Tests: fast/css-grid-layout/grid-add-item-with-positioned-items.html
       fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html
       fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html
       fast/css-grid-layout/grid-item-change-order-auto-flow.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::styleDidChange): Evaluate if the style change made the grid data invalid.
(WebCore::RenderBox::updateGridPositionAfterStyleChange): Evaluate if the style change made the grid data invalid.
* rendering/RenderBox.h:
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::Grid::setNeedsItemsPlacement): The grid must execute the items placement logic before continue processing the layout.
(WebCore::RenderGrid::addChild): Mark the grid data as dirty.
(WebCore::RenderGrid::removeChild): Mark the grid data as dirty.
(WebCore::RenderGrid::styleDidChange): Evaluate grid data validity.
(WebCore::RenderGrid::explicitGridDidResize): Mark the grid data as dirty.
(WebCore::RenderGrid::namedGridLinesDefinitionDidChange): Mark the grid data as dirty.
(WebCore::RenderGrid::layoutBlock): We don't need to clear the grid data anymore.
(WebCore::RenderGrid::dirtyGrid): Clearing the grid data and mark is as needing to execute the items placement logic.
(WebCore::RenderGrid::trackSizesForComputedStyle): Assert we don't need to perform the items placement logic.
(WebCore::RenderGrid::paintChildren): Assert we don't need to perform the items placement logic.
* rendering/RenderGrid.h:
(WebCore::RenderGrid::clear): Deleted.

LayoutTests:

The tests added are now needed to verify we perform correctly the
data validation after certain style changes.

* fast/css-grid-layout/grid-add-item-with-positioned-items-expected.txt: Added.
* fast/css-grid-layout/grid-add-item-with-positioned-items.html: Added.
* fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item-expected.txt: Added.
* fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html: Added.
* fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child-expected.txt: Added.
* fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html: Added.
* fast/css-grid-layout/grid-item-change-order-auto-flow-expected.txt: Added.
* fast/css-grid-layout/grid-item-change-order-auto-flow.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (210668 => 210669)


--- trunk/LayoutTests/ChangeLog	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/LayoutTests/ChangeLog	2017-01-12 18:41:28 UTC (rev 210669)
@@ -1,3 +1,22 @@
+2017-01-12  Javier Fernandez  <jfernan...@igalia.com>
+
+        [css-grid] Make the grid sizing data persistent through layouts
+        https://bugs.webkit.org/show_bug.cgi?id=166883
+
+        Reviewed by Darin Adler and Manuel Rego Casasnovas.
+
+        The tests added are now needed to verify we perform correctly the
+        data validation after certain style changes.
+
+        * fast/css-grid-layout/grid-add-item-with-positioned-items-expected.txt: Added.
+        * fast/css-grid-layout/grid-add-item-with-positioned-items.html: Added.
+        * fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item-expected.txt: Added.
+        * fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html: Added.
+        * fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child-expected.txt: Added.
+        * fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html: Added.
+        * fast/css-grid-layout/grid-item-change-order-auto-flow-expected.txt: Added.
+        * fast/css-grid-layout/grid-item-change-order-auto-flow.html: Added.
+
 2017-01-12  Chris Dumez  <cdu...@apple.com>
 
         [iOS] Implement support for KeyboardEvent.code

Added: trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items-expected.txt (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items-expected.txt	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,3 @@
+This tests checks that adding grid items when some of them are positioned does not crash.
+
+

Added: trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items.html (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-add-item-with-positioned-items.html	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #grid {
+        display: grid;
+        grid-auto-flow: stack;
+    }
+    .absolute {
+        position: absolute;
+    }
+</style>
+<script type="text/_javascript_">
+    if (window.testRunner)
+        testRunner.dumpAsText();
+</script>
+</head>
+<body>
+    <p>This tests checks that adding grid items when some of them are positioned does not crash.</p>
+    <div id="grid">
+        <div></div>
+        <div class="absolute"></div>
+    </div>
+    <script>
+        var grid = document.getElementById("grid");
+        grid.offsetTop;
+        var newItem1 = document.createElement("div");
+        grid.appendChild(newItem1);
+        var newItem2 = document.createElement("div");
+        newItem2.className = "absolute";
+        grid.appendChild(newItem2);
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item-expected.txt (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item-expected.txt	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,3 @@
+This test checks that adding a positioned block grid item after an inline grid item (which inserts it inside the existing anonymous block wrapping the inline item) does not crash on debug.
+
+test 

Added: trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+    #grid {
+        display: grid;
+        grid-auto-flow: stack;
+    }
+    embed {
+        position: absolute;
+    }
+</style>
+<script type="text/_javascript_">
+    if (window.testRunner)
+        testRunner.dumpAsText();
+</script>
+</head>
+<body>
+    <p>This test checks that adding a positioned block grid item after an inline grid item (which inserts it inside the
+    existing anonymous block wrapping the inline item) does not crash on debug.</p>
+    <div id="grid">
+        test
+    </div>
+    <script>
+        var grid = document.getElementById("grid");
+        grid.offsetTop;
+        var embed = document.createElement("embed");
+        embed.setAttribute("type", "image/png");
+        grid.appendChild(embed);
+    </script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child-expected.txt (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child-expected.txt	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,7 @@
+This test checks that grid-template-{rows|columns} dynamic updates recomputes the positions of automatically placed grid items.
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS

Added: trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<link href="" rel="stylesheet">
+<script src=""
+<style>
+.grid {
+    grid-auto-flow: row dense;
+    grid-auto-rows: 5px;
+    grid-auto-columns: 5px;
+}
+#firstGridItem {
+    grid-row: auto;
+    grid-column: 1;
+}
+
+#secondGridItem {
+    grid-row: 1;
+    grid-column: auto;
+}
+
+#thirdGridItem {
+    grid-row: auto;
+    grid-column: auto;
+}
+</style>
+<script>
+function testGridDefinitions(gridTemplateRows, gridTemplateColumns, gridTemplateAreas, firstGridItemData, secondGridItemData, thirdGridItemData)
+{
+    var gridElement = document.getElementsByClassName("grid")[0];
+    gridElement.style.gridTemplateRows = gridTemplateRows;
+    gridElement.style.gridTemplateColumns = gridTemplateColumns;
+    gridElement.style.gridTemplateAreas = gridTemplateAreas;
+
+    var firstGridItem = document.getElementById("firstGridItem");
+    firstGridItem.setAttribute("data-expected-width", firstGridItemData.width);
+    firstGridItem.setAttribute("data-expected-height", firstGridItemData.height);
+    firstGridItem.setAttribute("data-offset-x", firstGridItemData.x);
+    firstGridItem.setAttribute("data-offset-y", firstGridItemData.y);
+
+    var secondGridItem = document.getElementById("secondGridItem");
+    secondGridItem.setAttribute("data-expected-width", secondGridItemData.width);
+    secondGridItem.setAttribute("data-expected-height", secondGridItemData.height);
+    secondGridItem.setAttribute("data-offset-x", secondGridItemData.x);
+    secondGridItem.setAttribute("data-offset-y", secondGridItemData.y);
+
+    var thirdGridItem = document.getElementById("thirdGridItem");
+    thirdGridItem.setAttribute("data-expected-width", thirdGridItemData.width);
+    thirdGridItem.setAttribute("data-expected-height", thirdGridItemData.height);
+    thirdGridItem.setAttribute("data-offset-x", thirdGridItemData.x);
+    thirdGridItem.setAttribute("data-offset-y", thirdGridItemData.y);
+
+    checkLayout(".grid");
+}
+
+function testChangingGridDefinitions()
+{
+    testGridDefinitions('10px 20px', '10px', '', { 'width': '10', 'height': '20', 'x': '0', 'y': '10' }, { 'width': '10', 'height': '10', 'x': '0', 'y': '0' }, { 'width': '10', 'height': '5', 'x': '0', 'y': '30' });
+    testGridDefinitions('10px', '10px', '"a"', { 'width': '10', 'height': '5', 'x': '0', 'y': '10' }, { 'width': '10', 'height': '10', 'x': '0', 'y': '0' }, { 'width': '10', 'height': '5', 'x': '0', 'y': '15' });
+    testGridDefinitions('10px', '10px', '"a ."', { 'width': '10', 'height': '5', 'x': '0', 'y': '10' }, { 'width': '10', 'height': '10', 'x': '0', 'y': '0' }, { 'width': '5', 'height': '10', 'x': '10', 'y': '0' });
+    testGridDefinitions('50px', '30px 40px', '', { 'width': '30', 'height': '5', 'x': '0', 'y': '50' }, { 'width': '30', 'height': '50', 'x': '0', 'y': '0' }, { 'width': '40', 'height': '50', 'x': '30', 'y': '0' });
+    testGridDefinitions('50px', '60px', '', { 'width': '60', 'height': '5', 'x': '0', 'y': '50' }, { 'width': '60', 'height': '50', 'x': '0', 'y': '0' }, { 'width': '60', 'height': '5', 'x': '0', 'y': '55' });
+    testGridDefinitions('50px 100px 150px', '60px', '', { 'width': '60', 'height': '100', 'x': '0', 'y': '50' }, { 'width': '60', 'height': '50', 'x': '0', 'y': '0' }, { 'width': '60', 'height': '150', 'x': '0', 'y': '150' });
+}
+
+window.addEventListener("load", testChangingGridDefinitions, false);
+</script>
+<body>
+<div>This test checks that grid-template-{rows|columns} dynamic updates recomputes the positions of automatically placed grid items.</div>
+
+<div style="position: relative">
+    <div class="grid">
+        <div class="sizedToGridArea" id="firstGridItem"></div>
+        <div class="sizedToGridArea" id="secondGridItem"></div>
+        <div class="sizedToGridArea" id="thirdGridItem"></div>
+    </div>
+</div>
+
+</body>
+</html>

Added: trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow-expected.txt (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow-expected.txt	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,5 @@
+This test checks that grid items' 'order' dynamic updates recomputes the positions of automatically placed grid items.
+PASS
+PASS
+PASS
+PASS

Added: trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow.html (0 => 210669)


--- trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow.html	2017-01-12 18:41:28 UTC (rev 210669)
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<link href="" rel="stylesheet">
+<script src=""
+<style>
+.grid {
+    grid-auto-flow: row;
+    grid-template-rows: 50px 100px;
+    grid-template-columns: 40px;
+}
+
+#firstGridItem {
+    grid-row: auto;
+    grid-column: 1;
+}
+
+#secondGridItem {
+    grid-row: 1;
+    grid-column: auto;
+}
+
+#thirdGridItem {
+    grid-row: auto;
+    grid-column: auto;
+}
+</style>
+<script>
+function testGridItemsOrder(firstGridItemData, secondGridItemData, thirdGridItemData)
+{
+    var firstGridItem = document.getElementById("firstGridItem");
+    firstGridItem.style.order = firstGridItemData.order;
+    firstGridItem.setAttribute("data-expected-width", firstGridItemData.width);
+    firstGridItem.setAttribute("data-expected-height", firstGridItemData.height);
+    firstGridItem.setAttribute("data-offset-x", firstGridItemData.x);
+    firstGridItem.setAttribute("data-offset-y", firstGridItemData.y);
+
+    var secondGridItem = document.getElementById("secondGridItem");
+    secondGridItem.style.order = secondGridItemData.order;
+    secondGridItem.setAttribute("data-expected-width", secondGridItemData.width);
+    secondGridItem.setAttribute("data-expected-height", secondGridItemData.height);
+    secondGridItem.setAttribute("data-offset-x", secondGridItemData.x);
+    secondGridItem.setAttribute("data-offset-y", secondGridItemData.y);
+
+    var thirdGridItem = document.getElementById("thirdGridItem");
+    thirdGridItem.style.order = thirdGridItemData.order;
+    thirdGridItem.setAttribute("data-expected-width", thirdGridItemData.width);
+    thirdGridItem.setAttribute("data-expected-height", thirdGridItemData.height);
+    thirdGridItem.setAttribute("data-offset-x", thirdGridItemData.x);
+    thirdGridItem.setAttribute("data-offset-y", thirdGridItemData.y);
+
+    checkLayout(".grid");
+}
+
+function testChangingGridItemsOrder()
+{
+    testGridItemsOrder({ 'order': '0', 'width': '40', 'height': '100', 'x': '0', 'y': '50' }, { 'order': '0', 'width': '40', 'height': '50', 'x': '0', 'y': '0' }, { 'order': '0', 'width': '40', 'height': '0', 'x': '0', 'y': '150' });
+    testGridItemsOrder({ 'order': '0', 'width': '40', 'height': '100', 'x': '0', 'y': '50' }, { 'order': '-1', 'width': '40', 'height': '50', 'x': '0', 'y': '0' }, { 'order': '0', 'width': '40', 'height': '0', 'x': '0', 'y': '150' });
+    testGridItemsOrder({ 'order': '1', 'width': '40', 'height': '0', 'x': '0', 'y': '150' }, { 'order': '-1', 'width': '40', 'height': '50', 'x': '0', 'y': '0' }, { 'order': '0', 'width': '40', 'height': '100', 'x': '0', 'y': '50' });
+    testGridItemsOrder({ 'order': '1', 'width': '40', 'height': '100', 'x': '0', 'y': '50' }, { 'order': '-1', 'width': '40', 'height': '50', 'x': '0', 'y': '0' }, { 'order': '10', 'width': '40', 'height': '0', 'x': '0', 'y': '150' });
+}
+
+window.addEventListener("load", testChangingGridItemsOrder, false);
+</script>
+<body>
+<div>This test checks that grid items' 'order' dynamic updates recomputes the positions of automatically placed grid items.</div>
+
+<div style="position: relative">
+    <div class="grid">
+        <div class="sizedToGridArea" id="firstGridItem"></div>
+        <div class="sizedToGridArea" id="secondGridItem"></div>
+        <div class="sizedToGridArea" id="thirdGridItem"></div>
+    </div>
+</div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (210668 => 210669)


--- trunk/Source/WebCore/ChangeLog	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/Source/WebCore/ChangeLog	2017-01-12 18:41:28 UTC (rev 210669)
@@ -1,3 +1,43 @@
+2017-01-12  Javier Fernandez  <jfernan...@igalia.com>
+
+        [css-grid] Make the grid sizing data persistent through layouts
+        https://bugs.webkit.org/show_bug.cgi?id=166883
+
+        Reviewed by Darin Adler and Manuel Rego Casasnovas.
+
+        We want to keep the grid sizing data structures through different
+        layouts. This will allow to optimize some operations, reusing
+        these data while still valid. Additionally, operations like
+        determining the baseline position when the grid container is under
+        an inline formatting context need these data once the grid has
+        been laid out.
+
+        This patch controls the sizing data validity and make the data
+        structures persistent after layout.
+
+        Tests: fast/css-grid-layout/grid-add-item-with-positioned-items.html
+               fast/css-grid-layout/grid-add-positioned-block-item-after-inline-item.html
+               fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child.html
+               fast/css-grid-layout/grid-item-change-order-auto-flow.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::styleDidChange): Evaluate if the style change made the grid data invalid.
+        (WebCore::RenderBox::updateGridPositionAfterStyleChange): Evaluate if the style change made the grid data invalid.
+        * rendering/RenderBox.h:
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::Grid::setNeedsItemsPlacement): The grid must execute the items placement logic before continue processing the layout.
+        (WebCore::RenderGrid::addChild): Mark the grid data as dirty.
+        (WebCore::RenderGrid::removeChild): Mark the grid data as dirty.
+        (WebCore::RenderGrid::styleDidChange): Evaluate grid data validity.
+        (WebCore::RenderGrid::explicitGridDidResize): Mark the grid data as dirty.
+        (WebCore::RenderGrid::namedGridLinesDefinitionDidChange): Mark the grid data as dirty.
+        (WebCore::RenderGrid::layoutBlock): We don't need to clear the grid data anymore.
+        (WebCore::RenderGrid::dirtyGrid): Clearing the grid data and mark is as needing to execute the items placement logic.
+        (WebCore::RenderGrid::trackSizesForComputedStyle): Assert we don't need to perform the items placement logic.
+        (WebCore::RenderGrid::paintChildren): Assert we don't need to perform the items placement logic.
+        * rendering/RenderGrid.h:
+        (WebCore::RenderGrid::clear): Deleted.
+
 2017-01-12  Chris Dumez  <cdu...@apple.com>
 
         [iOS] Implement support for KeyboardEvent.code

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (210668 => 210669)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2017-01-12 18:41:28 UTC (rev 210669)
@@ -73,6 +73,10 @@
 #include <math.h>
 #include <wtf/StackStats.h>
 
+#if ENABLE(CSS_GRID_LAYOUT)
+#include "RenderGrid.h"
+#endif
+
 #if PLATFORM(IOS)
 #include "Settings.h"
 #endif
@@ -450,6 +454,9 @@
 
     if ((oldStyle && oldStyle->shapeOutside()) || style().shapeOutside())
         updateShapeOutsideInfoAfterStyleChange(style(), oldStyle);
+#if ENABLE(CSS_GRID_LAYOUT)
+    updateGridPositionAfterStyleChange(style(), oldStyle);
+#endif
 }
 
 void RenderBox::willBeRemovedFromTree()
@@ -462,6 +469,34 @@
     RenderBoxModelObject::willBeRemovedFromTree();
 }
     
+#if ENABLE(CSS_GRID_LAYOUT)
+
+void RenderBox::updateGridPositionAfterStyleChange(const RenderStyle& style, const RenderStyle* oldStyle)
+{
+    if (!oldStyle || !is<RenderGrid>(parent()))
+        return;
+
+    if (oldStyle->gridItemColumnStart() == style.gridItemColumnStart()
+        && oldStyle->gridItemColumnEnd() == style.gridItemColumnEnd()
+        && oldStyle->gridItemRowStart() == style.gridItemRowStart()
+        && oldStyle->gridItemRowEnd() == style.gridItemRowEnd()
+        && oldStyle->order() == style.order()
+        && oldStyle->hasOutOfFlowPosition() == style.hasOutOfFlowPosition())
+        return;
+
+    // Positioned items don't participate on the layout of the grid,
+    // so we don't need to mark the grid as dirty if they change positions.
+    if (oldStyle->hasOutOfFlowPosition() && style.hasOutOfFlowPosition())
+        return;
+
+    // It should be possible to not dirty the grid in some cases (like moving an
+    // explicitly placed grid item).
+    // For now, it's more simple to just always recompute the grid.
+    downcast<RenderGrid>(*parent()).dirtyGrid();
+}
+
+#endif
+
 void RenderBox::updateShapeOutsideInfoAfterStyleChange(const RenderStyle& style, const RenderStyle* oldStyle)
 {
     const ShapeValue* shapeOutside = style.shapeOutside();

Modified: trunk/Source/WebCore/rendering/RenderBox.h (210668 => 210669)


--- trunk/Source/WebCore/rendering/RenderBox.h	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2017-01-12 18:41:28 UTC (rev 210669)
@@ -654,6 +654,7 @@
     void updateShapeOutsideInfoAfterStyleChange(const RenderStyle&, const RenderStyle* oldStyle);
 
 #if ENABLE(CSS_GRID_LAYOUT)
+    void updateGridPositionAfterStyleChange(const RenderStyle&, const RenderStyle* oldStyle);
     bool isGridItem() const { return parent() && parent()->isRenderGrid(); }
 #endif
 

Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (210668 => 210669)


--- trunk/Source/WebCore/rendering/RenderGrid.cpp	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp	2017-01-12 18:41:28 UTC (rev 210669)
@@ -152,23 +152,20 @@
 {
     m_needsItemsPlacement = needsItemsPlacement;
 
-    if (needsItemsPlacement)
-        clear();
-}
+    if (!needsItemsPlacement) {
+        m_grid.shrinkToFit();
+        return;
+    }
 
-void RenderGrid::Grid::clear()
-{
     m_grid.resize(0);
     m_gridItemArea.clear();
     m_hasAnyOrthogonalGridItem = false;
     m_smallestRowStart = 0;
     m_smallestColumnStart = 0;
-    // FIXME: clear these once m_grid survives layout. We cannot clear them now because they're
-    // needed after layout.
-    // m_autoRepeatEmptyColumns = nullptr;
-    // m_autoRepeatEmptyRows = nullptr;
-    // m_autoRepeatColumns = 0;
-    // m_autoRepeatRows = 0;
+    m_autoRepeatEmptyColumns = nullptr;
+    m_autoRepeatEmptyRows = nullptr;
+    m_autoRepeatColumns = 0;
+    m_autoRepeatRows = 0;
 }
 
 class GridTrack {
@@ -491,6 +488,24 @@
         && childStyle.resolvedAlignSelf(newStyle, selfAlignmentNormalBehavior).position() != ItemPositionStretch;
 }
 
+void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+    RenderBlock::addChild(newChild, beforeChild);
+
+    // The grid needs to be recomputed as it might contain auto-placed items that
+    // will change their position.
+    dirtyGrid();
+}
+
+void RenderGrid::removeChild(RenderObject& child)
+{
+    RenderBlock::removeChild(child);
+
+    // The grid needs to be recomputed as it might contain auto-placed items that
+    // will change their position.
+    dirtyGrid();
+}
+
 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
 {
     RenderBlock::styleDidChange(diff, oldStyle);
@@ -512,8 +527,28 @@
             }
         }
     }
+
+    if (explicitGridDidResize(*oldStyle) || namedGridLinesDefinitionDidChange(*oldStyle) || oldStyle->gridAutoFlow() != style().gridAutoFlow()
+        || (style().gridAutoRepeatColumns().size() || style().gridAutoRepeatRows().size()))
+        dirtyGrid();
 }
 
+bool RenderGrid::explicitGridDidResize(const RenderStyle& oldStyle) const
+{
+    return oldStyle.gridColumns().size() != style().gridColumns().size()
+        || oldStyle.gridRows().size() != style().gridRows().size()
+        || oldStyle.namedGridAreaColumnCount() != style().namedGridAreaColumnCount()
+        || oldStyle.namedGridAreaRowCount() != style().namedGridAreaRowCount()
+        || oldStyle.gridAutoRepeatColumns().size() != style().gridAutoRepeatColumns().size()
+        || oldStyle.gridAutoRepeatRows().size() != style().gridAutoRepeatRows().size();
+}
+
+bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle& oldStyle) const
+{
+    return oldStyle.namedGridRowLines() != style().namedGridRowLines()
+        || oldStyle.namedGridColumnLines() != style().namedGridColumnLines();
+}
+
 LayoutUnit RenderGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizingData) const
 {
     LayoutUnit logicalHeight;
@@ -651,8 +686,6 @@
 
     layoutPositionedObjects(relayoutChildren || isDocumentElementRenderer());
 
-    clearGrid();
-
     computeOverflow(oldClientAfterEdge);
     statePusher.pop();
 
@@ -1953,8 +1986,11 @@
     return style().isGridAutoFlowDirectionColumn() ? ForRows : ForColumns;
 }
 
-void RenderGrid::clearGrid()
+void RenderGrid::dirtyGrid()
 {
+    if (m_grid.needsItemsPlacement())
+        return;
+
     m_grid.setNeedsItemsPlacement(true);
 }
 
@@ -1969,8 +2005,7 @@
     if (numPositions < 2)
         return tracks;
 
-    // FIXME: enable the ASSERT once m_grid is persistent.
-    // ASSERT(!m_grid.needsItemsPlacement());
+    ASSERT(!m_grid.needsItemsPlacement());
     bool hasCollapsedTracks = m_grid.hasAutoRepeatEmptyTracks(direction);
     LayoutUnit gap = !hasCollapsedTracks ? gridGapForDirection(direction) : LayoutUnit();
     tracks.reserveCapacity(numPositions - 1);
@@ -2803,8 +2838,7 @@
 
 void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect)
 {
-    // FIXME: enable the ASSERT once m_grid is persistent.
-    // ASSERT(!m_grid.needsItemsPlacement());
+    ASSERT(!m_grid.needsItemsPlacement());
     for (RenderBox* child = m_grid.orderIterator().first(); child; child = m_grid.orderIterator().next())
         paintChild(*child, paintInfo, paintOffset, forChild, usePrintRect, PaintAsInlineBlock);
 }

Modified: trunk/Source/WebCore/rendering/RenderGrid.h (210668 => 210669)


--- trunk/Source/WebCore/rendering/RenderGrid.h	2017-01-12 18:34:20 UTC (rev 210668)
+++ trunk/Source/WebCore/rendering/RenderGrid.h	2017-01-12 18:41:28 UTC (rev 210669)
@@ -65,6 +65,7 @@
     bool avoidsFloats() const override { return true; }
     bool canDropAnonymousBlockChild() const override { return false; }
 
+    void dirtyGrid();
     Vector<LayoutUnit> trackSizesForComputedStyle(GridTrackSizingDirection) const;
 
     const Vector<LayoutUnit>& columnPositions() const { return m_columnPositions; }
@@ -77,6 +78,12 @@
     bool isRenderGrid() const override { return true; }
     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
 
+    void addChild(RenderObject* newChild, RenderObject* beforeChild) final;
+    void removeChild(RenderObject&) final;
+
+    bool explicitGridDidResize(const RenderStyle&) const;
+    bool namedGridLinesDefinitionDidChange(const RenderStyle&) const;
+
     std::optional<LayoutUnit> computeIntrinsicLogicalContentHeightUsing(Length logicalHeightLength, std::optional<LayoutUnit> intrinsicContentHeight, LayoutUnit borderAndPadding) const override;
 
     class Grid;
@@ -117,7 +124,6 @@
 
     void layoutGridItems(GridSizingData&);
     void populateGridPositionsForDirection(GridSizingData&, GridTrackSizingDirection);
-    void clearGrid();
 
     static bool shouldProcessTrackForTrackSizeComputationPhase(TrackSizeComputationPhase, const GridTrackSize&);
     static bool trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(TrackSizeComputationPhase, const GridTrackSize&);
@@ -241,8 +247,6 @@
     private:
         friend class GridIterator;
 
-        void clear();
-
         OrderIterator m_orderIterator;
 
         int m_smallestColumnStart { 0 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to