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;