Changeset 292635 in webkit


Ignore:
Timestamp:
Apr 8, 2022 2:35:00 PM (3 months ago)
Author:
Antti Koivisto
Message:

[CSS Container Queries] Search query containers for ::slotted and and ::part rules in their scope
https://bugs.webkit.org/show_bug.cgi?id=238997

Reviewed by Sam Weinig.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt:

Source/WebCore:

"For selectors with pseudo elements, query containers can be established by the shadow-including inclusive ancestors of
the ultimate originating element."

https://drafts.csswg.org/css-contain-3/#container-queries

  • style/ContainerQueryEvaluator.cpp:

(WebCore::Style::ContainerQueryEvaluator::ContainerQueryEvaluator):
(WebCore::Style::ContainerQueryEvaluator::selectContainer const):
(WebCore::Style::ContainerQueryEvaluator::selectContainer):

For rules coming from a non-local scope, search query container starting from the originating element in that scope.

  • style/ContainerQueryEvaluator.h:
  • style/ElementRuleCollector.cpp:

(WebCore::Style::ElementRuleCollector::collectMatchingRulesForList):
(WebCore::Style::ElementRuleCollector::containerQueriesMatch):

Pass rule's style scope ordinal so we can find the right scope.

  • style/ElementRuleCollector.h:
Location:
trunk
Files:
7 edited

Legend:

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

    r292606 r292635  
     12022-04-08  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Search query containers for ::slotted and and ::part rules in their scope
     4        https://bugs.webkit.org/show_bug.cgi?id=238997
     5
     6        Reviewed by Sam Weinig.
     7
     8        * web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt:
     9
    1102022-04-08  Alan Bujtas  <zalan@apple.com>
    211
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt

    r292592 r292635  
    22PASS Match container in outer tree
    33PASS Match container in same tree, not walking flat tree ancestors
    4 FAIL Match container in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
     4PASS Match container in ::slotted selector's originating element tree
    55PASS Match container in outer tree for :host
    6 FAIL Match container in ::part selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
    7 FAIL Match container for ::before in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
     6PASS Match container in ::part selector's originating element tree
     7PASS Match container for ::before in ::slotted selector's originating element tree
    88PASS Match container in outer tree for :host::before
    9 FAIL Match container for ::before in ::part selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
    10 FAIL Match container for ::part selector's originating element tree for exportparts assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
     9PASS Match container for ::before in ::part selector's originating element tree
     10PASS Match container for ::part selector's originating element tree for exportparts
    1111PASS Match container for slot light tree child fallback
    1212
  • trunk/Source/WebCore/ChangeLog

    r292633 r292635  
     12022-04-08  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Search query containers for ::slotted and and ::part rules in their scope
     4        https://bugs.webkit.org/show_bug.cgi?id=238997
     5
     6        Reviewed by Sam Weinig.
     7
     8        "For selectors with pseudo elements, query containers can be established by the shadow-including inclusive ancestors of
     9        the ultimate originating element."
     10
     11        https://drafts.csswg.org/css-contain-3/#container-queries
     12
     13        * style/ContainerQueryEvaluator.cpp:
     14        (WebCore::Style::ContainerQueryEvaluator::ContainerQueryEvaluator):
     15        (WebCore::Style::ContainerQueryEvaluator::selectContainer const):
     16        (WebCore::Style::ContainerQueryEvaluator::selectContainer):
     17
     18        For rules coming from a non-local scope, search query container starting from the originating element in that scope.
     19
     20        * style/ContainerQueryEvaluator.h:
     21        * style/ElementRuleCollector.cpp:
     22        (WebCore::Style::ElementRuleCollector::collectMatchingRulesForList):
     23        (WebCore::Style::ElementRuleCollector::containerQueriesMatch):
     24
     25        Pass rule's style scope ordinal so we can find the right scope.
     26
     27        * style/ElementRuleCollector.h:
     28
    1292022-04-08  Brent Fulgham  <bfulgham@apple.com>
    230
  • trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp

    r292592 r292635  
    3636#include "RenderView.h"
    3737#include "StyleRule.h"
     38#include "StyleScope.h"
    3839
    3940namespace WebCore::Style {
     
    4445};
    4546
    46 ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, PseudoId pseudoId, SelectorMatchingState* selectorMatchingState)
     47ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, PseudoId pseudoId, ScopeOrdinal scopeOrdinal, SelectorMatchingState* selectorMatchingState)
    4748    : m_element(element)
    4849    , m_pseudoId(pseudoId)
     50    , m_scopeOrdinal(scopeOrdinal)
    4951    , m_selectorMatchingState(selectorMatchingState)
    5052{
     
    8183    auto* cachedQueryContainers = m_selectorMatchingState ? &m_selectorMatchingState->queryContainers : nullptr;
    8284
    83     auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId);
     85    auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId, m_scopeOrdinal);
    8486    if (!container)
    8587        return { };
     
    8890}
    8991
    90 const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, const CachedQueryContainers* cachedQueryContainers, PseudoId pseudoId)
     92const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, const CachedQueryContainers* cachedQueryContainers, PseudoId pseudoId, ScopeOrdinal scopeOrdinal)
    9193{
    9294    // "For each element, the query container to be queried is selected from among the element’s
     
    124126    };
    125127
     128    auto findOriginatingElement = [&]() -> const Element* {
     129        // ::part() selectors can query its originating host, but not internal query containers inside the shadow tree.
     130        if (scopeOrdinal <= ScopeOrdinal::ContainingHost)
     131            return hostForScopeOrdinal(element, scopeOrdinal);
     132        // ::slotted() selectors can query containers inside the shadow tree, including the slot itself.
     133        if (scopeOrdinal >= ScopeOrdinal::FirstSlot && scopeOrdinal <= ScopeOrdinal::SlotLimit)
     134            return assignedSlotForScopeOrdinal(element, scopeOrdinal);
     135        return nullptr;
     136    };
     137
     138    if (auto* originatingElement = findOriginatingElement()) {
     139        // For selectors with pseudo elements, query containers can be established by the shadow-including inclusive ancestors of the ultimate originating element.
     140        for (auto* ancestor = originatingElement; ancestor; ancestor = ancestor->parentOrShadowHostElement()) {
     141            if (isContainerForQuery(*ancestor))
     142                return ancestor;
     143        }
     144        return nullptr;
     145    }
     146
    126147    if (cachedQueryContainers) {
    127148        for (auto& container : makeReversedRange(*cachedQueryContainers)) {
  • trunk/Source/WebCore/style/ContainerQueryEvaluator.h

    r292375 r292635  
    2727#include "ContainerQuery.h"
    2828#include "SelectorMatchingState.h"
     29#include "StyleScopeOrdinal.h"
    2930#include <wtf/Ref.h>
    3031
     
    3940class ContainerQueryEvaluator {
    4041public:
    41     ContainerQueryEvaluator(const Element&, PseudoId, SelectorMatchingState*);
     42    ContainerQueryEvaluator(const Element&, PseudoId, ScopeOrdinal, SelectorMatchingState*);
    4243
    4344    bool evaluate(const FilteredContainerQuery&) const;
    4445
    45     static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None);
     46    static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None, ScopeOrdinal = ScopeOrdinal::Element);
    4647
    4748private:
     
    5556    const Ref<const Element> m_element;
    5657    const PseudoId m_pseudoId;
     58    ScopeOrdinal m_scopeOrdinal;
    5759    SelectorMatchingState* m_selectorMatchingState;
    5860};
  • trunk/Source/WebCore/style/ElementRuleCollector.cpp

    r291594 r292635  
    488488            continue;
    489489
    490         if (matchRequest.ruleSet.hasContainerQueries() && !containerQueriesMatch(matchRequest.ruleSet.containerQueriesFor(ruleData)))
     490        if (matchRequest.ruleSet.hasContainerQueries() && !containerQueriesMatch(ruleData, matchRequest))
    491491            continue;
    492492
     
    506506}
    507507
    508 bool ElementRuleCollector::containerQueriesMatch(const Vector<const FilteredContainerQuery*>& queries)
    509 {
     508bool ElementRuleCollector::containerQueriesMatch(const RuleData& ruleData, const MatchRequest& matchRequest)
     509{
     510    auto queries = matchRequest.ruleSet.containerQueriesFor(ruleData);
     511
    510512    if (queries.isEmpty())
    511513        return true;
    512514
    513515    // "Style rules defined on an element inside multiple nested container queries apply when all of the wrapping container queries are true for that element."
    514     ContainerQueryEvaluator evaluator(element(), m_pseudoElementRequest.pseudoId, m_selectorMatchingState);
     516    ContainerQueryEvaluator evaluator(element(), m_pseudoElementRequest.pseudoId, matchRequest.styleScopeOrdinal, m_selectorMatchingState);
    515517    for (auto* query : queries) {
    516518        if (!evaluator.evaluate(*query))
  • trunk/Source/WebCore/style/ElementRuleCollector.h

    r291594 r292635  
    115115    void collectMatchingRulesForList(const RuleSet::RuleDataVector*, const MatchRequest&);
    116116    bool ruleMatches(const RuleData&, unsigned& specificity, ScopeOrdinal);
    117     bool containerQueriesMatch(const Vector<const FilteredContainerQuery*>&);
     117    bool containerQueriesMatch(const RuleData&, const MatchRequest&);
    118118
    119119    void sortMatchedRules();
Note: See TracChangeset for help on using the changeset viewer.