Changeset 290077 in webkit


Ignore:
Timestamp:
Feb 17, 2022 2:53:52 PM (5 months ago)
Author:
Truitt Savell
Message:

Include sub grid items in the track sizing algorithm of the outer grid
https://bugs.webkit.org/show_bug.cgi?id=236337

Patch by Matt Woodrow <Matt Woodrow> on 2022-02-17
Reviewed by Dean Jackson.

Source/WebCore:

resolveIntrinsicTrackSizes and findUsedFlexFraction now recurse into subgridded items
to iterate the children sa if they were directly part of the outer grid.
New constructor added to GridIterator for constructing a new iterator for the subgrid items,
which adjusts the row/column indices into the local coordinate space of the subgrid.
Adds a new method to renderGrid 'placeItems' so that we can ensure subgrid items have finished placement
when doing sizing for the outer grid.

Existing test expectations updated.

  • rendering/Grid.cpp:

(WebCore::GridIterator::createForSubgrid):

  • rendering/Grid.h:

(WebCore::GridIterator::direction const):

  • rendering/GridTrackSizingAlgorithm.cpp:

(WebCore::GridTrackSizingAlgorithm::estimatedGridAreaBreadthForChild const):
(WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
(WebCore::GridTrackSizingAlgorithm::isIntrinsicSizedGridArea const):
(WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
(WebCore::GridTrackSizingAlgorithm::updateBaselineAlignmentContext):
(WebCore::GridTrackSizingAlgorithm::baselineOffsetForChild const):
(WebCore::IndefiniteSizeStrategy::accumulateFlexFraction const):
(WebCore::IndefiniteSizeStrategy::findUsedFlexFraction const):
(WebCore::GridTrackSizingAlgorithm::accumulateIntrinsicSizesForTrack):
(WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):

  • rendering/GridTrackSizingAlgorithm.h:
  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::placeItems):
(WebCore::insertIntoGrid):
(WebCore::RenderGrid::placeItemsOnGrid const):
(WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid const):
(WebCore::RenderGrid::placeAutoMajorAxisItemOnGrid const):
(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::isSubgridInParentDirection const):

  • rendering/RenderGrid.h:

LayoutTests:

Existing test expectations updated.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r290072 r290077  
     12022-02-17  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Include sub grid items in the track sizing algorithm of the outer grid
     4        https://bugs.webkit.org/show_bug.cgi?id=236337
     5
     6        Reviewed by Dean Jackson.
     7
     8        Existing test expectations updated.
     9
     10        * TestExpectations:
     11
    1122022-02-17  Jon Lee  <jonlee@apple.com>
    213
  • trunk/LayoutTests/TestExpectations

    r290038 r290077  
    14101410imported/w3c/web-platform-tests/css/css-grid/subgrid/item-percentage-height-001.html [ ImageOnlyFailure ]
    14111411imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-007.html [ ImageOnlyFailure ]
     1412imported/w3c/web-platform-tests/css/css-grid/subgrid/line-names-008.html [ ImageOnlyFailure ]
    14121413imported/w3c/web-platform-tests/css/css-grid/subgrid/orthogonal-writing-mode-001.html [ ImageOnlyFailure ]
    14131414imported/w3c/web-platform-tests/css/css-grid/subgrid/orthogonal-writing-mode-002.html [ ImageOnlyFailure ]
     
    14181419imported/w3c/web-platform-tests/css/css-grid/subgrid/repeat-auto-fill-003.html [ ImageOnlyFailure ]
    14191420imported/w3c/web-platform-tests/css/css-grid/subgrid/repeat-auto-fill-004.html [ ImageOnlyFailure ]
    1420 imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-item-block-size-001.html [ ImageOnlyFailure ]
    14211421imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-mbp-overflow-001.html [ ImageOnlyFailure ]
    14221422imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-mbp-overflow-002.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r290064 r290077  
     12022-02-17  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Include sub grid items in the track sizing algorithm of the outer grid
     4        https://bugs.webkit.org/show_bug.cgi?id=236337
     5
     6        Reviewed by Dean Jackson.
     7
     8        resolveIntrinsicTrackSizes and findUsedFlexFraction now recurse into subgridded items
     9        to iterate the children sa if they were directly part of the outer grid.
     10        New constructor added to GridIterator for constructing a new iterator for the subgrid items,
     11        which adjusts the row/column indices into the local coordinate space of the subgrid.
     12        Adds a new method to renderGrid 'placeItems' so that we can ensure subgrid items have finished placement
     13        when doing sizing for the outer grid.
     14
     15        Existing test expectations updated.
     16
     17        * rendering/Grid.cpp:
     18        (WebCore::GridIterator::createForSubgrid):
     19        * rendering/Grid.h:
     20        (WebCore::GridIterator::direction const):
     21        * rendering/GridTrackSizingAlgorithm.cpp:
     22        (WebCore::GridTrackSizingAlgorithm::estimatedGridAreaBreadthForChild const):
     23        (WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
     24        (WebCore::GridTrackSizingAlgorithm::isIntrinsicSizedGridArea const):
     25        (WebCore::GridTrackSizingAlgorithmStrategy::minSizeForChild const):
     26        (WebCore::GridTrackSizingAlgorithm::updateBaselineAlignmentContext):
     27        (WebCore::GridTrackSizingAlgorithm::baselineOffsetForChild const):
     28        (WebCore::IndefiniteSizeStrategy::accumulateFlexFraction const):
     29        (WebCore::IndefiniteSizeStrategy::findUsedFlexFraction const):
     30        (WebCore::GridTrackSizingAlgorithm::accumulateIntrinsicSizesForTrack):
     31        (WebCore::GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes):
     32        * rendering/GridTrackSizingAlgorithm.h:
     33        * rendering/RenderGrid.cpp:
     34        (WebCore::RenderGrid::placeItems):
     35        (WebCore::insertIntoGrid):
     36        (WebCore::RenderGrid::placeItemsOnGrid const):
     37        (WebCore::RenderGrid::placeSpecifiedMajorAxisItemsOnGrid const):
     38        (WebCore::RenderGrid::placeAutoMajorAxisItemOnGrid const):
     39        (WebCore::RenderGrid::layoutGridItems):
     40        (WebCore::RenderGrid::isSubgridInParentDirection const):
     41        * rendering/RenderGrid.h:
     42
    1432022-02-17  Alejandro G. Castro  <alex@igalia.com>
    244
  • trunk/Source/WebCore/rendering/Grid.cpp

    r289986 r290077  
    268268}
    269269
     270GridIterator GridIterator::createForSubgrid(const RenderGrid& subgrid, const GridIterator& outer)
     271{
     272    ASSERT(subgrid.isSubgridInParentDirection(outer.direction()));
     273    GridSpan fixedSpan = downcast<RenderGrid>(subgrid.parent())->gridSpanForChild(subgrid, outer.direction());
     274
     275    // Translate the current row/column indices into the coordinate
     276    // space of the subgrid.
     277    unsigned fixedIndex = (outer.direction() == ForColumns) ? outer.m_columnIndex : outer.m_rowIndex;
     278    fixedIndex -= fixedSpan.startLine();
     279
     280    GridTrackSizingDirection innerDirection = GridLayoutFunctions::flowAwareDirectionForChild(*downcast<RenderGrid>(subgrid.parent()), subgrid, outer.direction());
     281    ASSERT(subgrid.isSubgrid(innerDirection));
     282
     283    return GridIterator(subgrid.currentGrid(), innerDirection, fixedIndex);
     284}
     285
    270286} // namespace WebCore
  • trunk/Source/WebCore/rendering/Grid.h

    r289986 r290077  
    117117    GridIterator(const Grid&, GridTrackSizingDirection, unsigned fixedTrackIndex, unsigned varyingTrackIndex = 0);
    118118
     119    static GridIterator createForSubgrid(const RenderGrid& subgrid, const GridIterator& outer);
     120
    119121    RenderBox* nextGridItem();
    120122    bool isEmptyAreaEnough(unsigned rowSpan, unsigned columnSpan) const;
    121123    std::unique_ptr<GridArea> nextEmptyGridArea(unsigned fixedTrackSpan, unsigned varyingTrackSpan);
     124
     125    GridTrackSizingDirection direction() const
     126    {
     127        return m_direction;
     128    }
    122129
    123130private:
  • trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp

    r290007 r290077  
    588588std::optional<LayoutUnit> GridTrackSizingAlgorithm::estimatedGridAreaBreadthForChild(const RenderBox& child, GridTrackSizingDirection direction) const
    589589{
    590     const GridSpan& span = m_grid.gridItemSpan(child, direction);
     590    const GridSpan& span = m_renderGrid->gridSpanForChild(child, direction);
    591591    LayoutUnit gridAreaSize;
    592592    bool gridAreaIsIndefinite = false;
     
    629629
    630630    const Vector<GridTrack>& allTracks = tracks(direction);
    631     const GridSpan& span = m_grid.gridItemSpan(child, direction);
     631    const GridSpan& span = m_renderGrid->gridSpanForChild(child, direction);
    632632    LayoutUnit gridAreaBreadth;
    633633    for (auto trackPosition : span)
     
    651651    ASSERT(wasSetup());
    652652    GridTrackSizingDirection direction = gridDirectionForAxis(axis);
    653     const GridSpan& span = m_grid.gridItemSpan(child, direction);
     653    const GridSpan& span = m_renderGrid->gridSpanForChild(child, direction);
    654654    for (auto trackPosition : span) {
    655655        const auto& trackSize = rawGridTrackSize(direction, trackPosition);
     
    860860    if (childMinSize.isAuto() && overflowIsVisible) {
    861861        auto minSize = minContentForChild(child);
    862         const GridSpan& span = m_algorithm.grid().gridItemSpan(child, direction());
     862        const GridSpan& span = m_algorithm.m_renderGrid->gridSpanForChild(child, direction());
    863863
    864864        LayoutUnit maxBreadth;
     
    919919
    920920    ItemPosition align = m_renderGrid->selfAlignmentForChild(baselineAxis, child).position();
    921     const auto& span = m_grid.gridItemSpan(child, gridDirectionForAxis(baselineAxis));
     921    const auto& span = m_renderGrid->gridSpanForChild(child, gridDirectionForAxis(baselineAxis));
    922922    m_baselineAlignment.updateBaselineAlignmentContext(align, span.startLine(), child, baselineAxis);
    923923}
     
    929929
    930930    ItemPosition align = m_renderGrid->selfAlignmentForChild(baselineAxis, child).position();
    931     const auto& span = m_grid.gridItemSpan(child, gridDirectionForAxis(baselineAxis));
     931    const auto& span = m_renderGrid->gridSpanForChild(child, gridDirectionForAxis(baselineAxis));
    932932    return m_baselineAlignment.baselineOffsetForChild(align, span.startLine(), child, baselineAxis);
    933933}
     
    991991    LayoutUnit freeSpaceForStretchAutoTracksStep() const override;
    992992    bool isComputingSizeContainment() const override { return shouldApplySizeContainment(*renderGrid()); }
     993    void accumulateFlexFraction(double& flexFraction, GridIterator&, GridTrackSizingDirection outermostDirection, HashSet<RenderBox*>& itemsSet) const;
    993994};
    994995
     
    10121013    double flexFactor = track.cachedTrackSize().maxTrackBreadth().flex();
    10131014    return track.baseSize() / std::max<double>(1, flexFactor);
     1015}
     1016
     1017void IndefiniteSizeStrategy::accumulateFlexFraction(double& flexFraction, GridIterator& iterator, GridTrackSizingDirection outermostDirection, HashSet<RenderBox*>& itemsSet) const
     1018{
     1019    while (auto* gridItem = iterator.nextGridItem()) {
     1020        if (is<RenderGrid>(gridItem) && downcast<RenderGrid>(gridItem)->isSubgridInParentDirection(iterator.direction())) {
     1021            RenderGrid* inner = downcast<RenderGrid>(gridItem);
     1022
     1023            GridIterator childIterator = GridIterator::createForSubgrid(*inner, iterator);
     1024            accumulateFlexFraction(flexFraction, childIterator, outermostDirection, itemsSet);
     1025            continue;
     1026        }
     1027        // Do not include already processed items.
     1028        if (!itemsSet.add(gridItem).isNewEntry)
     1029            continue;
     1030
     1031        GridSpan span = m_algorithm.renderGrid()->gridSpanForChild(*gridItem, outermostDirection);
     1032
     1033        // Removing gutters from the max-content contribution of the item, so they are not taken into account in FindFrUnitSize().
     1034        LayoutUnit leftOverSpace = maxContentForChild(*gridItem) - renderGrid()->guttersSize(m_algorithm.grid(), outermostDirection, span.startLine(), span.integerSpan(), availableSpace());
     1035        flexFraction = std::max(flexFraction, findFrUnitSize(span, leftOverSpace));
     1036    }
    10141037}
    10151038
     
    10331056    for (const auto& trackIndex : flexibleSizedTracksIndex) {
    10341057        GridIterator iterator(grid, direction, trackIndex);
    1035         while (auto* gridItem = iterator.nextGridItem()) {
    1036             // Do not include already processed items.
    1037             if (!itemsSet.add(gridItem).isNewEntry)
    1038                 continue;
    1039 
    1040             const GridSpan& span = grid.gridItemSpan(*gridItem, direction);
    1041 
    1042             // Removing gutters from the max-content contribution of the item, so they are not taken into account in FindFrUnitSize().
    1043             LayoutUnit leftOverSpace = maxContentForChild(*gridItem) - renderGrid()->guttersSize(m_algorithm.grid(), direction, span.startLine(), span.integerSpan(), availableSpace());
    1044             flexFraction = std::max(flexFraction, findFrUnitSize(span, leftOverSpace));
    1045         }
     1058        accumulateFlexFraction(flexFraction, iterator, direction, itemsSet);
    10461059    }
    10471060
     
    12101223}
    12111224
     1225void GridTrackSizingAlgorithm::accumulateIntrinsicSizesForTrack(GridTrack& track, GridIterator& iterator, Vector<GridItemWithSpan>& itemsSortedByIncreasingSpan, Vector<GridItemWithSpan>& itemsCrossingFlexibleTracks, HashSet<RenderBox*>& itemsSet)
     1226{
     1227    while (auto* gridItem = iterator.nextGridItem()) {
     1228        bool isNewEntry = itemsSet.add(gridItem).isNewEntry;
     1229        if (is<RenderGrid>(gridItem) && downcast<RenderGrid>(gridItem)->isSubgridInParentDirection(iterator.direction())) {
     1230            RenderGrid* inner = downcast<RenderGrid>(gridItem);
     1231
     1232            GridIterator childIterator = GridIterator::createForSubgrid(*inner, iterator);
     1233            accumulateIntrinsicSizesForTrack(track, childIterator, itemsSortedByIncreasingSpan, itemsCrossingFlexibleTracks, itemsSet);
     1234            continue;
     1235        }
     1236        if (!isNewEntry)
     1237            continue;
     1238        GridSpan span = m_renderGrid->gridSpanForChild(*gridItem, m_direction);
     1239
     1240        if (spanningItemCrossesFlexibleSizedTracks(span))
     1241            itemsCrossingFlexibleTracks.append(GridItemWithSpan(*gridItem, span));
     1242        else if (span.integerSpan() == 1)
     1243            sizeTrackToFitNonSpanningItem(span, *gridItem, track);
     1244        else
     1245            itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
     1246    }
     1247}
     1248
    12121249void GridTrackSizingAlgorithm::resolveIntrinsicTrackSizes()
    12131250{
     
    12291266    Vector<GridItemWithSpan> itemsCrossingFlexibleTracks;
    12301267    HashSet<RenderBox*> itemsSet;
     1268
    12311269    if (m_grid.hasGridItems()) {
    12321270        for (auto trackIndex : m_contentSizedTracksIndex) {
     
    12341272            GridTrack& track = allTracks[trackIndex];
    12351273
    1236             while (auto* gridItem = iterator.nextGridItem()) {
    1237                 if (itemsSet.add(gridItem).isNewEntry) {
    1238                     const GridSpan& span = m_grid.gridItemSpan(*gridItem, m_direction);
    1239                     if (spanningItemCrossesFlexibleSizedTracks(span))
    1240                         itemsCrossingFlexibleTracks.append(GridItemWithSpan(*gridItem, span));
    1241                     else if (span.integerSpan() == 1)
    1242                         sizeTrackToFitNonSpanningItem(span, *gridItem, track);
    1243                     else
    1244                         itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, span));
    1245                 }
    1246             }
     1274            accumulateIntrinsicSizesForTrack(track, iterator, itemsSortedByIncreasingSpan, itemsCrossingFlexibleTracks, itemsSet);
    12471275        }
    12481276        std::sort(itemsSortedByIncreasingSpan.begin(), itemsSortedByIncreasingSpan.end());
  • trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h

    r290007 r290077  
    5656
    5757class GridTrackSizingAlgorithmStrategy;
     58class GridItemWithSpan;
    5859
    5960class GridTrack {
     
    121122    // and encapsulate any access in the algorithm class.
    122123    Grid& mutableGrid() const { return m_grid; }
     124
     125    const RenderGrid* renderGrid() { return m_renderGrid; };
    123126
    124127    LayoutUnit minContentSize() const { return m_minContentSize; };
     
    194197    void stretchAutoTracks();
    195198
     199    void accumulateIntrinsicSizesForTrack(GridTrack&, GridIterator&, Vector<GridItemWithSpan>& itemsSortedByIncreasingSpan, Vector<GridItemWithSpan>& itemsCrossingFlexibleTracks, HashSet<RenderBox*>& itemsSet);
     200
    196201    bool copyUsedTrackSizesForSubgrid();
    197202
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r290032 r290077  
    648648}
    649649
     650void RenderGrid::placeItems()
     651{
     652    updateLogicalWidth();
     653
     654    LayoutUnit availableSpaceForColumns = availableLogicalWidth();
     655    placeItemsOnGrid(m_trackSizingAlgorithm, availableSpaceForColumns);
     656}
     657
     658static GridArea insertIntoGrid(Grid& grid, RenderBox& child, const GridArea& area)
     659{
     660    GridArea clamped = grid.insert(child, area);
     661    if (!is<RenderGrid>(child))
     662        return clamped;
     663
     664    RenderGrid& renderGrid = downcast<RenderGrid>(child);
     665    if (renderGrid.isSubgridRows() || renderGrid.isSubgridColumns())
     666        renderGrid.placeItems();
     667    return clamped;
     668}
     669
    650670// FIXME: We shouldn't have to pass the available logical width as argument. The problem is that
    651671// availableLogicalWidth() does always return a value even if we cannot resolve it like when
     
    701721            continue;
    702722        }
    703         grid.insert(*child, { area.rows, area.columns });
     723        insertIntoGrid(grid, *child, { area.rows, area.columns });
    704724    }
    705725
     
    831851            emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(grid, *autoGridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
    832852
    833         *emptyGridArea = grid.insert(*autoGridItem, *emptyGridArea);
     853        *emptyGridArea = insertIntoGrid(grid, *autoGridItem, *emptyGridArea);
    834854
    835855        if (!isGridAutoFlowDense)
     
    903923    }
    904924
    905     grid.insert(gridItem, *emptyGridArea);
     925    *emptyGridArea = insertIntoGrid(grid, gridItem, *emptyGridArea);
    906926    autoPlacementCursor.first = emptyGridArea->rows.startLine();
    907927    autoPlacementCursor.second = emptyGridArea->columns.startLine();
     
    10161036
    10171037    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    1018        
    10191038        if (m_grid.orderIterator().shouldSkipChild(*child)) {
    10201039            if (child->isOutOfFlowPositioned())
     
    10221041            continue;
    10231042        }
     1043
     1044        if (is<RenderGrid>(child) && (downcast<RenderGrid>(child)->isSubgridColumns() || downcast<RenderGrid>(child)->isSubgridRows()))
     1045            child->setNeedsLayout(MarkOnlyThis);
    10241046
    10251047        // Setting the definite grid area's sizes. It may imply that the
     
    16371659        return false;
    16381660    return is<RenderGrid>(parent());
     1661}
     1662
     1663bool RenderGrid::isSubgridInParentDirection(GridTrackSizingDirection parentDirection) const
     1664{
     1665    if (!is<RenderGrid>(parent()))
     1666        return false;
     1667    GridTrackSizingDirection direction = GridLayoutFunctions::flowAwareDirectionForChild(*downcast<RenderGrid>(parent()), *this, parentDirection);
     1668    return isSubgrid(direction);
    16391669}
    16401670
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r290007 r290077  
    9696        return isSubgrid(ForColumns);
    9797    }
     98    bool isSubgridInParentDirection(GridTrackSizingDirection parentDirection) const;
    9899
    99100    const Grid& currentGrid() const
     
    106107        return numTracks(direction, m_grid);
    107108    }
     109
     110    void placeItems();
    108111
    109112private:
Note: See TracChangeset for help on using the changeset viewer.