Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (289985 => 289986)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-02-17 01:31:02 UTC (rev 289986)
@@ -1,3 +1,15 @@
+2022-02-16 Matt Woodrow <mattwood...@apple.com>
+
+ Inherit track count from parent grid for subgridded axes and clamp item placement to that explicit grid.
+ https://bugs.webkit.org/show_bug.cgi?id=236122
+
+ Reviewed by Dean Jackson.
+
+ Test changes to match latest spec, submitted upstream as https://github.com/web-platform-tests/wpt/pull/32629
+
+ * web-platform-tests/css/css-grid/subgrid/line-names-002-expected.html:
+ * web-platform-tests/css/css-grid/subgrid/line-names-005-expected.html:
+
2022-02-16 Said Abou-Hallawa <s...@apple.com>
[GPU Process] Enable drawing the SVGImage in the GPU Process
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-002-expected.html (289985 => 289986)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-002-expected.html 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-002-expected.html 2022-02-17 01:31:02 UTC (rev 289986)
@@ -14,7 +14,7 @@
.grid {
display: grid;
- grid: auto / [a] 50px 50px [a] 50px 50px [a];
+ grid: auto / [a] 50px 40px [a] 10px 50px [a];
padding: 20px 10px;
}
@@ -32,7 +32,7 @@
<div class="grid">
<div class="subgrid">
- <x style="grid-column: 1 / 3"></x>
+ <x style="grid-column: 3 / 4"></x>
</div>
</div>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-005-expected.html (289985 => 289986)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-005-expected.html 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-005-expected.html 2022-02-17 01:31:02 UTC (rev 289986)
@@ -115,7 +115,7 @@
<div style="display:grid; width:500px; grid-auto-columns: 50px;">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
<div class="subgrid2">
- <x style="grid-column: span 4 / 11">x</x>
+ <x style="grid-column: span 3 / 11">x</x>
</div>
</div>
@@ -129,7 +129,7 @@
<div style="display:grid; grid: auto / repeat(10, 50px) repeat(10, [a] 50px) [a]">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
<div style="display:grid; grid:auto/subgrid; grid-column: span 10; grid-row:2">
- <x style="grid-column: 1 / 11">x</x>
+ <x style="grid-column: 10 / 11">x</x>
</div>
</div>
Modified: trunk/Source/WebCore/ChangeLog (289985 => 289986)
--- trunk/Source/WebCore/ChangeLog 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/ChangeLog 2022-02-17 01:31:02 UTC (rev 289986)
@@ -1,3 +1,58 @@
+2022-02-16 Matt Woodrow <mattwood...@apple.com>
+
+ Inherit track count from parent grid for subgridded axes and clamp item placement to that explicit grid.
+ https://bugs.webkit.org/show_bug.cgi?id=236122
+
+ Reviewed by Dean Jackson.
+
+ Changes GridPositionsResolver::explicitGrid<>Count to return the number of tracks
+ spanned in the parent grid, for axes that are a subgrid.
+
+ Updates adjustGridPositionsForStyle to use the number of lines specified in the
+ subgrid property, for grid items that are also a subgrid and have an otherwise
+ indefinite span.
+
+ Adds clamping support to Grid so that we can prevent subgrids from ever adding
+ new implicit tracks.
+
+ * rendering/Grid.cpp:
+ (WebCore::Grid::insert):
+ (WebCore::Grid::setClampingForSubgrid):
+ (WebCore::Grid::clampAndTranslateToImplicitGrid):
+ (WebCore::Grid::setNeedsItemsPlacement):
+ * rendering/Grid.h:
+ * rendering/RenderGrid.cpp:
+ (WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
+ (WebCore::RenderGrid::placeItemsOnGrid const):
+ (WebCore::RenderGrid::populateExplicitGridAndOrderIterator const):
+ (WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid const):
+ (WebCore::RenderGrid::isSubgrid const):
+ (WebCore::RenderGrid::isSubgridRows const):
+ (WebCore::RenderGrid::isSubgridColumns const):
+ (WebCore::RenderGrid::gridAreaBreadthForOutOfFlowChild):
+ (WebCore::RenderGrid::numTracks const):
+ (WebCore::transposedDirection):
+ (WebCore::RenderGrid::computeGridSpanForOutOfFlowChild const):
+ (WebCore::RenderGrid::gridSpanForOutOfFlowChild const):
+ (WebCore::RenderGrid::gridSpanForChild const):
+ * rendering/RenderGrid.h:
+ * rendering/style/GridArea.h:
+ (WebCore::GridSpan::integerSpan const):
+ (WebCore::GridSpan::translateTo):
+ (WebCore::GridSpan::clamp):
+ * rendering/style/GridPositionsResolver.cpp:
+ (WebCore::isIndefiniteSpan):
+ (WebCore::adjustGridPositionsFromStyle):
+ (WebCore::GridPositionsResolver::explicitGridColumnCount):
+ (WebCore::GridPositionsResolver::explicitGridRowCount):
+ (WebCore::explicitGridSizeForSide):
+ (WebCore::resolveNamedGridLinePositionFromStyle):
+ (WebCore::resolveNamedGridLinePositionAgainstOppositePosition):
+ (WebCore::resolveGridPositionAgainstOppositePosition):
+ (WebCore::resolveGridPositionFromStyle):
+ (WebCore::GridPositionsResolver::resolveGridPositionsFromStyle):
+ * rendering/style/GridPositionsResolver.h:
+
2022-02-16 Said Abou-Hallawa <s...@apple.com>
[GPU Process] Enable drawing the SVGImage in the GPU Process
Modified: trunk/Source/WebCore/rendering/Grid.cpp (289985 => 289986)
--- trunk/Source/WebCore/rendering/Grid.cpp 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/Grid.cpp 2022-02-17 01:31:02 UTC (rev 289986)
@@ -61,17 +61,24 @@
}
}
-void Grid::insert(RenderBox& child, const GridArea& area)
+GridArea Grid::insert(RenderBox& child, const GridArea& area)
{
- ASSERT(area.rows.isTranslatedDefinite() && area.columns.isTranslatedDefinite());
- ensureGridSize(area.rows.endLine(), area.columns.endLine());
+ GridArea clampedArea = area;
+ if (m_maxRows)
+ clampedArea.rows.clamp(m_maxRows);
+ if (m_maxColumns)
+ clampedArea.columns.clamp(m_maxColumns);
- for (auto row : area.rows) {
- for (auto column : area.columns)
+ ASSERT(clampedArea.rows.isTranslatedDefinite() && clampedArea.columns.isTranslatedDefinite());
+ ensureGridSize(clampedArea.rows.endLine(), clampedArea.columns.endLine());
+
+ for (auto row : clampedArea.rows) {
+ for (auto column : clampedArea.columns)
m_grid[row][column].append(child);
}
- setGridItemArea(child, area);
+ setGridItemArea(child, clampedArea);
+ return clampedArea;
}
void Grid::setExplicitGridStart(unsigned rowStart, unsigned columnStart)
@@ -85,6 +92,24 @@
return direction == ForRows ? m_explicitRowStart : m_explicitColumnStart;
}
+void Grid::setClampingForSubgrid(unsigned maxRows, unsigned maxColumns)
+{
+ m_maxRows = maxRows;
+ m_maxColumns = maxColumns;
+}
+
+void Grid::clampAreaToSubgridIfNeeded(GridArea& area)
+{
+ if (!area.rows.isIndefinite()) {
+ if (m_maxRows)
+ area.rows.clamp(m_maxRows);
+ }
+ if (!area.columns.isIndefinite()) {
+ if (m_maxColumns)
+ area.columns.clamp(m_maxColumns);
+ }
+}
+
GridArea Grid::gridItemArea(const RenderBox& item) const
{
ASSERT(m_gridItemArea.contains(&item));
@@ -161,6 +186,8 @@
m_autoRepeatEmptyRows = nullptr;
m_autoRepeatColumns = 0;
m_autoRepeatRows = 0;
+ m_maxColumns = 0;
+ m_maxRows = 0;
}
GridIterator::GridIterator(const Grid& grid, GridTrackSizingDirection direction, unsigned fixedTrackIndex, unsigned varyingTrackIndex)
Modified: trunk/Source/WebCore/rendering/Grid.h (289985 => 289986)
--- trunk/Source/WebCore/rendering/Grid.h 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/Grid.h 2022-02-17 01:31:02 UTC (rev 289986)
@@ -48,7 +48,7 @@
unsigned numTracks(GridTrackSizingDirection) const;
void ensureGridSize(unsigned maximumRowSize, unsigned maximumColumnSize);
- void insert(RenderBox&, const GridArea&);
+ GridArea insert(RenderBox&, const GridArea&);
// Note that each in flow child of a grid container becomes a grid item. This means that
// this method will return false for a grid container with only out of flow children.
@@ -67,6 +67,10 @@
unsigned autoRepeatTracks(GridTrackSizingDirection) const;
void setAutoRepeatTracks(unsigned autoRepeatRows, unsigned autoRepeatColumns);
+ void setClampingForSubgrid(unsigned maxRows, unsigned maxColumns);
+
+ void clampAreaToSubgridIfNeeded(GridArea&);
+
void setAutoRepeatEmptyColumns(std::unique_ptr<OrderedTrackIndexSet>);
void setAutoRepeatEmptyRows(std::unique_ptr<OrderedTrackIndexSet>);
@@ -92,6 +96,9 @@
unsigned m_autoRepeatColumns { 0 };
unsigned m_autoRepeatRows { 0 };
+ unsigned m_maxColumns { 0 };
+ unsigned m_maxRows { 0 };
+
bool m_needsItemsPlacement { true };
GridAsMatrix m_grid;
Modified: trunk/Source/WebCore/rendering/GridLayoutFunctions.cpp (289985 => 289986)
--- trunk/Source/WebCore/rendering/GridLayoutFunctions.cpp 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/GridLayoutFunctions.cpp 2022-02-17 01:31:02 UTC (rev 289986)
@@ -102,6 +102,20 @@
return direction == ForColumns ? child.overridingContainingBlockContentLogicalWidth() : child.overridingContainingBlockContentLogicalHeight();
}
+bool isFlippedDirection(const RenderGrid& grid, GridTrackSizingDirection direction)
+{
+ if (direction == ForColumns)
+ return !grid.style().isLeftToRightDirection();
+ return grid.style().isFlippedBlocksWritingMode();
+}
+
+bool isSubgridReversedDirection(const RenderGrid& grid, GridTrackSizingDirection outerDirection, const RenderGrid& subgrid)
+{
+ GridTrackSizingDirection childDirection = flowAwareDirectionForChild(grid, subgrid, outerDirection);
+ ASSERT(subgrid.isSubgrid(childDirection));
+ return isFlippedDirection(grid, outerDirection) != isFlippedDirection(subgrid, childDirection);
+}
+
} // namespace GridLayoutFunctions
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/GridLayoutFunctions.h (289985 => 289986)
--- trunk/Source/WebCore/rendering/GridLayoutFunctions.h 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/GridLayoutFunctions.h 2022-02-17 01:31:02 UTC (rev 289986)
@@ -45,6 +45,9 @@
bool hasOverridingContainingBlockContentSizeForChild(const RenderBox&, GridTrackSizingDirection);
std::optional<LayoutUnit> overridingContainingBlockContentSizeForChild(const RenderBox&, GridTrackSizingDirection);
+bool isFlippedDirection(const RenderGrid&, GridTrackSizingDirection);
+bool isSubgridReversedDirection(const RenderGrid&, GridTrackSizingDirection outerDirection, const RenderGrid& subgrid);
+
}
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (289985 => 289986)
--- trunk/Source/WebCore/rendering/RenderGrid.cpp 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp 2022-02-17 01:31:02 UTC (rev 289986)
@@ -446,8 +446,7 @@
LayoutUnit childMaxWidth;
bool hadExcludedChildren = computePreferredWidthsForExcludedChildren(childMinWidth, childMaxWidth);
- Grid grid(const_cast<RenderGrid&>(*this));
- GridTrackSizingAlgorithm algorithm(this, grid);
+ GridTrackSizingAlgorithm algorithm(this, const_cast<Grid&>(m_grid));
placeItemsOnGrid(algorithm, std::nullopt);
performGridItemsPreLayout(algorithm);
@@ -641,7 +640,6 @@
Grid& grid = algorithm.mutableGrid();
unsigned autoRepeatColumns = computeAutoRepeatTracksCount(ForColumns, availableLogicalWidth);
unsigned autoRepeatRows = computeAutoRepeatTracksCount(ForRows, availableLogicalHeightForPercentageComputation());
-
autoRepeatRows = clampAutoRepeatTracks(ForRows, autoRepeatRows);
autoRepeatColumns = clampAutoRepeatTracks(ForColumns, autoRepeatColumns);
@@ -670,6 +668,7 @@
child->setOverridingContainingBlockContentLogicalHeight(std::nullopt);
GridArea area = grid.gridItemArea(*child);
+ grid.clampAreaToSubgridIfNeeded(area);
if (!area.rows.isIndefinite())
area.rows.translate(grid.explicitGridStart(ForRows));
if (!area.columns.isIndefinite())
@@ -690,8 +689,8 @@
#if ASSERT_ENABLED
if (grid.hasGridItems()) {
- ASSERT(grid.numTracks(ForRows) >= GridPositionsResolver::explicitGridRowCount(style(), grid.autoRepeatTracks(ForRows)));
- ASSERT(grid.numTracks(ForColumns) >= GridPositionsResolver::explicitGridColumnCount(style(), grid.autoRepeatTracks(ForColumns)));
+ ASSERT(grid.numTracks(ForRows) >= GridPositionsResolver::explicitGridRowCount(*this));
+ ASSERT(grid.numTracks(ForColumns) >= GridPositionsResolver::explicitGridColumnCount(*this));
}
#endif
@@ -745,33 +744,35 @@
OrderIteratorPopulator populator(grid.orderIterator());
unsigned explicitRowStart = 0;
unsigned explicitColumnStart = 0;
- unsigned autoRepeatRows = grid.autoRepeatTracks(ForRows);
- unsigned autoRepeatColumns = grid.autoRepeatTracks(ForColumns);
- unsigned maximumRowIndex = GridPositionsResolver::explicitGridRowCount(style(), autoRepeatRows);
- unsigned maximumColumnIndex = GridPositionsResolver::explicitGridColumnCount(style(), autoRepeatColumns);
+ unsigned maximumRowIndex = GridPositionsResolver::explicitGridRowCount(*this);
+ unsigned maximumColumnIndex = GridPositionsResolver::explicitGridColumnCount(*this);
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
if (!populator.collectChild(*child))
continue;
- GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForRows, autoRepeatRows);
- if (!rowPositions.isIndefinite()) {
- explicitRowStart = std::max<int>(explicitRowStart, -rowPositions.untranslatedStartLine());
- maximumRowIndex = std::max<int>(maximumRowIndex, rowPositions.untranslatedEndLine());
- } else {
- // Grow the grid for items with a definite row span, getting the largest such span.
- unsigned spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem(*child, ForRows);
- maximumRowIndex = std::max(maximumRowIndex, spanSize);
+ GridSpan rowPositions = GridPositionsResolver::resolveGridPositionsFromStyle(*child, ForRows);
+ if (!isSubgridRows()) {
+ if (!rowPositions.isIndefinite()) {
+ explicitRowStart = std::max<int>(explicitRowStart, -rowPositions.untranslatedStartLine());
+ maximumRowIndex = std::max<int>(maximumRowIndex, rowPositions.untranslatedEndLine());
+ } else {
+ // Grow the grid for items with a definite row span, getting the largest such span.
+ unsigned spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem(*child, ForRows);
+ maximumRowIndex = std::max(maximumRowIndex, spanSize);
+ }
}
- GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(style(), *child, ForColumns, autoRepeatColumns);
- if (!columnPositions.isIndefinite()) {
- explicitColumnStart = std::max<int>(explicitColumnStart, -columnPositions.untranslatedStartLine());
- maximumColumnIndex = std::max<int>(maximumColumnIndex, columnPositions.untranslatedEndLine());
- } else {
- // Grow the grid for items with a definite column span, getting the largest such span.
- unsigned spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem(*child, ForColumns);
- maximumColumnIndex = std::max(maximumColumnIndex, spanSize);
+ GridSpan columnPositions = GridPositionsResolver::resolveGridPositionsFromStyle(*child, ForColumns);
+ if (!isSubgridColumns()) {
+ if (!columnPositions.isIndefinite()) {
+ explicitColumnStart = std::max<int>(explicitColumnStart, -columnPositions.untranslatedStartLine());
+ maximumColumnIndex = std::max<int>(maximumColumnIndex, columnPositions.untranslatedEndLine());
+ } else {
+ // Grow the grid for items with a definite column span, getting the largest such span.
+ unsigned spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem(*child, ForColumns);
+ maximumColumnIndex = std::max(maximumColumnIndex, spanSize);
+ }
}
grid.setGridItemArea(*child, { rowPositions, columnPositions });
@@ -779,6 +780,7 @@
grid.setExplicitGridStart(explicitRowStart, explicitColumnStart);
grid.ensureGridSize(maximumRowIndex + explicitRowStart, maximumColumnIndex + explicitColumnStart);
+ grid.setClampingForSubgrid(isSubgridRows() ? maximumRowIndex : 0, isSubgridColumns() ? maximumColumnIndex : 0);
}
std::unique_ptr<GridArea> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(Grid& grid, const RenderBox& gridItem, GridTrackSizingDirection specifiedDirection, const GridSpan& specifiedPositions) const
@@ -812,7 +814,7 @@
if (!emptyGridArea)
emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(grid, *autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
- grid.insert(*autoGridItem, *emptyGridArea);
+ *emptyGridArea = grid.insert(*autoGridItem, *emptyGridArea);
if (!isGridAutoFlowDense)
minorAxisCursors.set(majorAxisInitialPosition, isForColumns ? emptyGridArea->rows.startLine() : emptyGridArea->columns.startLine());
@@ -1610,23 +1612,25 @@
return clientLogicalWidth();
}
+bool RenderGrid::isSubgrid(GridTrackSizingDirection direction) const
+{
+ if (isOutOfFlowPositioned() || isExcludedFromNormalLayout())
+ return false;
+ if ((direction == ForColumns) ? !style().gridSubgridColumns() : !style().gridSubgridRows())
+ return false;
+ return is<RenderGrid>(parent());
+}
+
LayoutUnit RenderGrid::gridAreaBreadthForOutOfFlowChild(const RenderBox& child, GridTrackSizingDirection direction)
{
ASSERT(child.isOutOfFlowPositioned());
bool isRowAxis = direction == ForColumns;
- GridSpan span = GridPositionsResolver::resolveGridPositionsFromStyle(style(), child, direction, autoRepeatCountForDirection(direction));
- if (span.isIndefinite())
- return isRowAxis ? clientLogicalWidth() : clientLogicalHeight();
-
- unsigned explicitStart = m_grid.explicitGridStart(direction);
- int startLine = span.untranslatedStartLine() + explicitStart;
- int endLine = span.untranslatedEndLine() + explicitStart;
int lastLine = numTracks(direction, m_grid);
- GridPosition startPosition = direction == ForColumns ? child.style().gridItemColumnStart() : child.style().gridItemRowStart();
- GridPosition endPosition = direction == ForColumns ? child.style().gridItemColumnEnd() : child.style().gridItemRowEnd();
- bool startIsAuto = startPosition.isAuto() || startLine < 0 || startLine > lastLine;
- bool endIsAuto = endPosition.isAuto() || endLine < 0 || endLine > lastLine;
+ int startLine, endLine;
+ bool startIsAuto, endIsAuto;
+ if (!computeGridPositionsForOutOfFlowChild(child, direction, startLine, startIsAuto, endLine, endIsAuto))
+ return isRowAxis ? clientLogicalWidth() : clientLogicalHeight();
if (startIsAuto && endIsAuto)
return isRowAxis ? clientLogicalWidth() : clientLogicalHeight();
@@ -1920,7 +1924,7 @@
return grid.numTracks(ForRows);
// FIXME: This still requires knowledge about m_grid internals.
- return grid.numTracks(ForRows) ? grid.numTracks(ForColumns) : GridPositionsResolver::explicitGridColumnCount(style(), grid.autoRepeatTracks(ForColumns));
+ return grid.numTracks(ForRows) ? grid.numTracks(ForColumns) : GridPositionsResolver::explicitGridColumnCount(*this);
}
void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect)
@@ -1977,4 +1981,62 @@
return isHorizontalWritingMode() ? child.style().width().isAuto() : child.style().height().isAuto();
}
+bool RenderGrid::computeGridPositionsForOutOfFlowChild(const RenderBox& child, GridTrackSizingDirection direction, int& startLine, bool& startIsAuto, int& endLine, bool& endIsAuto) const
+{
+ ASSERT(child.isOutOfFlowPositioned());
+ int lastLine = numTracks(direction, m_grid);
+ GridSpan span = GridPositionsResolver::resolveGridPositionsFromStyle(child, direction);
+ if (span.isIndefinite())
+ return false;
+
+ unsigned explicitStart = m_grid.explicitGridStart(direction);
+ startLine = span.untranslatedStartLine() + explicitStart;
+ endLine = span.untranslatedEndLine() + explicitStart;
+
+ GridPosition startPosition = direction == ForColumns ? child.style().gridItemColumnStart() : child.style().gridItemRowStart();
+ GridPosition endPosition = direction == ForColumns ? child.style().gridItemColumnEnd() : child.style().gridItemRowEnd();
+
+ startIsAuto = startPosition.isAuto() || startLine < 0 || startLine > lastLine;
+ endIsAuto = endPosition.isAuto() || endLine < 0 || endLine > lastLine;
+ return true;
+}
+
+GridSpan RenderGrid::gridSpanForOutOfFlowChild(const RenderBox& child, GridTrackSizingDirection direction) const
+{
+ int lastLine = numTracks(direction, m_grid);
+ int startLine, endLine;
+ bool startIsAuto, endIsAuto;
+ if (!computeGridPositionsForOutOfFlowChild(child, direction, startLine, startIsAuto, endLine, endIsAuto))
+ return GridSpan::translatedDefiniteGridSpan(0, lastLine);
+ return GridSpan::translatedDefiniteGridSpan(startIsAuto ? 0 : startLine, endIsAuto ? lastLine : endLine);
+}
+
+GridSpan RenderGrid::gridSpanForChild(const RenderBox& child, GridTrackSizingDirection direction) const
+{
+ ASSERT(is<RenderGrid>(child.parent()));
+
+ RenderGrid* renderGrid = downcast<RenderGrid>(child.parent());
+ // |direction| is specified relative to this grid, switch it if |child|'s direct parent grid
+ // is using a different writing mode.
+ direction = GridLayoutFunctions::flowAwareDirectionForChild(*this, *renderGrid, direction);
+ GridSpan span = child.isOutOfFlowPositioned() ? renderGrid->gridSpanForOutOfFlowChild(child, direction) : renderGrid->currentGrid().gridItemSpan(child, direction);
+
+ while (renderGrid != this) {
+ ASSERT(is<RenderGrid>(renderGrid->parent()));
+ RenderGrid* parent = downcast<RenderGrid>(renderGrid->parent());
+
+ bool isSubgrid = renderGrid->isSubgrid(direction);
+
+ direction = GridLayoutFunctions::flowAwareDirectionForChild(*parent, *renderGrid, direction);
+
+ GridSpan parentSpan = renderGrid->isOutOfFlowPositioned() ? parent->gridSpanForOutOfFlowChild(*renderGrid, direction) : parent->currentGrid().gridItemSpan(*renderGrid, direction);
+ if (isSubgrid)
+ span.translateTo(parentSpan, GridLayoutFunctions::isSubgridReversedDirection(*parent, direction, *renderGrid));
+ else
+ span = parentSpan;
+ renderGrid = parent;
+ }
+ return span;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderGrid.h (289985 => 289986)
--- trunk/Source/WebCore/rendering/RenderGrid.h 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/RenderGrid.h 2022-02-17 01:31:02 UTC (rev 289986)
@@ -82,6 +82,25 @@
StyleContentAlignmentData contentAlignment(GridTrackSizingDirection) const;
+ // Computes the span relative to this RenderGrid, even if the RenderBox is a child
+ // of a descendant subgrid.
+ GridSpan gridSpanForChild(const RenderBox&, GridTrackSizingDirection) const;
+
+ bool isSubgrid(GridTrackSizingDirection) const;
+ bool isSubgridRows() const
+ {
+ return isSubgrid(ForRows);
+ }
+ bool isSubgridColumns() const
+ {
+ return isSubgrid(ForColumns);
+ }
+
+ const Grid& currentGrid() const
+ {
+ return m_grid;
+ }
+
private:
ItemPosition selfAlignmentNormalBehavior(const RenderBox* child = nullptr) const override
{
@@ -150,8 +169,6 @@
void setLogicalPositionForChild(RenderBox&) const;
void setLogicalOffsetForChild(RenderBox&, GridTrackSizingDirection) const;
LayoutUnit logicalOffsetForChild(const RenderBox&, GridTrackSizingDirection) const;
- GridArea cachedGridArea(const RenderBox&) const;
- GridSpan cachedGridSpan(const RenderBox&, GridTrackSizingDirection) const;
LayoutUnit gridAreaBreadthForChildIncludingAlignmentOffsets(const RenderBox&, GridTrackSizingDirection) const;
@@ -193,6 +210,9 @@
Vector<RenderBox*> computeAspectRatioDependentAndBaselineItems();
+ GridSpan gridSpanForOutOfFlowChild(const RenderBox&, GridTrackSizingDirection) const;
+ bool computeGridPositionsForOutOfFlowChild(const RenderBox&, GridTrackSizingDirection, int&, bool&, int&, bool&) const;
+
Grid m_grid;
GridTrackSizingAlgorithm m_trackSizingAlgorithm;
Modified: trunk/Source/WebCore/rendering/style/GridArea.h (289985 => 289986)
--- trunk/Source/WebCore/rendering/style/GridArea.h 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/style/GridArea.h 2022-02-17 01:31:02 UTC (rev 289986)
@@ -65,7 +65,7 @@
unsigned integerSpan() const
{
- ASSERT(isTranslatedDefinite());
+ ASSERT(!isIndefinite());
return m_endLine - m_startLine;
}
@@ -141,6 +141,31 @@
ASSERT(m_endLine > 0);
}
+ // Moves this span to be in the same coordinate space as |parent|.
+ // If reverse is specified, then swaps the direction to handle RTL/LTR changes.
+ void translateTo(const GridSpan& parent, bool reverse)
+ {
+ ASSERT(m_type == TranslatedDefinite);
+ ASSERT(parent.m_type == TranslatedDefinite);
+ if (reverse) {
+ int start = m_startLine;
+ m_startLine = parent.endLine() - m_endLine;
+ m_endLine = parent.endLine() - start;
+ } else {
+ m_startLine += parent.m_startLine;
+ m_endLine += parent.m_startLine;
+ }
+ }
+
+ void clamp(int max)
+ {
+ ASSERT(m_type != Indefinite);
+ m_startLine = std::max(m_startLine, 0);
+ m_endLine = std::max(std::min(m_endLine, max), 1);
+ if (m_startLine >= m_endLine)
+ m_startLine = m_endLine - 1;
+ }
+
private:
enum GridSpanType {UntranslatedDefinite, TranslatedDefinite, Indefinite};
Modified: trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp (289985 => 289986)
--- trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp 2022-02-17 01:31:02 UTC (rev 289986)
@@ -33,6 +33,7 @@
#include "GridArea.h"
#include "RenderBox.h"
+#include "RenderGrid.h"
#include <cstdlib>
namespace WebCore {
@@ -152,6 +153,16 @@
return std::min(firstExplicitPosition(), m_implicitNamedLinesIndexes->at(firstLine));
}
+// https://drafts.csswg.org/css-grid-2/#indefinite-grid-span
+static bool isIndefiniteSpan(GridPosition& initialPosition, GridPosition& finalPosition)
+{
+ if (initialPosition.isAuto())
+ return !finalPosition.isSpan();
+ if (finalPosition.isAuto())
+ return !initialPosition.isSpan();
+ return false;
+}
+
static void adjustGridPositionsFromStyle(const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition)
{
bool isForColumns = direction == ForColumns;
@@ -168,21 +179,44 @@
finalPosition.setSpanPosition(1, String());
if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull())
initialPosition.setSpanPosition(1, String());
+
+ if (isIndefiniteSpan(initialPosition, finalPosition) && is<RenderGrid>(gridItem) && downcast<RenderGrid>(gridItem).isSubgrid(direction)) {
+ // Indefinite span for an item that is subgridded in this axis.
+ int lineCount = (isForColumns ? gridItem.style().orderedNamedGridColumnLines() : gridItem.style().orderedNamedGridRowLines()).size();
+
+ if (initialPosition.isAuto()) {
+ // Set initial position to span <line names - 1>
+ initialPosition.setSpanPosition(std::max(1, lineCount - 1), "");
+ } else {
+ // Set final position to span <line names - 1>
+ finalPosition.setSpanPosition(std::max(1, lineCount - 1), "");
+ }
+ }
}
-unsigned GridPositionsResolver::explicitGridColumnCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
+unsigned GridPositionsResolver::explicitGridColumnCount(const RenderGrid& gridContainer)
{
- return std::min<unsigned>(std::max(gridContainerStyle.gridColumns().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaColumnCount()), GridPosition::max());
+ if (gridContainer.isSubgridColumns()) {
+ const RenderGrid& parent = *downcast<RenderGrid>(gridContainer.parent());
+ GridTrackSizingDirection direction = GridLayoutFunctions::flowAwareDirectionForChild(parent, gridContainer, ForColumns);
+ return parent.gridSpanForChild(gridContainer, direction).integerSpan();
+ }
+ return std::min<unsigned>(std::max(gridContainer.style().gridColumns().size() + gridContainer.autoRepeatCountForDirection(ForColumns), gridContainer.style().namedGridAreaColumnCount()), GridPosition::max());
}
-unsigned GridPositionsResolver::explicitGridRowCount(const RenderStyle& gridContainerStyle, unsigned autoRepeatTracksCount)
+unsigned GridPositionsResolver::explicitGridRowCount(const RenderGrid& gridContainer)
{
- return std::min<unsigned>(std::max(gridContainerStyle.gridRows().size() + autoRepeatTracksCount, gridContainerStyle.namedGridAreaRowCount()), GridPosition::max());
+ if (gridContainer.isSubgridRows()) {
+ const RenderGrid& parent = *downcast<RenderGrid>(gridContainer.parent());
+ GridTrackSizingDirection direction = GridLayoutFunctions::flowAwareDirectionForChild(parent, gridContainer, ForRows);
+ return parent.gridSpanForChild(gridContainer, direction).integerSpan();
+ }
+ return std::min<unsigned>(std::max(gridContainer.style().gridRows().size() + gridContainer.autoRepeatCountForDirection(ForRows), gridContainer.style().namedGridAreaRowCount()), GridPosition::max());
}
-static unsigned explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side, unsigned autoRepeatTracksCount)
+static unsigned explicitGridSizeForSide(const RenderGrid& gridContainer, GridPositionSide side)
{
- return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainerStyle, autoRepeatTracksCount) : GridPositionsResolver::explicitGridRowCount(gridContainerStyle, autoRepeatTracksCount);
+ return isColumnSide(side) ? GridPositionsResolver::explicitGridColumnCount(gridContainer) : GridPositionsResolver::explicitGridRowCount(gridContainer);
}
static unsigned lookAheadForNamedGridLine(int start, unsigned numberOfLines, unsigned gridLastLine, NamedLineCollection& linesCollection)
@@ -224,12 +258,12 @@
return start + 1;
}
-static int resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
+static int resolveNamedGridLinePositionFromStyle(const RenderGrid& gridContainer, const GridPosition& position, GridPositionSide side)
{
ASSERT(!position.namedGridLine().isNull());
- unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
- NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
+ unsigned lastLine = explicitGridSizeForSide(gridContainer, side);
+ NamedLineCollection linesCollection(gridContainer.style(), position.namedGridLine(), directionFromSide(side), lastLine, gridContainer.autoRepeatCountForDirection(directionFromSide(side)));
if (position.isPositive())
return lookAheadForNamedGridLine(0, std::abs(position.integerPosition()), lastLine, linesCollection);
@@ -250,7 +284,7 @@
return GridSpan::untranslatedDefiniteGridSpan(start, end);
}
-static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
+static GridSpan resolveNamedGridLinePositionAgainstOppositePosition(const RenderGrid& gridContainer, int oppositeLine, const GridPosition& position, GridPositionSide side)
{
ASSERT(position.isSpan());
ASSERT(!position.namedGridLine().isNull());
@@ -257,12 +291,12 @@
// Negative positions are not allowed per the specification and should have been handled during parsing.
ASSERT(position.spanPosition() > 0);
- unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
- NamedLineCollection linesCollection(gridContainerStyle, position.namedGridLine(), directionFromSide(side), lastLine, autoRepeatTracksCount);
+ unsigned lastLine = explicitGridSizeForSide(gridContainer, side);
+ NamedLineCollection linesCollection(gridContainer.style(), position.namedGridLine(), directionFromSide(side), lastLine, gridContainer.autoRepeatCountForDirection(directionFromSide(side)));
return definiteGridSpanWithNamedLineSpanAgainstOpposite(oppositeLine, position, side, lastLine, linesCollection);
}
-static GridSpan resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, int oppositeLine, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
+static GridSpan resolveGridPositionAgainstOppositePosition(const RenderGrid& gridContainer, int oppositeLine, const GridPosition& position, GridPositionSide side)
{
if (position.isAuto()) {
if (isStartSide(side))
@@ -275,7 +309,7 @@
if (!position.namedGridLine().isNull()) {
// span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
- return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, oppositeLine, position, side, autoRepeatTracksCount);
+ return resolveNamedGridLinePositionAgainstOppositePosition(gridContainer, oppositeLine, position, side);
}
// 'span 1' is contained inside a single grid track regardless of the direction.
@@ -315,7 +349,7 @@
return position.spanPosition();
}
-static int resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side, unsigned autoRepeatTracksCount)
+static int resolveGridPositionFromStyle(const RenderGrid& gridContainer, const GridPosition& position, GridPositionSide side)
{
switch (position.type()) {
case ExplicitPosition: {
@@ -322,7 +356,7 @@
ASSERT(position.integerPosition());
if (!position.namedGridLine().isNull())
- return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side, autoRepeatTracksCount);
+ return resolveNamedGridLinePositionFromStyle(gridContainer, position, side);
// Handle <integer> explicit position.
if (position.isPositive())
@@ -329,7 +363,7 @@
return position.integerPosition() - 1;
unsigned resolvedPosition = std::abs(position.integerPosition()) - 1;
- const unsigned endOfTrack = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
+ const unsigned endOfTrack = explicitGridSizeForSide(gridContainer, side);
return endOfTrack - resolvedPosition;
}
@@ -341,14 +375,14 @@
String namedGridLine = position.namedGridLine();
ASSERT(!position.namedGridLine().isNull());
- unsigned lastLine = explicitGridSizeForSide(gridContainerStyle, side, autoRepeatTracksCount);
- NamedLineCollection implicitLines(gridContainerStyle, implicitNamedGridLineForSide(namedGridLine, side), directionFromSide(side), lastLine, autoRepeatTracksCount);
+ unsigned lastLine = explicitGridSizeForSide(gridContainer, side);
+ NamedLineCollection implicitLines(gridContainer.style(), implicitNamedGridLineForSide(namedGridLine, side), directionFromSide(side), lastLine, gridContainer.autoRepeatCountForDirection(directionFromSide(side)));
if (implicitLines.hasNamedLines())
return implicitLines.firstPosition();
// Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
// item's placement.
- NamedLineCollection explicitLines(gridContainerStyle, namedGridLine, directionFromSide(side), lastLine, autoRepeatTracksCount);
+ NamedLineCollection explicitLines(gridContainer.style(), namedGridLine, directionFromSide(side), lastLine, gridContainer.autoRepeatCountForDirection(directionFromSide(side)));
if (explicitLines.hasNamedLines())
return explicitLines.firstPosition();
@@ -365,8 +399,11 @@
return 0;
}
-GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, unsigned autoRepeatTracksCount)
+GridSpan GridPositionsResolver::resolveGridPositionsFromStyle(const RenderBox& gridItem, GridTrackSizingDirection direction)
{
+ auto* gridContainer = downcast<RenderGrid>(gridItem.containingBlock());
+ ASSERT(gridContainer);
+
GridPosition initialPosition, finalPosition;
adjustGridPositionsFromStyle(gridItem, direction, initialPosition, finalPosition);
@@ -379,18 +416,18 @@
if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
// Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
- auto endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
- return resolveGridPositionAgainstOppositePosition(gridContainerStyle, endLine, initialPosition, initialSide, autoRepeatTracksCount);
+ auto endLine = resolveGridPositionFromStyle(*gridContainer, finalPosition, finalSide);
+ return resolveGridPositionAgainstOppositePosition(*gridContainer, endLine, initialPosition, initialSide);
}
if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
// Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
- auto startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
- return resolveGridPositionAgainstOppositePosition(gridContainerStyle, startLine, finalPosition, finalSide, autoRepeatTracksCount);
+ auto startLine = resolveGridPositionFromStyle(*gridContainer, initialPosition, initialSide);
+ return resolveGridPositionAgainstOppositePosition(*gridContainer, startLine, finalPosition, finalSide);
}
- int startLine = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialSide, autoRepeatTracksCount);
- int endLine = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalSide, autoRepeatTracksCount);
+ int startLine = resolveGridPositionFromStyle(*gridContainer, initialPosition, initialSide);
+ int endLine = resolveGridPositionFromStyle(*gridContainer, finalPosition, finalSide);
if (startLine > endLine)
std::swap(startLine, endLine);
Modified: trunk/Source/WebCore/rendering/style/GridPositionsResolver.h (289985 => 289986)
--- trunk/Source/WebCore/rendering/style/GridPositionsResolver.h 2022-02-17 01:25:59 UTC (rev 289985)
+++ trunk/Source/WebCore/rendering/style/GridPositionsResolver.h 2022-02-17 01:31:02 UTC (rev 289986)
@@ -36,6 +36,7 @@
class GridSpan;
class RenderBox;
+class RenderGrid;
class RenderStyle;
enum GridTrackSizingDirection {
@@ -73,9 +74,9 @@
static GridPositionSide initialPositionSide(GridTrackSizingDirection);
static GridPositionSide finalPositionSide(GridTrackSizingDirection);
static unsigned spanSizeForAutoPlacedItem(const RenderBox&, GridTrackSizingDirection);
- static GridSpan resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, unsigned autoRepeatTracksCount);
- static unsigned explicitGridColumnCount(const RenderStyle&, unsigned autoRepeatColumnsCount);
- static unsigned explicitGridRowCount(const RenderStyle&, unsigned autoRepeatRowsCount);
+ static GridSpan resolveGridPositionsFromStyle(const RenderBox&, GridTrackSizingDirection);
+ static unsigned explicitGridColumnCount(const RenderGrid&);
+ static unsigned explicitGridRowCount(const RenderGrid&);
};
} // namespace WebCore