⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276235 in webkit


Ignore:
Timestamp:
Apr 18, 2021, 11:13:38 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Support contain: layout
https://bugs.webkit.org/show_bug.cgi?id=223569

Patch by Rob Buis <rbuis@igalia.com> on 2021-04-18
Reviewed by Darin Adler.

Source/WebCore:

This patch implements layout containment as specified[1].
It adds shouldApplyLayoutContainment to check whether the
element applies for layout containment. Is so, then:

  • an independent formatting context is established.
  • any overflow is treated as ink overflow.
  • an absolute positioning and fixed positioning

containing block is established.

  • a stacking context is created.
  • for baseline handling, the box is treated as having no

baseline. For grid/flexible box containers/items, this needs
a baseline synthesized from the border edges [2], for buttons it
requires a baseline synthesized from the margin edges [2, 3].

[1] https://drafts.csswg.org/css-contain-2/#layout-containment
[2] https://drafts.csswg.org/css-align-3/#synthesize-baseline
[3] https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::firstLineBaseline const):
(WebCore::RenderBlock::inlineBlockBaseline const):

  • rendering/RenderBlockFlow.cpp:

(WebCore::RenderBlockFlow::firstLineBaseline const):
(WebCore::RenderBlockFlow::inlineBlockBaseline const):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::createsNewFormattingContext const):
(WebCore::RenderBox::layoutOverflowRectForPropagation const):

  • rendering/RenderBox.h:
  • rendering/RenderButton.cpp:

(WebCore::RenderButton::baselinePosition const):

  • rendering/RenderElement.h:

(WebCore::RenderElement::canContainFixedPositionObjects const):
(WebCore::RenderElement::canContainAbsolutelyPositionedObjects const):

  • rendering/RenderFlexibleBox.cpp:

(WebCore::RenderFlexibleBox::firstLineBaseline const):

  • rendering/RenderGrid.cpp:

(WebCore::RenderGrid::firstLineBaseline const):

  • rendering/RenderListBox.cpp:

(WebCore::RenderListBox::baselinePosition const):

  • rendering/RenderObject.cpp:

(WebCore::objectIsRelayoutBoundary):
(WebCore::shouldApplyLayoutContainment):

  • rendering/RenderObject.h:

(WebCore::RenderObject::isAtomicInlineLevelBox const):

  • rendering/RenderTable.cpp:

(WebCore::RenderTable::firstLineBaseline const):

  • rendering/style/RenderStyle.h:

(WebCore::RenderStyle::containsLayout const):

  • style/StyleAdjuster.cpp:

(WebCore::Style::Adjuster::adjust const):

LayoutTests:

Unskip tests that pass now.

Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r276234 r276235  
     12021-04-18  Rob Buis  <rbuis@igalia.com>
     2
     3        Support contain: layout
     4        https://bugs.webkit.org/show_bug.cgi?id=223569
     5
     6        Reviewed by Darin Adler.
     7
     8        Unskip tests that pass now.
     9
     10        * TestExpectations:
     11
    1122021-04-18  Diego Pino Garcia  <dpino@igalia.com>
    213
  • trunk/LayoutTests/TestExpectations

    r276216 r276235  
    46794679# CSS containment tests that fail
    46804680imported/w3c/web-platform-tests/css/css-contain/contain-animation-001.html [ ImageOnlyFailure ]
    4681 imported/w3c/web-platform-tests/css/css-contain/contain-content-001.html [ ImageOnlyFailure ]
    4682 imported/w3c/web-platform-tests/css/css-contain/contain-content-002.html [ ImageOnlyFailure ]
    4683 imported/w3c/web-platform-tests/css/css-contain/contain-content-003.html [ ImageOnlyFailure ]
    4684 imported/w3c/web-platform-tests/css/css-contain/contain-content-004.html [ ImageOnlyFailure ]
    4685 imported/w3c/web-platform-tests/css/css-contain/contain-content-011.html [ ImageOnlyFailure ]
    4686 imported/w3c/web-platform-tests/css/css-contain/contain-layout-006.html [ ImageOnlyFailure ]
    4687 imported/w3c/web-platform-tests/css/css-contain/contain-layout-007.html [ ImageOnlyFailure ]
    4688 imported/w3c/web-platform-tests/css/css-contain/contain-layout-013.html [ ImageOnlyFailure ]
    4689 imported/w3c/web-platform-tests/css/css-contain/contain-layout-014.html [ ImageOnlyFailure ]
    4690 imported/w3c/web-platform-tests/css/css-contain/contain-layout-016.html [ ImageOnlyFailure ]
    4691 imported/w3c/web-platform-tests/css/css-contain/contain-layout-baseline-001.html [ ImageOnlyFailure ]
    4692 imported/w3c/web-platform-tests/css/css-contain/contain-layout-baseline-002.html [ ImageOnlyFailure ]
    4693 imported/w3c/web-platform-tests/css/css-contain/contain-layout-baseline-003.html [ ImageOnlyFailure ]
    4694 imported/w3c/web-platform-tests/css/css-contain/contain-layout-baseline-004.html [ ImageOnlyFailure ]
    4695 imported/w3c/web-platform-tests/css/css-contain/contain-layout-baseline-005.html [ ImageOnlyFailure ]
     4681# webkit-ruby-text
     4682imported/w3c/web-platform-tests/css/css-contain/contain-layout-017.html [ ImageOnlyFailure ]
    46964683imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-001.html [ ImageOnlyFailure ]
    46974684imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-003.html [ ImageOnlyFailure ]
     
    47084695imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-021.html [ ImageOnlyFailure ]
    47094696imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-022.html [ ImageOnlyFailure ]
    4710 imported/w3c/web-platform-tests/css/css-contain/contain-layout-button-001.html [ ImageOnlyFailure ]
    4711 imported/w3c/web-platform-tests/css/css-contain/contain-layout-cell-001.html [ ImageOnlyFailure ]
    4712 imported/w3c/web-platform-tests/css/css-contain/contain-layout-cell-002.html [ ImageOnlyFailure ]
    4713 imported/w3c/web-platform-tests/css/css-contain/contain-layout-containing-block-absolute-001.html [ ImageOnlyFailure ]
    4714 imported/w3c/web-platform-tests/css/css-contain/contain-layout-containing-block-fixed-001.html [ ImageOnlyFailure ]
    4715 imported/w3c/web-platform-tests/css/css-contain/contain-layout-flexbox-001.html [ ImageOnlyFailure ]
    4716 imported/w3c/web-platform-tests/css/css-contain/contain-layout-formatting-context-float-001.html [ ImageOnlyFailure ]
    4717 imported/w3c/web-platform-tests/css/css-contain/contain-layout-formatting-context-margin-001.html [ ImageOnlyFailure ]
    4718 imported/w3c/web-platform-tests/css/css-contain/contain-layout-grid-001.html [ ImageOnlyFailure ]
    4719 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ifc-022.html [ ImageOnlyFailure ]
    4720 imported/w3c/web-platform-tests/css/css-contain/contain-layout-independent-formatting-context-001.html [ ImageOnlyFailure ]
    4721 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-013.html [ ImageOnlyFailure ]
    4722 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-014.html [ ImageOnlyFailure ]
    4723 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-015.html [ ImageOnlyFailure ]
    4724 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-016.html [ ImageOnlyFailure ]
    4725 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-017.html [ ImageOnlyFailure ]
    4726 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-018.html [ ImageOnlyFailure ]
    4727 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-019.html [ ImageOnlyFailure ]
    4728 imported/w3c/web-platform-tests/css/css-contain/contain-layout-ink-overflow-020.html [ ImageOnlyFailure ]
    4729 imported/w3c/web-platform-tests/css/css-contain/contain-layout-overflow-001.html [ ImageOnlyFailure ]
    4730 imported/w3c/web-platform-tests/css/css-contain/contain-layout-overflow-002.html [ ImageOnlyFailure ]
    47314697imported/w3c/web-platform-tests/css/css-contain/contain-layout-size-003.html [ ImageOnlyFailure ]
    4732 imported/w3c/web-platform-tests/css/css-contain/contain-layout-stacking-context-001.html [ ImageOnlyFailure ]
    4733 imported/w3c/web-platform-tests/css/css-contain/contain-layout-suppress-baseline-001.html [ ImageOnlyFailure ]
    4734 imported/w3c/web-platform-tests/css/css-contain/contain-layout-suppress-baseline-002.html [ ImageOnlyFailure ]
    47354698imported/w3c/web-platform-tests/css/css-contain/contain-paint-001.html [ ImageOnlyFailure ]
    47364699imported/w3c/web-platform-tests/css/css-contain/contain-paint-004.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/ChangeLog

    r276232 r276235  
     12021-04-18  Rob Buis  <rbuis@igalia.com>
     2
     3        Support contain: layout
     4        https://bugs.webkit.org/show_bug.cgi?id=223569
     5
     6        Reviewed by Darin Adler.
     7
     8        This patch implements layout containment as specified[1].
     9        It adds shouldApplyLayoutContainment to check whether the
     10        element applies for layout containment. Is so, then:
     11        - an independent formatting context is established.
     12        - any overflow is treated as ink overflow.
     13        - an absolute positioning and fixed positioning
     14        containing block is established.
     15        - a stacking context is created.
     16        - for baseline handling, the box is treated as having no
     17        baseline. For grid/flexible box containers/items, this needs
     18        a baseline synthesized from the border edges [2], for buttons it
     19        requires a baseline synthesized from the margin edges [2, 3].
     20
     21        [1] https://drafts.csswg.org/css-contain-2/#layout-containment
     22        [2] https://drafts.csswg.org/css-align-3/#synthesize-baseline
     23        [3] https://www.w3.org/TR/CSS2/visudet.html#propdef-vertical-align
     24
     25        * rendering/RenderBlock.cpp:
     26        (WebCore::RenderBlock::firstLineBaseline const):
     27        (WebCore::RenderBlock::inlineBlockBaseline const):
     28        * rendering/RenderBlockFlow.cpp:
     29        (WebCore::RenderBlockFlow::firstLineBaseline const):
     30        (WebCore::RenderBlockFlow::inlineBlockBaseline const):
     31        * rendering/RenderBox.cpp:
     32        (WebCore::RenderBox::createsNewFormattingContext const):
     33        (WebCore::RenderBox::layoutOverflowRectForPropagation const):
     34        * rendering/RenderBox.h:
     35        * rendering/RenderButton.cpp:
     36        (WebCore::RenderButton::baselinePosition const):
     37        * rendering/RenderElement.h:
     38        (WebCore::RenderElement::canContainFixedPositionObjects const):
     39        (WebCore::RenderElement::canContainAbsolutelyPositionedObjects const):
     40        * rendering/RenderFlexibleBox.cpp:
     41        (WebCore::RenderFlexibleBox::firstLineBaseline const):
     42        * rendering/RenderGrid.cpp:
     43        (WebCore::RenderGrid::firstLineBaseline const):
     44        * rendering/RenderListBox.cpp:
     45        (WebCore::RenderListBox::baselinePosition const):
     46        * rendering/RenderObject.cpp:
     47        (WebCore::objectIsRelayoutBoundary):
     48        (WebCore::shouldApplyLayoutContainment):
     49        * rendering/RenderObject.h:
     50        (WebCore::RenderObject::isAtomicInlineLevelBox const):
     51        * rendering/RenderTable.cpp:
     52        (WebCore::RenderTable::firstLineBaseline const):
     53        * rendering/style/RenderStyle.h:
     54        (WebCore::RenderStyle::containsLayout const):
     55        * style/StyleAdjuster.cpp:
     56        (WebCore::Style::Adjuster::adjust const):
     57
    1582021-04-18  Sam Weinig  <weinig@apple.com>
    259
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r276216 r276235  
    25762576Optional<LayoutUnit> RenderBlock::firstLineBaseline() const
    25772577{
     2578    if (shouldApplyLayoutContainment(*this))
     2579        return WTF::nullopt;
     2580
    25782581    if (isWritingModeRoot() && !isRubyRun())
    25792582        return Optional<LayoutUnit>();
     
    25912594Optional<LayoutUnit> RenderBlock::inlineBlockBaseline(LineDirectionMode lineDirection) const
    25922595{
     2596    if (shouldApplyLayoutContainment(*this))
     2597        return synthesizedBaselineFromBorderBox(*this, lineDirection) + (lineDirection == HorizontalLine ? marginBottom() : marginLeft());
     2598
    25932599    if (isWritingModeRoot() && !isRubyRun())
    25942600        return Optional<LayoutUnit>();
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r276216 r276235  
    31133113        return WTF::nullopt;
    31143114
     3115    if (shouldApplyLayoutContainment(*this))
     3116        return WTF::nullopt;
     3117
    31153118    if (!childrenInline())
    31163119        return RenderBlock::firstLineBaseline();
     
    31343137    if (isWritingModeRoot() && !isRubyRun())
    31353138        return WTF::nullopt;
     3139
     3140    if (shouldApplyLayoutContainment(*this))
     3141        return RenderBlock::inlineBlockBaseline(lineDirection);
    31363142
    31373143    if (style().display() == DisplayType::InlineBlock) {
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r276182 r276235  
    46794679    return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated()
    46804680        || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isDocumentElementRenderer() || isRenderFragmentedFlow() || isRenderFragmentContainer()
    4681         || isGridItem() || style().specifiesColumns() || style().columnSpan() == ColumnSpan::All || style().display() == DisplayType::FlowRoot;
     4681        || style().containsLayout() || isGridItem() || style().specifiesColumns() || style().columnSpan() == ColumnSpan::All || style().display() == DisplayType::FlowRoot;
    46824682}
    46834683
     
    49264926    // Only propagate interior layout overflow if we don't clip it.
    49274927    LayoutRect rect = borderBoxRect();
    4928     if (!hasOverflowClip())
     4928    if (!shouldApplyLayoutContainment(*this) && !hasOverflowClip())
    49294929        rect.unite(layoutOverflowRect());
    49304930
  • trunk/Source/WebCore/rendering/RenderBox.h

    r275873 r276235  
    5555        return isDocumentElementRenderer() || isPositioned() || createsGroup() || hasOverflowClip()
    5656            || hasTransformRelatedProperty() || hasHiddenBackface() || hasReflection() || style().specifiesColumns()
    57             || !style().hasAutoUsedZIndex() || hasRunningAcceleratedAnimations();
     57            || style().containsLayout() || !style().hasAutoUsedZIndex() || hasRunningAcceleratedAnimations();
    5858    }
    5959
  • trunk/Source/WebCore/rendering/RenderButton.cpp

    r275594 r276235  
    149149}
    150150
    151 LayoutUnit RenderButton::baselinePosition(FontBaseline, bool, LineDirectionMode direction, LinePositionMode) const
     151LayoutUnit RenderButton::baselinePosition(FontBaseline fontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode mode) const
    152152{
     153    if (shouldApplyLayoutContainment(*this))
     154        return RenderFlexibleBox::baselinePosition(fontBaseline, firstLine, direction, mode);
    153155    // We cannot rely on RenderFlexibleBox::baselinePosition() because of flexboxes have some special behavior
    154156    // regarding baselines that shouldn't apply to buttons.
  • trunk/Source/WebCore/rendering/RenderElement.h

    r275478 r276235  
    430430        || (hasTransform() && isRenderBlock())
    431431        || isSVGForeignObject()
     432        || shouldApplyLayoutContainment(*this)
    432433        || isOutOfFlowRenderFragmentedFlow();
    433434}
     
    438439        || (isRenderBlock() && hasTransformRelatedProperty())
    439440        || isSVGForeignObject()
     441        || shouldApplyLayoutContainment(*this)
    440442        || isRenderView();
    441443}
  • trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp

    r275873 r276235  
    156156Optional<LayoutUnit> RenderFlexibleBox::firstLineBaseline() const
    157157{
    158     if (isWritingModeRoot() || m_numberOfInFlowChildrenOnFirstLine <= 0)
     158    if (isWritingModeRoot() || m_numberOfInFlowChildrenOnFirstLine <= 0 || shouldApplyLayoutContainment(*this))
    159159        return Optional<LayoutUnit>();
    160160    RenderBox* baselineChild = nullptr;
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r275494 r276235  
    12601260Optional<LayoutUnit> RenderGrid::firstLineBaseline() const
    12611261{
    1262     if (isWritingModeRoot() || !m_grid.hasGridItems())
     1262    if (isWritingModeRoot() || !m_grid.hasGridItems() || shouldApplyLayoutContainment(*this))
    12631263        return WTF::nullopt;
    12641264
  • trunk/Source/WebCore/rendering/RenderListBox.cpp

    r276182 r276235  
    276276LayoutUnit RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
    277277{
    278     return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
     278    auto baseline = RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode);
     279    if (!shouldApplyLayoutContainment(*this))
     280        baseline -= baselineAdjustment;
     281    return baseline;
    279282}
    280283
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r275478 r276235  
    503503        return true;
    504504
     505    if (shouldApplyLayoutContainment(*object))
     506        return true;
     507
    505508    if (object->isSVGRoot())
    506509        return true;
     
    24412444
    24422445#endif
     2446
     2447bool WebCore::shouldApplyLayoutContainment(const WebCore::RenderObject& renderer)
     2448{
     2449    return renderer.style().containsLayout() && (!renderer.isInline() || renderer.isAtomicInlineLevelBox()) && !renderer.isRubyText() && (!renderer.isTablePart() || renderer.isRenderBlockFlow());
     2450}
  • trunk/Source/WebCore/rendering/RenderObject.h

    r275478 r276235  
    203203    bool isRenderInline() const;
    204204    bool isRenderLayerModelObject() const;
     205
     206    inline bool isAtomicInlineLevelBox() const;
    205207
    206208    virtual bool isCounter() const { return false; }
     
    11761178}
    11771179
     1180bool RenderObject::isAtomicInlineLevelBox() const
     1181{
     1182    return style().isDisplayInlineType() && !(style().display() == DisplayType::Inline && !isReplaced());
     1183}
     1184
    11781185WTF::TextStream& operator<<(WTF::TextStream&, const RenderObject&);
    11791186
     
    11831190void printGraphicsLayerTreeForLiveDocuments();
    11841191#endif
     1192
     1193bool shouldApplyLayoutContainment(const RenderObject&);
    11851194
    11861195} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderTable.cpp

    r275931 r276235  
    14991499    // This is also needed to properly determine the baseline of a cell if it has a table child.
    15001500
    1501     if (isWritingModeRoot())
     1501    if (isWritingModeRoot() || shouldApplyLayoutContainment(*this))
    15021502        return Optional<LayoutUnit>();
    15031503
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r276216 r276235  
    525525    bool hasAspectRatio() const { return aspectRatioType() == AspectRatioType::Ratio || aspectRatioType() == AspectRatioType::AutoAndRatio; }
    526526    OptionSet<Containment> contain() const { return m_rareNonInheritedData->contain; }
     527    bool containsLayout() const { return m_rareNonInheritedData->contain.contains(Containment::Layout); }
    527528    BoxAlignment boxAlign() const { return static_cast<BoxAlignment>(m_rareNonInheritedData->deprecatedFlexibleBox->align); }
    528529    BoxDirection boxDirection() const { return static_cast<BoxDirection>(m_inheritedFlags.boxDirection); }
  • trunk/Source/WebCore/style/StyleAdjuster.cpp

    r276216 r276235  
    438438#endif
    439439
     440    // contain: layout creates a stacking context.
     441    if (style.hasAutoUsedZIndex() && style.containsLayout())
     442        style.setUsedZIndex(0);
     443
    440444    // Cull out any useless layers and also repeat patterns into additional layers.
    441445    style.adjustBackgroundLayers();
Note: See TracChangeset for help on using the changeset viewer.