diff --git a/LayoutTests/fast/css-grid-layout/grid-stylechange-crash-expected.txt b/LayoutTests/fast/css-grid-layout/grid-stylechange-crash-expected.txt new file mode 100644 index 000000000000..73409aea8dfa --- /dev/null +++ b/LayoutTests/fast/css-grid-layout/grid-stylechange-crash-expected.txt @@ -0,0 +1,2 @@ +PASS if no crash. + diff --git a/LayoutTests/fast/css-grid-layout/grid-stylechange-crash.html b/LayoutTests/fast/css-grid-layout/grid-stylechange-crash.html new file mode 100644 index 000000000000..a799210c6bd0 --- /dev/null +++ b/LayoutTests/fast/css-grid-layout/grid-stylechange-crash.html @@ -0,0 +1,17 @@ + + +
+
+ PASS if no crash. +
+
+
+
+ \ No newline at end of file diff --git a/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp b/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp index f6ed31078c82..50c678d8ba9b 100644 --- a/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp +++ b/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp @@ -1615,6 +1615,7 @@ bool GridTrackSizingAlgorithm::copyUsedTrackSizesForSubgrid() GridSpan span = outer->gridSpanForChild(*m_renderGrid, direction); Vector& allTracks = tracks(m_direction); int numTracks = allTracks.size(); + RELEASE_ASSERT((parentTracks.size() - 1) >= (numTracks - 1 + span.startLine())); for (int i = 0; i < numTracks; i++) allTracks[i] = parentTracks[i + span.startLine()]; diff --git a/Source/WebCore/rendering/RenderGrid.cpp b/Source/WebCore/rendering/RenderGrid.cpp index bff4658f2caa..08432e9d0b65 100644 --- a/Source/WebCore/rendering/RenderGrid.cpp +++ b/Source/WebCore/rendering/RenderGrid.cpp @@ -106,9 +106,16 @@ void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl } } + auto subgridChanged = subgridDidChange(*oldStyle); if (explicitGridDidResize(*oldStyle) || namedGridLinesDefinitionDidChange(*oldStyle) || implicitGridLinesDefinitionDidChange(*oldStyle) || oldStyle->gridAutoFlow() != style().gridAutoFlow() - || (style().gridAutoRepeatColumns().size() || style().gridAutoRepeatRows().size())) - dirtyGrid(); + || (style().gridAutoRepeatColumns().size() || style().gridAutoRepeatRows().size()) || subgridChanged) + dirtyGrid(subgridChanged); +} + +bool RenderGrid::subgridDidChange(const RenderStyle& oldStyle) const +{ + return oldStyle.gridSubgridRows() != style().gridSubgridRows() + || oldStyle.gridSubgridColumns() != style().gridSubgridColumns(); } bool RenderGrid::explicitGridDidResize(const RenderStyle& oldStyle) const @@ -1190,12 +1197,20 @@ GridTrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() const return (autoPlacementMajorAxisDirection() == ForColumns) ? ForRows : ForColumns; } -void RenderGrid::dirtyGrid() +void RenderGrid::dirtyGrid(bool subgridChanged) { if (currentGrid().needsItemsPlacement()) return; currentGrid().setNeedsItemsPlacement(true); + + auto currentChild = this; + while (currentChild && (subgridChanged || currentChild->isSubgridRows() || currentChild->isSubgridColumns())) { + currentChild = dynamicDowncast(currentChild->parent()); + if (currentChild) + currentChild->currentGrid().setNeedsItemsPlacement(true); + subgridChanged = false; + } } Vector RenderGrid::trackSizesForComputedStyle(GridTrackSizingDirection direction) const diff --git a/Source/WebCore/rendering/RenderGrid.h b/Source/WebCore/rendering/RenderGrid.h index 3523b9439bb2..64c052f80509 100644 --- a/Source/WebCore/rendering/RenderGrid.h +++ b/Source/WebCore/rendering/RenderGrid.h @@ -62,7 +62,7 @@ class RenderGrid final : public RenderBlock { bool avoidsFloats() const override { return true; } bool canDropAnonymousBlockChild() const override { return false; } - void dirtyGrid(); + void dirtyGrid(bool subgridChanged = false); Vector trackSizesForComputedStyle(GridTrackSizingDirection) const; const Vector& columnPositions() const { return m_columnPositions; } @@ -144,6 +144,7 @@ class RenderGrid final : public RenderBlock { bool selfAlignmentChangedToStretch(GridAxis, const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderBox&) const; bool selfAlignmentChangedFromStretch(GridAxis, const RenderStyle& oldStyle, const RenderStyle& newStyle, const RenderBox&) const; + bool subgridDidChange(const RenderStyle& oldStyle) const; bool explicitGridDidResize(const RenderStyle&) const; bool namedGridLinesDefinitionDidChange(const RenderStyle&) const; bool implicitGridLinesDefinitionDidChange(const RenderStyle&) const;