- a/Source/WebCore/ChangeLog +31 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2022-02-23  Antti Koivisto  <antti@apple.com>
2
3
        [CSS Container Queries] offsetWidth/Height and similar should update layout for container queries
4
        https://bugs.webkit.org/show_bug.cgi?id=237079
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Fix
9
10
        css/css-contain/container-queries/inline-size-containment.html
11
        css/css-contain/container-queries/inline-size-containment-vertical-rl.html
12
13
        * dom/Document.cpp:
14
        (WebCore::Document::updateLayout):
15
16
        Make iterative instead of recursive.
17
18
        (WebCore::Document::updateLayoutIfDimensionsOutOfDate):
19
20
        Check for query containers.
21
        Call local updateLayout instead of the FrameViewLayoutContext one.
22
23
        * page/FrameView.cpp:
24
        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
25
        * style/StyleScope.cpp:
26
        (WebCore::Style::Scope::updateQueryContainerState):
27
28
        Add protection against infinite layout/invalidation cycle with unstable layouts.
29
30
        * style/StyleScope.h:
31
1
2022-02-23  Zan Dobersek  <zdobersek@igalia.com>
32
2022-02-23  Zan Dobersek  <zdobersek@igalia.com>
2
33
3
        [GStreamer] Add WebKitDMABufVideoSink
34
        [GStreamer] Add WebKitDMABufVideoSink
- a/Source/WebCore/dom/Document.cpp -6 / +18 lines
Lines 2208-2215 void Document::updateLayout() a/Source/WebCore/dom/Document.cpp_sec1
2208
2208
2209
    frameView->layoutContext().layout();
2209
    frameView->layoutContext().layout();
2210
2210
2211
    if (styleScope().updateQueryContainerState())
2211
    Style::Scope::QueryContainerUpdateContext queryContainerUpdateContext;
2212
        updateLayout();
2212
    while (styleScope().updateQueryContainerState(queryContainerUpdateContext)) {
2213
        updateStyleIfNeeded();
2214
2215
        if (!frameView->layoutContext().needsLayout())
2216
            break;
2217
2218
        frameView->layoutContext().layout();
2219
    }
2213
}
2220
}
2214
2221
2215
void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
2222
void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
Lines 2313-2319 bool Document::updateLayoutIfDimensionsOutOfDate(Element& element, DimensionsChe a/Source/WebCore/dom/Document.cpp_sec2
2313
            
2320
            
2314
            previousBox = currentBox;
2321
            previousBox = currentBox;
2315
            currentBox = downcast<RenderBox>(currRenderer);
2322
            currentBox = downcast<RenderBox>(currRenderer);
2316
            
2323
2324
            if (currentBox->style().containerType() != ContainerType::None) {
2325
                requireFullLayout = true;
2326
                break;
2327
            }
2328
2317
            // If a box needs layout for itself or if a box has changed children and sizes its width to
2329
            // If a box needs layout for itself or if a box has changed children and sizes its width to
2318
            // its content, then require a full layout.
2330
            // its content, then require a full layout.
2319
            if (currentBox->selfNeedsLayout() ||
2331
            if (currentBox->selfNeedsLayout() ||
Lines 2348-2356 bool Document::updateLayoutIfDimensionsOutOfDate(Element& element, DimensionsChe a/Source/WebCore/dom/Document.cpp_sec3
2348
    
2360
    
2349
    StackStats::LayoutCheckPoint layoutCheckPoint;
2361
    StackStats::LayoutCheckPoint layoutCheckPoint;
2350
2362
2351
    // Only do a layout if changes have occurred that make it necessary.      
2363
    // Only do a layout if changes have occurred that make it necessary.
2352
    if (requireFullLayout && frameView && renderView() && (frameView->layoutContext().isLayoutPending() || renderView()->needsLayout()))
2364
    if (requireFullLayout)
2353
        frameView->layoutContext().layout();
2365
        updateLayout();
2354
    
2366
    
2355
    return requireFullLayout;
2367
    return requireFullLayout;
2356
}
2368
}
- a/Source/WebCore/page/FrameView.cpp -1 / +3 lines
Lines 4541-4546 void FrameView::updateLayoutAndStyleIfNeededRecursive() a/Source/WebCore/page/FrameView.cpp_sec1
4541
        return descendantsDeque.first().ptr();
4541
        return descendantsDeque.first().ptr();
4542
    };
4542
    };
4543
4543
4544
    Style::Scope::QueryContainerUpdateContext queryContainerUpdateContext;
4545
4544
    for (unsigned i = 0; i < maxUpdatePasses; ++i) {
4546
    for (unsigned i = 0; i < maxUpdatePasses; ++i) {
4545
        bool didWork = false;
4547
        bool didWork = false;
4546
        DescendantsDeque deque;
4548
        DescendantsDeque deque;
Lines 4549-4555 void FrameView::updateLayoutAndStyleIfNeededRecursive() a/Source/WebCore/page/FrameView.cpp_sec2
4549
                didWork = true;
4551
                didWork = true;
4550
            if (view->needsLayout()) {
4552
            if (view->needsLayout()) {
4551
                view->layoutContext().layout();
4553
                view->layoutContext().layout();
4552
                view->frame().document()->styleScope().updateQueryContainerState();
4554
                view->frame().document()->styleScope().updateQueryContainerState(queryContainerUpdateContext);
4553
                didWork = true;
4555
                didWork = true;
4554
            }
4556
            }
4555
        }
4557
        }
- a/Source/WebCore/style/StyleScope.cpp -6 / +7 lines
Lines 783-789 bool Scope::isForUserAgentShadowTree() const a/Source/WebCore/style/StyleScope.cpp_sec1
783
    return m_shadowRoot && m_shadowRoot->mode() == ShadowRootMode::UserAgent;
783
    return m_shadowRoot && m_shadowRoot->mode() == ShadowRootMode::UserAgent;
784
}
784
}
785
785
786
bool Scope::updateQueryContainerState()
786
bool Scope::updateQueryContainerState(QueryContainerUpdateContext& context)
787
{
787
{
788
    ASSERT(!m_shadowRoot);
788
    ASSERT(!m_shadowRoot);
789
    ASSERT(m_document.renderView());
789
    ASSERT(m_document.renderView());
Lines 791-797 bool Scope::updateQueryContainerState() a/Source/WebCore/style/StyleScope.cpp_sec2
791
    auto previousStates = WTFMove(m_queryContainerStates);
791
    auto previousStates = WTFMove(m_queryContainerStates);
792
    m_queryContainerStates.clear();
792
    m_queryContainerStates.clear();
793
793
794
    Vector<Element*> changedContainers;
794
    Vector<Element*> containersToInvalidate;
795
795
796
    for (auto& containerRenderer : m_document.renderView()->containerQueryBoxes()) {
796
    for (auto& containerRenderer : m_document.renderView()->containerQueryBoxes()) {
797
        auto* containerElement = containerRenderer.element();
797
        auto* containerElement = containerRenderer.element();
Lines 814-828 bool Scope::updateQueryContainerState() a/Source/WebCore/style/StyleScope.cpp_sec3
814
814
815
        auto it = previousStates.find(*containerElement);
815
        auto it = previousStates.find(*containerElement);
816
        bool changed = it == previousStates.end() || sizeChanged(it->value);
816
        bool changed = it == previousStates.end() || sizeChanged(it->value);
817
        if (changed)
817
        // Protect against unstable layout by invalidating only once per container.
818
            changedContainers.append(containerElement);
818
        if (changed && context.invalidatedContainers.add(containerElement).isNewEntry)
819
            containersToInvalidate.append(containerElement);
819
        m_queryContainerStates.add(*containerElement, size);
820
        m_queryContainerStates.add(*containerElement, size);
820
    }
821
    }
821
822
822
    for (auto* toInvalidate : changedContainers)
823
    for (auto* toInvalidate : containersToInvalidate)
823
        toInvalidate->invalidateForQueryContainerChange();
824
        toInvalidate->invalidateForQueryContainerChange();
824
825
825
    return !changedContainers.isEmpty();
826
    return !containersToInvalidate.isEmpty();
826
}
827
}
827
828
828
HTMLSlotElement* assignedSlotForScopeOrdinal(const Element& element, ScopeOrdinal scopeOrdinal)
829
HTMLSlotElement* assignedSlotForScopeOrdinal(const Element& element, ScopeOrdinal scopeOrdinal)
- a/Source/WebCore/style/StyleScope.h -1 / +4 lines
Lines 129-135 public: a/Source/WebCore/style/StyleScope.h_sec1
129
    static Scope& forNode(Node&);
129
    static Scope& forNode(Node&);
130
    static Scope* forOrdinal(Element&, ScopeOrdinal);
130
    static Scope* forOrdinal(Element&, ScopeOrdinal);
131
131
132
    bool updateQueryContainerState();
132
    struct QueryContainerUpdateContext {
133
        HashSet<Element*> invalidatedContainers;
134
    };
135
    bool updateQueryContainerState(QueryContainerUpdateContext&);
133
136
134
private:
137
private:
135
    Scope& documentScope();
138
    Scope& documentScope();
- a/LayoutTests/imported/w3c/ChangeLog +12 lines
Lines 1-3 a/LayoutTests/imported/w3c/ChangeLog_sec1
1
2022-02-23  Antti Koivisto  <antti@apple.com>
2
3
        [CSS Container Queries] offsetWidth/Height and similar should update layout for container queries
4
        https://bugs.webkit.org/show_bug.cgi?id=237079
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * web-platform-tests/css/css-contain/container-queries/auto-scrollbars-expected.txt:
9
        * web-platform-tests/css/css-contain/container-queries/inline-size-containment-expected.txt:
10
        * web-platform-tests/css/css-contain/container-queries/inline-size-containment-vertical-rl-expected.txt:
11
        * web-platform-tests/css/css-contain/container-queries/transition-scrollbars-expected.txt:
12
1
2022-02-22  Antti Koivisto  <antti@apple.com>
13
2022-02-22  Antti Koivisto  <antti@apple.com>
2
14
3
        [CSS container Queries] getComputedStyle should update style for invalid query containers
15
        [CSS container Queries] getComputedStyle should update style for invalid query containers
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/auto-scrollbars-expected.txt -1 / +1 lines
Lines 1-4 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/auto-scrollbars-expected.txt_sec1
1
1
2
FAIL Initial layout - expecting a scrollbar without overflowing content instead of overflowing content without a scrollbar assert_equals: Layout with a scrollbar means the container query applies expected "50px" but got "100px"
2
FAIL Initial layout - expecting a scrollbar without overflowing content instead of overflowing content without a scrollbar assert_less_than: Expects a vertical scrollbar expected a number less than 100 but got 100
3
FAIL Same result after a reflow assert_less_than: Expects a vertical scrollbar expected a number less than 100 but got 100
3
FAIL Same result after a reflow assert_less_than: Expects a vertical scrollbar expected a number less than 100 but got 100
4
4
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-containment-expected.txt -1 / +1 lines
Lines 1-3 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-containment-expected.txt_sec1
1
1
2
FAIL inline-size containment only assert_equals: expected 400 but got 20
2
PASS inline-size containment only
3
3
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-containment-vertical-rl-expected.txt -1 / +1 lines
Lines 1-3 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-containment-vertical-rl-expected.txt_sec1
1
1
2
FAIL inline-size containment only assert_equals: expected 50 but got 400
2
PASS inline-size containment only
3
3
- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/transition-scrollbars-expected.txt -1 / +1 lines
Lines 1-4 a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/transition-scrollbars-expected.txt_sec1
1
Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo
1
Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo Foo bar foo bar foo
2
2
3
FAIL Scrollbars do not cause a transition of background-color assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 255)"
3
FAIL Scrollbars do not cause a transition of background-color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(0, 64, 128)"
4
4

Return to Bug 237079