- Revision
- 292079
- Author
- mattwood...@apple.com
- Date
- 2022-03-29 16:04:15 -0700 (Tue, 29 Mar 2022)
Log Message
Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
https://bugs.webkit.org/show_bug.cgi?id=237732
Reviewed by Dean Jackson.
Source/WebCore:
Test: fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html
* rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
(WebCore::GridTrackSizingAlgorithm::advanceNextState):
(WebCore::GridTrackSizingAlgorithm::isValidTransition const):
* rendering/GridTrackSizingAlgorithm.h:
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutBlock):
(WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
* rendering/RenderGrid.h:
computeIntrinsicLogicalWidths can re-layout children (via performGridItemsPreLayout, as well as during
the track sizing algorithm), and does so using the estimated track sizes. This can be incorrect, and if
we're not about to do a full layout on this RenderGrid, it can leave the children in an invalid state.
This caches the intrinsic sizes when we do a full layout, so that we can use these values instead when
we just want to query the RenderGrid without mutating anything.
LayoutTests:
Don't mutate children during computeIntrinsicWidth
* TestExpectations:
* fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html: Added.
* fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html: Added.
* platform/ios/TestExpectations:
Marked existing WPT as passing on MacOS (since we run layout multiple times there).
Added new test for this implementation-specific bug.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (292078 => 292079)
--- trunk/LayoutTests/ChangeLog 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/ChangeLog 2022-03-29 23:04:15 UTC (rev 292079)
@@ -1,3 +1,20 @@
+2022-03-29 Matt Woodrow <mattwood...@apple.com>
+
+ Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
+ https://bugs.webkit.org/show_bug.cgi?id=237732
+
+ Reviewed by Dean Jackson.
+
+ Don't mutate children during computeIntrinsicWidth
+
+ * TestExpectations:
+ * fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html: Added.
+ * fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html: Added.
+ * platform/ios/TestExpectations:
+
+ Marked existing WPT as passing on MacOS (since we run layout multiple times there).
+ Added new test for this implementation-specific bug.
+
2022-03-29 Myles C. Maxfield <mmaxfi...@apple.com>
[Cocoa] Automatically relayout the page when new fonts are installed
Modified: trunk/LayoutTests/TestExpectations (292078 => 292079)
--- trunk/LayoutTests/TestExpectations 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/TestExpectations 2022-03-29 23:04:15 UTC (rev 292079)
@@ -1362,7 +1362,6 @@
webkit.org/b/216145 imported/w3c/web-platform-tests/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-auto-repeat-dynamic-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-repeat-max-width-001.html [ ImageOnlyFailure ]
webkit.org/b/234879 imported/w3c/web-platform-tests/css/css-grid/grid-items/grid-intrinsic-maximums.html [ ImageOnlyFailure ]
imported/w3c/web-platform-tests/css/css-grid/grid-items/grid-item-inline-contribution-003.html [ ImageOnlyFailure ]
Added: trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html (0 => 292079)
--- trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html 2022-03-29 23:04:15 UTC (rev 292079)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="background: red; max-width: 200px; padding: 20px;">
+ <div style="background: yellowgreen; display: grid; align-items: baseline;">
+ <span>Very long example text for testing line break which will not happen due to the bug</span>
+ </div>
+</div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html (0 => 292079)
--- trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html 2022-03-29 23:04:15 UTC (rev 292079)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="display: grid;">
+ <div style="background: red; max-width: 200px; padding: 20px; display: flex;">
+ <div style="background: yellowgreen; display: grid; align-items: baseline;">
+ <span>Very long example text for testing line break which will not happen due to the bug</span>
+ </div>
+ </div>
+</div>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/ios/TestExpectations (292078 => 292079)
--- trunk/LayoutTests/platform/ios/TestExpectations 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2022-03-29 23:04:15 UTC (rev 292079)
@@ -3147,6 +3147,8 @@
webkit.org/b/212226 imported/w3c/web-platform-tests/css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-008.html [ ImageOnlyFailure ]
webkit.org/b/212227 imported/w3c/web-platform-tests/css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-002.html [ ImageOnlyFailure ]
+imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-repeat-max-width-001.html [ ImageOnlyFailure ]
+
fast/text/text-styles/-apple-system [ Pass ]
webkit.org/b/214155 imported/w3c/web-platform-tests/html/cross-origin-embedder-policy/blob.https.html [ Pass Failure ]
Modified: trunk/Source/WebCore/ChangeLog (292078 => 292079)
--- trunk/Source/WebCore/ChangeLog 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/ChangeLog 2022-03-29 23:04:15 UTC (rev 292079)
@@ -1,3 +1,29 @@
+2022-03-29 Matt Woodrow <mattwood...@apple.com>
+
+ Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
+ https://bugs.webkit.org/show_bug.cgi?id=237732
+
+ Reviewed by Dean Jackson.
+
+ Test: fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html
+
+ * rendering/GridTrackSizingAlgorithm.cpp:
+ (WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
+ (WebCore::GridTrackSizingAlgorithm::advanceNextState):
+ (WebCore::GridTrackSizingAlgorithm::isValidTransition const):
+ * rendering/GridTrackSizingAlgorithm.h:
+ * rendering/RenderGrid.cpp:
+ (WebCore::RenderGrid::layoutBlock):
+ (WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
+ * rendering/RenderGrid.h:
+
+ computeIntrinsicLogicalWidths can re-layout children (via performGridItemsPreLayout, as well as during
+ the track sizing algorithm), and does so using the estimated track sizes. This can be incorrect, and if
+ we're not about to do a full layout on this RenderGrid, it can leave the children in an invalid state.
+
+ This caches the intrinsic sizes when we do a full layout, so that we can use these values instead when
+ we just want to query the RenderGrid without mutating anything.
+
2022-03-29 Myles C. Maxfield <mmaxfi...@apple.com>
[Cocoa] Automatically relayout the page when new fonts are installed
Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp (292078 => 292079)
--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp 2022-03-29 23:04:15 UTC (rev 292079)
@@ -623,11 +623,11 @@
// To determine the column track's size based on an orthogonal grid item we need it's logical
// height, which may depend on the row track's size. It's possible that the row tracks sizing
// logic has not been performed yet, so we will need to do an estimation.
- if (direction == ForRows && (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingSecondIteration)) {
+ if (direction == ForRows && (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingExtraIterationForSizeContainment || m_sizingState == ColumnSizingSecondIteration)) {
ASSERT(GridLayoutFunctions::isOrthogonalChild(*m_renderGrid, child));
// FIXME (jfernandez) Content Alignment should account for this heuristic.
// https://github.com/w3c/csswg-drafts/issues/2697
- if (m_sizingState == ColumnSizingFirstIteration)
+ if (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingExtraIterationForSizeContainment)
return estimatedGridAreaBreadthForChild(child, ForRows);
addContentAlignmentOffset = true;
}
@@ -1410,6 +1410,9 @@
{
switch (m_sizingState) {
case ColumnSizingFirstIteration:
+ m_sizingState = m_strategy->isComputingSizeContainment() ? ColumnSizingExtraIterationForSizeContainment : RowSizingFirstIteration;
+ return;
+ case ColumnSizingExtraIterationForSizeContainment:
m_sizingState = RowSizingFirstIteration;
return;
case RowSizingFirstIteration:
@@ -1433,6 +1436,7 @@
{
switch (m_sizingState) {
case ColumnSizingFirstIteration:
+ case ColumnSizingExtraIterationForSizeContainment:
case ColumnSizingSecondIteration:
return m_direction == ForColumns;
case RowSizingFirstIteration:
Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h (292078 => 292079)
--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h 2022-03-29 23:04:15 UTC (rev 292079)
@@ -241,6 +241,7 @@
enum SizingState {
ColumnSizingFirstIteration,
+ ColumnSizingExtraIterationForSizeContainment,
RowSizingFirstIteration,
RowSizingExtraIterationForSizeContainment,
ColumnSizingSecondIteration,
Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (292078 => 292079)
--- trunk/Source/WebCore/rendering/RenderGrid.cpp 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp 2022-03-29 23:04:15 UTC (rev 292079)
@@ -280,8 +280,16 @@
// logical width is always definite as the above call to updateLogicalWidth() properly resolves intrinsic
// sizes. We cannot do the same for heights though because many code paths inside updateLogicalHeight() require
// a previous call to setLogicalHeight() to resolve heights properly (like for positioned items for example).
- computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
+ if (shouldApplySizeContainment(*this))
+ computeTrackSizesForIndefiniteSize(m_trackSizingAlgorithm, ForColumns);
+ else
+ computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
+ m_minContentSize = m_trackSizingAlgorithm.minContentSize();
+ m_maxContentSize = m_trackSizingAlgorithm.maxContentSize();
+ if (shouldApplySizeContainment(*this))
+ computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
+
// 1.5- Compute Content Distribution offsets for column tracks
computeContentPositionAndDistributionOffset(ForColumns, m_trackSizingAlgorithm.freeSpace(ForColumns).value(), nonCollapsedTracks(ForColumns));
@@ -459,24 +467,30 @@
LayoutUnit childMaxWidth;
bool hadExcludedChildren = computePreferredWidthsForExcludedChildren(childMinWidth, childMaxWidth);
- GridTrackSizingAlgorithm algorithm(this, const_cast<Grid&>(m_grid));
- placeItemsOnGrid(algorithm, std::nullopt);
+ if (needsLayout()) {
+ GridTrackSizingAlgorithm algorithm(this, const_cast<Grid&>(m_grid));
+ placeItemsOnGrid(algorithm, std::nullopt);
- performGridItemsPreLayout(algorithm);
+ performGridItemsPreLayout(algorithm);
- if (m_baselineItemsCached)
- algorithm.copyBaselineItemsCache(m_trackSizingAlgorithm, GridRowAxis);
- else {
- for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
- if (child->isOutOfFlowPositioned())
- continue;
- if (isBaselineAlignmentForChild(*child, GridRowAxis))
- algorithm.cacheBaselineAlignedItem(*child, GridRowAxis);
+ if (m_baselineItemsCached)
+ algorithm.copyBaselineItemsCache(m_trackSizingAlgorithm, GridRowAxis);
+ else {
+ for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ if (child->isOutOfFlowPositioned())
+ continue;
+ if (isBaselineAlignmentForChild(*child, GridRowAxis))
+ algorithm.cacheBaselineAlignedItem(*child, GridRowAxis);
+ }
}
+
+ computeTrackSizesForIndefiniteSize(algorithm, ForColumns, &minLogicalWidth, &maxLogicalWidth);
+ } else {
+ LayoutUnit totalGuttersSize = guttersSize(m_grid, ForColumns, 0, numTracks(ForColumns), std::nullopt);
+ minLogicalWidth = *m_minContentSize + totalGuttersSize;
+ maxLogicalWidth = *m_maxContentSize + totalGuttersSize;
}
- computeTrackSizesForIndefiniteSize(algorithm, ForColumns, &minLogicalWidth, &maxLogicalWidth);
-
if (hadExcludedChildren) {
minLogicalWidth = std::max(minLogicalWidth, childMinWidth);
maxLogicalWidth = std::max(maxLogicalWidth, childMaxWidth);
Modified: trunk/Source/WebCore/rendering/RenderGrid.h (292078 => 292079)
--- trunk/Source/WebCore/rendering/RenderGrid.h 2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/RenderGrid.h 2022-03-29 23:04:15 UTC (rev 292079)
@@ -243,6 +243,9 @@
OutOfFlowPositionsMap m_outOfFlowItemColumn;
OutOfFlowPositionsMap m_outOfFlowItemRow;
+ std::optional<LayoutUnit> m_minContentSize;
+ std::optional<LayoutUnit> m_maxContentSize;
+
bool m_hasAnyOrthogonalItem {false};
bool m_hasAspectRatioBlockSizeDependentItem { false };
bool m_baselineItemsCached {false};