| Differences between
and this patch
- a/Source/WebCore/ChangeLog +28 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2021-05-31  Rob Buis  <rbuis@igalia.com>
2
3
        [css-contain] Support contain:style
4
        https://bugs.webkit.org/show_bug.cgi?id=226458
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        WIP.
9
10
        * css/CSSComputedStyleDeclaration.cpp:
11
        (WebCore::ComputedStyleExtractor::valueForPropertyInStyle):
12
        * css/parser/CSSPropertyParser.cpp:
13
        (WebCore::consumeContain):
14
        * rendering/RenderCounter.cpp:
15
        (WebCore::ancestorStyleContainmentObject):
16
        (WebCore::previousInPreOrder):
17
        (WebCore::previousSiblingOrParentElement):
18
        (WebCore::makeCounterNode):
19
        (WebCore::RenderCounter::rendererSubtreeAttached):
20
        * rendering/RenderObject.cpp:
21
        (WebCore::shouldApplyStyleContainment):
22
        * rendering/RenderObject.h:
23
        * rendering/style/RenderStyle.h:
24
        (WebCore::RenderStyle::containsStyle const):
25
        * rendering/style/RenderStyleConstants.h:
26
        * style/StyleBuilderCustom.h:
27
        (WebCore::Style::BuilderCustom::applyValueContain):
28
1
2021-05-28  Martin Robinson  <mrobinson@webkit.org>
29
2021-05-28  Martin Robinson  <mrobinson@webkit.org>
2
30
3
        More readily layout when scroll-snap properties change
31
        More readily layout when scroll-snap properties change
- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +2 lines
Lines 3488-3493 RefPtr<CSSValue> ComputedStyleExtractor::valueForPropertyInStyle(const RenderSty a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp_sec1
3488
                list->append(cssValuePool.createIdentifierValue(CSSValueSize));
3488
                list->append(cssValuePool.createIdentifierValue(CSSValueSize));
3489
            if (containment & Containment::Layout)
3489
            if (containment & Containment::Layout)
3490
                list->append(cssValuePool.createIdentifierValue(CSSValueLayout));
3490
                list->append(cssValuePool.createIdentifierValue(CSSValueLayout));
3491
            if (containment & Containment::Style)
3492
                list->append(cssValuePool.createIdentifierValue(CSSValueStyle));
3491
            if (containment & Containment::Paint)
3493
            if (containment & Containment::Paint)
3492
                list->append(cssValuePool.createIdentifierValue(CSSValuePaint));
3494
                list->append(cssValuePool.createIdentifierValue(CSSValuePaint));
3493
            return list;
3495
            return list;
- a/Source/WebCore/css/parser/CSSPropertyParser.cpp -1 / +8 lines
Lines 3850-3856 static RefPtr<CSSValue> consumeContain(CSSParserTokenRange& range) a/Source/WebCore/css/parser/CSSPropertyParser.cpp_sec1
3850
    if (auto singleValue = consumeIdent<CSSValueNone, CSSValueStrict, CSSValueContent>(range))
3850
    if (auto singleValue = consumeIdent<CSSValueNone, CSSValueStrict, CSSValueContent>(range))
3851
        return singleValue;
3851
        return singleValue;
3852
    auto list = CSSValueList::createSpaceSeparated();
3852
    auto list = CSSValueList::createSpaceSeparated();
3853
    RefPtr<CSSPrimitiveValue> size, layout, paint;
3853
    RefPtr<CSSPrimitiveValue> size, layout, paint, style;
3854
    while (!range.atEnd()) {
3854
    while (!range.atEnd()) {
3855
        switch (range.peek().id()) {
3855
        switch (range.peek().id()) {
3856
        case CSSValueSize:
3856
        case CSSValueSize:
Lines 3868-3873 static RefPtr<CSSValue> consumeContain(CSSParserTokenRange& range) a/Source/WebCore/css/parser/CSSPropertyParser.cpp_sec2
3868
                return nullptr;
3868
                return nullptr;
3869
            paint = consumeIdent(range);
3869
            paint = consumeIdent(range);
3870
            break;
3870
            break;
3871
        case CSSValueStyle:
3872
            if (style)
3873
                return nullptr;
3874
            style = consumeIdent(range);
3875
            break;
3871
        default:
3876
        default:
3872
            return nullptr;
3877
            return nullptr;
3873
        }
3878
        }
Lines 3876-3881 static RefPtr<CSSValue> consumeContain(CSSParserTokenRange& range) a/Source/WebCore/css/parser/CSSPropertyParser.cpp_sec3
3876
        list->append(size.releaseNonNull());
3881
        list->append(size.releaseNonNull());
3877
    if (layout)
3882
    if (layout)
3878
        list->append(layout.releaseNonNull());
3883
        list->append(layout.releaseNonNull());
3884
    if (style)
3885
        list->append(style.releaseNonNull());
3879
    if (paint)
3886
    if (paint)
3880
        list->append(paint.releaseNonNull());
3887
        list->append(paint.releaseNonNull());
3881
    if (!list->length())
3888
    if (!list->length())
- a/Source/WebCore/rendering/RenderCounter.cpp -7 / +32 lines
Lines 57-71 static CounterMaps& counterMaps() a/Source/WebCore/rendering/RenderCounter.cpp_sec1
57
    return staticCounterMaps;
57
    return staticCounterMaps;
58
}
58
}
59
59
60
static Element* ancestorStyleContainmentObject(const Element& element)
61
{
62
    for (Element* ancestor = element.parentElement(); ancestor; ancestor = ancestor->parentElement()) {
63
        if (auto* style = ancestor->existingComputedStyle()) {
64
            if (style->containsStyle())
65
                return ancestor;
66
        }
67
    }
68
    return nullptr;
69
}
70
60
// This function processes the renderer tree in the order of the DOM tree
71
// This function processes the renderer tree in the order of the DOM tree
61
// including pseudo elements as defined in CSS 2.1.
72
// including pseudo elements as defined in CSS 2.1.
62
static RenderElement* previousInPreOrder(const RenderElement& renderer)
73
static RenderElement* previousInPreOrder(const RenderElement& renderer)
63
{
74
{
64
    ASSERT(renderer.element());
75
    ASSERT(renderer.element());
65
    Element* previous = ElementTraversal::previousIncludingPseudo(*renderer.element());
76
    Element* previous = ElementTraversal::previousIncludingPseudo(*renderer.element());
66
    while (previous && !previous->renderer())
77
    Element* styleContainAncestor = ancestorStyleContainmentObject(*renderer.element());
67
        previous = ElementTraversal::previousIncludingPseudo(*previous);
78
    while (true) {
68
    return previous ? previous->renderer() : 0;
79
        while (previous && !previous->renderer() && !previous->hasDisplayContents())
80
            previous = ElementTraversal::previousIncludingPseudo(*previous);
81
        if (!previous)
82
            return nullptr;
83
        Element* previousStyleContainAncestor = ancestorStyleContainmentObject(*previous);
84
        if (previousStyleContainAncestor == styleContainAncestor)
85
            return previous->renderer();
86
        if (!previousStyleContainAncestor)
87
            return nullptr;
88
        previous = previousStyleContainAncestor;
89
    }
69
}
90
}
70
91
71
static inline Element* parentOrPseudoHostElement(const RenderElement& renderer)
92
static inline Element* parentOrPseudoHostElement(const RenderElement& renderer)
Lines 78-84 static inline Element* parentOrPseudoHostElement(const RenderElement& renderer) a/Source/WebCore/rendering/RenderCounter.cpp_sec2
78
static Element* previousSiblingOrParentElement(const Element& element)
99
static Element* previousSiblingOrParentElement(const Element& element)
79
{
100
{
80
    if (auto* previous = ElementTraversal::pseudoAwarePreviousSibling(element)) {
101
    if (auto* previous = ElementTraversal::pseudoAwarePreviousSibling(element)) {
81
        while (previous && !previous->renderer())
102
        while (previous && !previous->renderer() && !previous->hasDisplayContents())
82
            previous = ElementTraversal::pseudoAwarePreviousSibling(*previous);
103
            previous = ElementTraversal::pseudoAwarePreviousSibling(*previous);
83
104
84
        if (previous)
105
        if (previous)
Lines 96-101 static Element* previousSiblingOrParentElement(const Element& element) a/Source/WebCore/rendering/RenderCounter.cpp_sec3
96
    auto* parent = element.parentElement();
117
    auto* parent = element.parentElement();
97
    if (parent && !parent->renderer())
118
    if (parent && !parent->renderer())
98
        parent = previousSiblingOrParentElement(*parent);
119
        parent = previousSiblingOrParentElement(*parent);
120
    if (parent && parent->renderer() && parent->renderer()->style().containsStyle())
121
        return nullptr;
99
    return parent;
122
    return parent;
100
}
123
}
101
124
Lines 335-341 static CounterNode* makeCounterNode(RenderElement& renderer, const AtomString& i a/Source/WebCore/rendering/RenderCounter.cpp_sec4
335
    maps.add(&renderer, makeUnique<CounterMap>()).iterator->value->add(identifier, newNode.copyRef());
358
    maps.add(&renderer, makeUnique<CounterMap>()).iterator->value->add(identifier, newNode.copyRef());
336
    renderer.setHasCounterNodeMap(true);
359
    renderer.setHasCounterNodeMap(true);
337
360
338
    if (newNode->parent())
361
    if (newNode->parent() || shouldApplyStyleContainment(renderer))
339
        return newNode.ptr();
362
        return newNode.ptr();
340
363
341
    // Check if some nodes that were previously root nodes should become children of this node now.
364
    // Check if some nodes that were previously root nodes should become children of this node now.
Lines 343-349 static CounterNode* makeCounterNode(RenderElement& renderer, const AtomString& i a/Source/WebCore/rendering/RenderCounter.cpp_sec5
343
    auto* stayWithin = parentOrPseudoHostElement(renderer);
366
    auto* stayWithin = parentOrPseudoHostElement(renderer);
344
    bool skipDescendants = false;
367
    bool skipDescendants = false;
345
    while ((currentRenderer = nextInPreOrder(*currentRenderer, stayWithin, skipDescendants))) {
368
    while ((currentRenderer = nextInPreOrder(*currentRenderer, stayWithin, skipDescendants))) {
346
        skipDescendants = false;
369
        skipDescendants = shouldApplyStyleContainment(*currentRenderer);
347
        if (!currentRenderer->hasCounterNodeMap())
370
        if (!currentRenderer->hasCounterNodeMap())
348
            continue;
371
            continue;
349
        auto* currentCounter = maps.find(currentRenderer)->value->get(identifier);
372
        auto* currentCounter = maps.find(currentRenderer)->value->get(identifier);
Lines 549-556 void RenderCounter::rendererSubtreeAttached(RenderElement& renderer) a/Source/WebCore/rendering/RenderCounter.cpp_sec6
549
        element = renderer.generatingElement();
572
        element = renderer.generatingElement();
550
    if (element && !element->renderer())
573
    if (element && !element->renderer())
551
        return; // No need to update if the parent is not attached yet
574
        return; // No need to update if the parent is not attached yet
575
    bool crossedBoundary = false;
552
    for (RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder(&renderer)) {
576
    for (RenderObject* descendant = &renderer; descendant; descendant = descendant->nextInPreOrder(&renderer)) {
553
        if (is<RenderElement>(*descendant))
577
        crossedBoundary |= shouldApplyStyleContainment(*descendant);
578
        if (crossedBoundary && is<RenderElement>(*descendant))
554
            updateCounters(downcast<RenderElement>(*descendant));
579
            updateCounters(downcast<RenderElement>(*descendant));
555
    }
580
    }
556
}
581
}
- a/Source/WebCore/rendering/RenderObject.cpp +5 lines
Lines 2514-2516 bool WebCore::shouldApplySizeContainment(const WebCore::RenderObject& renderer) a/Source/WebCore/rendering/RenderObject.cpp_sec1
2514
{
2514
{
2515
    return renderer.style().containsSize() && (!renderer.isInline() || renderer.isAtomicInlineLevelBox()) && !renderer.isRubyText() && (!renderer.isTablePart() || renderer.isTableCaption()) && !renderer.isTable();
2515
    return renderer.style().containsSize() && (!renderer.isInline() || renderer.isAtomicInlineLevelBox()) && !renderer.isRubyText() && (!renderer.isTablePart() || renderer.isTableCaption()) && !renderer.isTable();
2516
}
2516
}
2517
2518
bool WebCore::shouldApplyStyleContainment(const WebCore::RenderObject& renderer)
2519
{
2520
    return renderer.style().containsStyle() && (!renderer.isInline() || renderer.isAtomicInlineLevelBox()) && !renderer.isRubyText() && (!renderer.isTablePart() || renderer.isTableCaption()) && !renderer.isTable();
2521
}
- a/Source/WebCore/rendering/RenderObject.h +1 lines
Lines 1197-1202 void printGraphicsLayerTreeForLiveDocuments(); a/Source/WebCore/rendering/RenderObject.h_sec1
1197
1197
1198
bool shouldApplyLayoutContainment(const RenderObject&);
1198
bool shouldApplyLayoutContainment(const RenderObject&);
1199
bool shouldApplySizeContainment(const RenderObject&);
1199
bool shouldApplySizeContainment(const RenderObject&);
1200
bool shouldApplyStyleContainment(const RenderObject&);
1200
1201
1201
} // namespace WebCore
1202
} // namespace WebCore
1202
1203
- a/Source/WebCore/rendering/style/RenderStyle.h +1 lines
Lines 528-533 public: a/Source/WebCore/rendering/style/RenderStyle.h_sec1
528
    OptionSet<Containment> contain() const { return m_rareNonInheritedData->contain; }
528
    OptionSet<Containment> contain() const { return m_rareNonInheritedData->contain; }
529
    bool containsLayout() const { return m_rareNonInheritedData->contain.contains(Containment::Layout); }
529
    bool containsLayout() const { return m_rareNonInheritedData->contain.contains(Containment::Layout); }
530
    bool containsSize() const { return m_rareNonInheritedData->contain.contains(Containment::Size); }
530
    bool containsSize() const { return m_rareNonInheritedData->contain.contains(Containment::Size); }
531
    bool containsStyle() const { return m_rareNonInheritedData->contain.contains(Containment::Style); }
531
    BoxAlignment boxAlign() const { return static_cast<BoxAlignment>(m_rareNonInheritedData->deprecatedFlexibleBox->align); }
532
    BoxAlignment boxAlign() const { return static_cast<BoxAlignment>(m_rareNonInheritedData->deprecatedFlexibleBox->align); }
532
    BoxDirection boxDirection() const { return static_cast<BoxDirection>(m_inheritedFlags.boxDirection); }
533
    BoxDirection boxDirection() const { return static_cast<BoxDirection>(m_inheritedFlags.boxDirection); }
533
    float boxFlex() const { return m_rareNonInheritedData->deprecatedFlexibleBox->flex; }
534
    float boxFlex() const { return m_rareNonInheritedData->deprecatedFlexibleBox->flex; }
- a/Source/WebCore/rendering/style/RenderStyleConstants.h +1 lines
Lines 1223-1228 enum class Containment : uint8_t { a/Source/WebCore/rendering/style/RenderStyleConstants.h_sec1
1223
    Layout   = 1 << 0,
1223
    Layout   = 1 << 0,
1224
    Paint    = 1 << 1,
1224
    Paint    = 1 << 1,
1225
    Size     = 1 << 2,
1225
    Size     = 1 << 2,
1226
    Style    = 1 << 3,
1226
};
1227
};
1227
1228
1228
extern const float defaultMiterLimit;
1229
extern const float defaultMiterLimit;
- a/Source/WebCore/style/StyleBuilderCustom.h +3 lines
Lines 1277-1282 inline void BuilderCustom::applyValueContain(BuilderState& builderState, CSSValu a/Source/WebCore/style/StyleBuilderCustom.h_sec1
1277
        case CSSValuePaint:
1277
        case CSSValuePaint:
1278
            containment.add(Containment::Paint);
1278
            containment.add(Containment::Paint);
1279
            break;
1279
            break;
1280
        case CSSValueStyle:
1281
            containment.add(Containment::Style);
1282
            break;
1280
        default:
1283
        default:
1281
            break;
1284
            break;
1282
        };
1285
        };
- a/LayoutTests/imported/w3c/ChangeLog +10 lines
Lines 1-3 a/LayoutTests/imported/w3c/ChangeLog_sec1
1
2021-05-31  Rob Buis  <rbuis@igalia.com>
2
3
        [css-contain] Support contain:style
4
        https://bugs.webkit.org/show_bug.cgi?id=226458
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * web-platform-tests/css/css-contain/parsing/contain-computed-expected.txt:
9
        * web-platform-tests/css/css-contain/parsing/contain-valid-expected.txt:
10
1
2021-05-28  Martin Robinson  <mrobinson@webkit.org>
11
2021-05-28  Martin Robinson  <mrobinson@webkit.org>
2
12
3
        More readily layout when scroll-snap properties change
13
        More readily layout when scroll-snap properties change
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/parsing/contain-computed-expected.txt -4 / +4 lines
Lines 4-15 PASS Property contain value 'strict' a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/parsing/contain-computed-expected.txt_sec1
4
PASS Property contain value 'content'
4
PASS Property contain value 'content'
5
PASS Property contain value 'size'
5
PASS Property contain value 'size'
6
PASS Property contain value 'layout'
6
PASS Property contain value 'layout'
7
FAIL Property contain value 'style' assert_true: 'style' is a supported value for contain. expected true got false
7
PASS Property contain value 'style'
8
PASS Property contain value 'paint'
8
PASS Property contain value 'paint'
9
PASS Property contain value 'size layout'
9
PASS Property contain value 'size layout'
10
FAIL Property contain value 'style paint' assert_true: 'style paint' is a supported value for contain. expected true got false
10
PASS Property contain value 'style paint'
11
FAIL Property contain value 'layout style paint' assert_true: 'layout style paint' is a supported value for contain. expected true got false
11
PASS Property contain value 'layout style paint'
12
FAIL Property contain value 'size layout style paint' assert_true: 'size layout style paint' is a supported value for contain. expected true got false
12
PASS Property contain value 'size layout style paint'
13
PASS Property contain value 'size layout paint'
13
PASS Property contain value 'size layout paint'
14
PASS Property contain value 'layout paint'
14
PASS Property contain value 'layout paint'
15
15
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/parsing/contain-valid-expected.txt -4 / +4 lines
Lines 4-13 PASS e.style['contain'] = "strict" should set the property value a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/parsing/contain-valid-expected.txt_sec1
4
PASS e.style['contain'] = "content" should set the property value
4
PASS e.style['contain'] = "content" should set the property value
5
PASS e.style['contain'] = "size" should set the property value
5
PASS e.style['contain'] = "size" should set the property value
6
PASS e.style['contain'] = "layout" should set the property value
6
PASS e.style['contain'] = "layout" should set the property value
7
FAIL e.style['contain'] = "style" should set the property value assert_not_equals: property should be set got disallowed value ""
7
PASS e.style['contain'] = "style" should set the property value
8
PASS e.style['contain'] = "paint" should set the property value
8
PASS e.style['contain'] = "paint" should set the property value
9
PASS e.style['contain'] = "layout size" should set the property value
9
PASS e.style['contain'] = "layout size" should set the property value
10
FAIL e.style['contain'] = "paint style" should set the property value assert_not_equals: property should be set got disallowed value ""
10
PASS e.style['contain'] = "paint style" should set the property value
11
FAIL e.style['contain'] = "layout style paint" should set the property value assert_not_equals: property should be set got disallowed value ""
11
PASS e.style['contain'] = "layout style paint" should set the property value
12
FAIL e.style['contain'] = "layout paint style size" should set the property value assert_not_equals: property should be set got disallowed value ""
12
PASS e.style['contain'] = "layout paint style size" should set the property value
13
13

Return to Bug 226458