Changeset 292524 in webkit


Ignore:
Timestamp:
Apr 7, 2022 12:11:27 AM (3 months ago)
Author:
Matt Woodrow
Message:

Grid items that establish an independent formatting context should not be subgrids.
https://bugs.webkit.org/show_bug.cgi?id=237692

Reviewed by Alan Bujtas.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-grid/subgrid/abs-pos-003-expected.html: Removed.
  • web-platform-tests/css/css-grid/subgrid/abs-pos-003.html: Removed.
  • web-platform-tests/css/css-grid/subgrid/abs-pos-004-expected.html: Removed.
  • web-platform-tests/css/css-grid/subgrid/abs-pos-004.html: Removed.
  • web-platform-tests/css/css-grid/subgrid/independent-formatting-context-expected.html: Added.
  • web-platform-tests/css/css-grid/subgrid/independent-formatting-context.html: Added.

Removes tests that expect position:absolute combined with grid-template-X: subgrid to work.
Adds new test to confirm that elements that establish an independent formatting context can't
also be a subgrid.

Source/WebCore:

New WPT css/css-grid/subgrid/independent-formatting-context.html added to check this case.

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::createsNewFormattingContext const):

  • rendering/RenderBox.h:

(WebCore::RenderBox::markForPaginationRelayoutIfNeeded):
(WebCore::RenderBox::isWritingModeRoot const): Deleted.
(WebCore::RenderBox::isDeprecatedFlexItem const): Deleted.
(WebCore::RenderBox::isFlexItemIncludingDeprecated const): Deleted.

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::createsNewFormattingContext const):

  • rendering/RenderElement.h:

(WebCore::RenderElement::isWritingModeRoot const):
(WebCore::RenderElement::isDeprecatedFlexItem const):
(WebCore::RenderElement::isFlexItemIncludingDeprecated const):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::isBlockContainer const):

  • rendering/RenderObject.h:

Grid items establish a new formatting context, unless they're a subgrid [1], but subgrid
is disabled if any other property causes the element to establish a formatting context [2].
Adds a new helper to check everything except grid, so that we can resolve this without
infinite recursion.
Stops writing-mode changes from establishing an independent formatting context if
the box is a grid container, since this should only happen is the box is a block
container [3].
Adds new helper for isBlockContainer, since writing-mode changes use it.

[1] https://drafts.csswg.org/css-grid-2/#grid-item-display
[2] https://drafts.csswg.org/css-grid-2/#subgrid-listing
[3] https://drafts.csswg.org/css-writing-modes/#block-flow

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::isSubgrid const):
(WebCore::RenderGrid::createsNewFormattingContext const):
(WebCore::RenderGrid::mayBeSubgridExcludingAbsPos const): Deleted.
(WebCore::RenderGrid::gridSpanCoversRealTracks const): Deleted.

  • rendering/RenderGrid.h:
  • rendering/style/GridPositionsResolver.cpp:

(WebCore::adjustGridPositionsFromStyle):

Makes isSubgrid return false if the element establishes an independent formatting context
(excluding contexts established by being a grid item), and removes no longer needed code
for handling position:absolute subgrids.

Location:
trunk
Files:
2 added
4 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r292523 r292524  
     12022-04-07  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Grid items that establish an independent formatting context should not be subgrids.
     4        https://bugs.webkit.org/show_bug.cgi?id=237692
     5
     6        Reviewed by Alan Bujtas.
     7
     8        * web-platform-tests/css/css-grid/subgrid/abs-pos-003-expected.html: Removed.
     9        * web-platform-tests/css/css-grid/subgrid/abs-pos-003.html: Removed.
     10        * web-platform-tests/css/css-grid/subgrid/abs-pos-004-expected.html: Removed.
     11        * web-platform-tests/css/css-grid/subgrid/abs-pos-004.html: Removed.
     12        * web-platform-tests/css/css-grid/subgrid/independent-formatting-context-expected.html: Added.
     13        * web-platform-tests/css/css-grid/subgrid/independent-formatting-context.html: Added.
     14
     15        Removes tests that expect position:absolute combined with grid-template-X: subgrid to work.
     16        Adds new test to confirm that elements that establish an independent formatting context can't
     17        also be a subgrid.
     18
    1192022-04-06  Tim Nguyen  <ntim@apple.com>
    220
  • trunk/Source/WebCore/ChangeLog

    r292523 r292524  
     12022-04-07  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Grid items that establish an independent formatting context should not be subgrids.
     4        https://bugs.webkit.org/show_bug.cgi?id=237692
     5
     6        Reviewed by Alan Bujtas.
     7
     8        New WPT css/css-grid/subgrid/independent-formatting-context.html added to check this case.
     9
     10        * rendering/RenderBox.cpp:
     11        (WebCore::RenderBox::createsNewFormattingContext const):
     12        * rendering/RenderBox.h:
     13        (WebCore::RenderBox::markForPaginationRelayoutIfNeeded):
     14        (WebCore::RenderBox::isWritingModeRoot const): Deleted.
     15        (WebCore::RenderBox::isDeprecatedFlexItem const): Deleted.
     16        (WebCore::RenderBox::isFlexItemIncludingDeprecated const): Deleted.
     17        * rendering/RenderElement.cpp:
     18        (WebCore::RenderElement::createsNewFormattingContext const):
     19        * rendering/RenderElement.h:
     20        (WebCore::RenderElement::isWritingModeRoot const):
     21        (WebCore::RenderElement::isDeprecatedFlexItem const):
     22        (WebCore::RenderElement::isFlexItemIncludingDeprecated const):
     23        * rendering/RenderObject.cpp:
     24        (WebCore::RenderObject::isBlockContainer const):
     25        * rendering/RenderObject.h:
     26
     27        Grid items establish a new formatting context, unless they're a subgrid [1], but subgrid
     28        is disabled if any other property causes the element to establish a formatting context [2].
     29        Adds a new helper to check everything except grid, so that we can resolve this without
     30        infinite recursion.
     31        Stops writing-mode changes from establishing an independent formatting context if
     32        the box is a grid container, since this should only happen is the box is a block
     33        container [3].
     34        Adds new helper for isBlockContainer, since writing-mode changes use it.
     35
     36        [1] https://drafts.csswg.org/css-grid-2/#grid-item-display
     37        [2] https://drafts.csswg.org/css-grid-2/#subgrid-listing
     38        [3] https://drafts.csswg.org/css-writing-modes/#block-flow
     39
     40        * rendering/RenderGrid.cpp:
     41        (WebCore::RenderGrid::isSubgrid const):
     42        (WebCore::RenderGrid::createsNewFormattingContext const):
     43        (WebCore::RenderGrid::mayBeSubgridExcludingAbsPos const): Deleted.
     44        (WebCore::RenderGrid::gridSpanCoversRealTracks const): Deleted.
     45        * rendering/RenderGrid.h:
     46        * rendering/style/GridPositionsResolver.cpp:
     47        (WebCore::adjustGridPositionsFromStyle):
     48
     49        Makes isSubgrid return false if the element establishes an independent formatting context
     50        (excluding contexts established by being a grid item), and removes no longer needed code
     51        for handling position:absolute subgrids.
     52
    1532022-04-06  Tim Nguyen  <ntim@apple.com>
    254
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r292157 r292524  
    49454945}
    49464946
    4947 bool RenderBox::createsNewFormattingContext() const
    4948 {
    4949     return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasPotentiallyScrollableOverflow() || isFlexItemIncludingDeprecated()
    4950         || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isDocumentElementRenderer() || isRenderFragmentedFlow()
    4951         || style().containsLayout() || paintContainmentApplies() || isGridItem() || style().specifiesColumns() || style().columnSpan() == ColumnSpan::All || style().display() == DisplayType::FlowRoot;
     4947bool RenderBox::establishesIndependentFormattingContext() const
     4948{
     4949    return isGridItem() || RenderElement::establishesIndependentFormattingContext();
    49524950}
    49534951
  • trunk/Source/WebCore/rendering/RenderBox.h

    r290225 r292524  
    572572
    573573    virtual void markForPaginationRelayoutIfNeeded() { }
    574 
    575     bool isWritingModeRoot() const { return !parent() || parent()->style().writingMode() != style().writingMode(); }
    576 
    577     bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isDeprecatedFlexibleBox(); }
    578     bool isFlexItemIncludingDeprecated() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBoxIncludingDeprecated(); }
    579574   
    580575    LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
     
    684679    void willBeDestroyed() override;
    685680
    686     bool createsNewFormattingContext() const;
     681    bool establishesIndependentFormattingContext() const override;
    687682
    688683    virtual bool shouldResetLogicalHeightBeforeLayout() const { return false; }
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r291548 r292524  
    23902390}
    23912391
    2392 }
     2392bool RenderElement::createsNewFormattingContext() const
     2393{
     2394    // Writing-mode changes establish an independent block formatting context
     2395    // if the box is a block-container.
     2396    // https://drafts.csswg.org/css-writing-modes/#block-flow
     2397    if (isWritingModeRoot() && isBlockContainer())
     2398        return true;
     2399    return isInlineBlockOrInlineTable() || isFlexItemIncludingDeprecated()
     2400        || isTableCell() || isTableCaption() || isFieldset() || isDocumentElementRenderer() || isRenderFragmentedFlow()
     2401        || style().specifiesColumns() || style().columnSpan() == ColumnSpan::All || style().display() == DisplayType::FlowRoot || establishesIndependentFormattingContext();
     2402}
     2403
     2404bool RenderElement::establishesIndependentFormattingContext() const
     2405{
     2406    return isFloatingOrOutOfFlowPositioned() || hasPotentiallyScrollableOverflow() || style().containsLayout() || paintContainmentApplies();
     2407}
     2408
     2409
     2410}
  • trunk/Source/WebCore/rendering/RenderElement.h

    r290867 r292524  
    272272    Overflow effectiveOverflowBlockDirection() const { return style().isHorizontalWritingMode() ? effectiveOverflowY() : effectiveOverflowX(); }
    273273
     274    bool isWritingModeRoot() const { return !parent() || parent()->style().writingMode() != style().writingMode(); }
     275
     276    bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isDeprecatedFlexibleBox(); }
     277    bool isFlexItemIncludingDeprecated() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBoxIncludingDeprecated(); }
     278
    274279protected:
    275280    enum BaseTypeFlag {
     
    328333    bool isVisibleInViewport() const;
    329334
     335    bool createsNewFormattingContext() const;
     336    virtual bool establishesIndependentFormattingContext() const;
     337
    330338private:
    331339    RenderElement(ContainerNode&, RenderStyle&&, BaseTypeFlags);
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r292465 r292524  
    226226        }
    227227
    228         // We keep a cache of items with baseline as alignment values so that we only compute the baseline shims for
     228        // We keep a cache of items with baseline as aligcnment values so that we only compute the baseline shims for
    229229        // such items. This cache is needed for performance related reasons due to the cost of evaluating the item's
    230230        // participation in a baseline context during the track sizing algorithm.
     
    16541654bool RenderGrid::isSubgrid(GridTrackSizingDirection direction) const
    16551655{
    1656     if (!mayBeSubgridExcludingAbsPos(direction))
    1657         return false;
    1658     return downcast<RenderGrid>(parent())->gridSpanCoversRealTracks(*this, direction);
    1659 }
    1660 
    1661 bool RenderGrid::isSubgridInParentDirection(GridTrackSizingDirection parentDirection) const
    1662 {
    1663     if (!is<RenderGrid>(parent()))
    1664         return false;
    1665     GridTrackSizingDirection direction = GridLayoutFunctions::flowAwareDirectionForChild(*downcast<RenderGrid>(parent()), *this, parentDirection);
    1666     return isSubgrid(direction);
    1667 }
    1668 
    1669 bool RenderGrid::isSubgridOf(GridTrackSizingDirection direction, const RenderGrid& ancestor)
    1670 {
    1671     if (!isSubgrid(direction))
    1672         return false;
    1673     if (parent() == &ancestor)
    1674         return true;
    1675 
    1676     auto& parentGrid = *downcast<RenderGrid>(parent());
    1677     GridTrackSizingDirection parentDirection = GridLayoutFunctions::flowAwareDirectionForParent(parentGrid, *this, direction);
    1678     return parentGrid.isSubgridOf(parentDirection, ancestor);
    1679 }
    1680 
    1681 bool RenderGrid::mayBeSubgridExcludingAbsPos(GridTrackSizingDirection direction) const
    1682 {
    1683     // Should exclude cases where we establish an IFC, like contain layout.
    1684     if (isExcludedFromNormalLayout())
     1656    // If the grid container is forced to establish an independent formatting
     1657    // context (like contain layout, or position:absolute), then the used value
     1658    // of grid-template-rows/columns is 'none' and the container is not a subgrid.
     1659    // https://drafts.csswg.org/css-grid-2/#subgrid-listing
     1660    if (RenderElement::establishesIndependentFormattingContext())
    16851661        return false;
    16861662    if (direction == ForColumns ? !style().gridSubgridColumns() : !style().gridSubgridRows())
     
    16891665        return false;
    16901666    return true;
     1667}
     1668
     1669bool RenderGrid::isSubgridInParentDirection(GridTrackSizingDirection parentDirection) const
     1670{
     1671    if (!is<RenderGrid>(parent()))
     1672        return false;
     1673    GridTrackSizingDirection direction = GridLayoutFunctions::flowAwareDirectionForChild(*downcast<RenderGrid>(parent()), *this, parentDirection);
     1674    return isSubgrid(direction);
     1675}
     1676
     1677bool RenderGrid::isSubgridOf(GridTrackSizingDirection direction, const RenderGrid& ancestor)
     1678{
     1679    if (!isSubgrid(direction))
     1680        return false;
     1681    if (parent() == &ancestor)
     1682        return true;
     1683
     1684    auto& parentGrid = *downcast<RenderGrid>(parent());
     1685    GridTrackSizingDirection parentDirection = GridLayoutFunctions::flowAwareDirectionForParent(parentGrid, *this, direction);
     1686    return parentGrid.isSubgridOf(parentDirection, ancestor);
    16911687}
    16921688
     
    21082104}
    21092105
    2110 bool RenderGrid::gridSpanCoversRealTracks(const RenderBox& child, GridTrackSizingDirection direction) const
    2111 {
    2112     // Only out of flow positioned items can span to the special line that covers
    2113     // the padding area.
    2114     if (!child.isOutOfFlowPositioned())
    2115         return true;
    2116 
    2117     int lastLine = numTracks(direction, m_grid);
    2118     int startLine, endLine;
    2119     bool startIsAuto, endIsAuto;
    2120     if (!computeGridPositionsForOutOfFlowChild(child, direction, startLine, startIsAuto, endLine, endIsAuto))
    2121         return lastLine > 0;
    2122 
    2123     // If the resulting span covers only the padding area, then it's not a real
    2124     // track that could be used for a subgrid.
    2125     if (startIsAuto && !endLine)
    2126         return false;
    2127     if (endIsAuto && startLine == lastLine)
    2128         return false;
    2129     return true;
     2106bool RenderGrid::establishesIndependentFormattingContext() const
     2107{
     2108    // Grid items establish a new independent formatting context, unless
     2109    // they're a subgrid
     2110    // https://drafts.csswg.org/css-grid-2/#grid-item-display
     2111    if (isGridItem()) {
     2112        if (!isSubgridRows() && !isSubgridColumns())
     2113            return true;
     2114    }
     2115    return RenderElement::establishesIndependentFormattingContext();
    21302116}
    21312117
  • trunk/Source/WebCore/rendering/RenderGrid.h

    r292079 r292524  
    103103    bool isSubgridOf(GridTrackSizingDirection, const RenderGrid& ancestor);
    104104
    105     bool mayBeSubgridExcludingAbsPos(GridTrackSizingDirection) const;
    106 
    107105    const Grid& currentGrid() const
    108106    {
     
    221219
    222220    bool shouldResetLogicalHeightBeforeLayout() const override { return true; }
     221    bool establishesIndependentFormattingContext() const override;
    223222
    224223    bool aspectRatioPrefersInline(const RenderBox& child, bool blockFlowIsColumnAxis);
     
    229228
    230229    bool computeGridPositionsForOutOfFlowChild(const RenderBox&, GridTrackSizingDirection, int&, bool&, int&, bool&) const;
    231     bool gridSpanCoversRealTracks(const RenderBox&, GridTrackSizingDirection) const;
    232230
    233231    Grid m_grid;
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r292228 r292524  
    196196}
    197197
     198bool RenderObject::isBlockContainer() const
     199{
     200    auto display = style().display();
     201    return (display == DisplayType::Block
     202        || display == DisplayType::InlineBlock
     203        || display == DisplayType::FlowRoot
     204        || display == DisplayType::ListItem
     205        || display == DisplayType::TableCell
     206        || display == DisplayType::TableCaption) && !isRenderReplaced();
     207}
     208
    198209void RenderObject::setFragmentedFlowStateIncludingDescendants(FragmentedFlowState state, const RenderElement* fragmentedFlowRoot)
    199210{
  • trunk/Source/WebCore/rendering/RenderObject.h

    r291992 r292524  
    388388    bool isAnonymous() const { return m_bitfields.isAnonymous(); }
    389389    bool isAnonymousBlock() const;
     390    bool isBlockContainer() const;
    390391
    391392    bool isFloating() const { return m_bitfields.floating(); }
  • trunk/Source/WebCore/rendering/style/GridPositionsResolver.cpp

    r292221 r292524  
    381381        initialPosition.setSpanPosition(1, String());
    382382
    383     // Absolutely positioned items specifying subgrid might not actually be a subgrid if their grid
    384     // span doesn't cover any tracks and only the padding area. We don't know if that is the case until
    385     // we've figured out their grid position though, which is what we're trying to do now.
    386     if (isIndefiniteSpan(initialPosition, finalPosition) && is<RenderGrid>(gridItem) && downcast<RenderGrid>(gridItem).mayBeSubgridExcludingAbsPos(direction)) {
     383    if (isIndefiniteSpan(initialPosition, finalPosition) && is<RenderGrid>(gridItem) && downcast<RenderGrid>(gridItem).isSubgrid(direction)) {
    387384        // Indefinite span for an item that is subgridded in this axis.
    388385        int lineCount = (isForColumns ? gridItem.style().orderedNamedGridColumnLines() : gridItem.style().orderedNamedGridRowLines()).size();
Note: See TracChangeset for help on using the changeset viewer.