Title: [292635] trunk
Revision
292635
Author
an...@apple.com
Date
2022-04-08 14:35:00 -0700 (Fri, 08 Apr 2022)

Log 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:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (292634 => 292635)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-04-08 21:35:00 UTC (rev 292635)
@@ -1,3 +1,12 @@
+2022-04-08  Antti Koivisto  <an...@apple.com>
+
+        [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.
+
+        * web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt:
+
 2022-04-08  Alan Bujtas  <za...@apple.com>
 
         Do not use std::numeric_limits<float>::min() as the initial value to collect max values for glyph overflow

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt (292634 => 292635)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/container-for-shadow-dom-expected.txt	2022-04-08 21:35:00 UTC (rev 292635)
@@ -1,12 +1,12 @@
 
 PASS Match container in outer tree
 PASS Match container in same tree, not walking flat tree ancestors
-FAIL Match container in ::slotted selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
+PASS Match container in ::slotted selector's originating element tree
 PASS Match container in outer tree for :host
-FAIL Match container in ::part selector's originating element tree assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
-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)"
+PASS Match container in ::part selector's originating element tree
+PASS Match container for ::before in ::slotted selector's originating element tree
 PASS Match container in outer tree for :host::before
-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)"
-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)"
+PASS Match container for ::before in ::part selector's originating element tree
+PASS Match container for ::part selector's originating element tree for exportparts
 PASS Match container for slot light tree child fallback
 

Modified: trunk/Source/WebCore/ChangeLog (292634 => 292635)


--- trunk/Source/WebCore/ChangeLog	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/Source/WebCore/ChangeLog	2022-04-08 21:35:00 UTC (rev 292635)
@@ -1,3 +1,31 @@
+2022-04-08  Antti Koivisto  <an...@apple.com>
+
+        [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.
+
+        "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:
+
 2022-04-08  Brent Fulgham  <bfulg...@apple.com>
 
         Move WebGPU to WebCore/features.json and add <model> element

Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp (292634 => 292635)


--- trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp	2022-04-08 21:35:00 UTC (rev 292635)
@@ -35,6 +35,7 @@
 #include "MediaQuery.h"
 #include "RenderView.h"
 #include "StyleRule.h"
+#include "StyleScope.h"
 
 namespace WebCore::Style {
 
@@ -43,9 +44,10 @@
     CSSToLengthConversionData conversionData;
 };
 
-ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, PseudoId pseudoId, SelectorMatchingState* selectorMatchingState)
+ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, PseudoId pseudoId, ScopeOrdinal scopeOrdinal, SelectorMatchingState* selectorMatchingState)
     : m_element(element)
     , m_pseudoId(pseudoId)
+    , m_scopeOrdinal(scopeOrdinal)
     , m_selectorMatchingState(selectorMatchingState)
 {
 }
@@ -80,7 +82,7 @@
 
     auto* cachedQueryContainers = m_selectorMatchingState ? &m_selectorMatchingState->queryContainers : nullptr;
 
-    auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId);
+    auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId, m_scopeOrdinal);
     if (!container)
         return { };
 
@@ -87,7 +89,7 @@
     return makeSelectedContainer(*container);
 }
 
-const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, const CachedQueryContainers* cachedQueryContainers, PseudoId pseudoId)
+const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, const CachedQueryContainers* cachedQueryContainers, PseudoId pseudoId, ScopeOrdinal scopeOrdinal)
 {
     // "For each element, the query container to be queried is selected from among the element’s
     // ancestor query containers that have a valid container-type for all the container features
@@ -123,6 +125,25 @@
         return style->containerNames().contains(name);
     };
 
+    auto findOriginatingElement = [&]() -> const Element* {
+        // ::part() selectors can query its originating host, but not internal query containers inside the shadow tree.
+        if (scopeOrdinal <= ScopeOrdinal::ContainingHost)
+            return hostForScopeOrdinal(element, scopeOrdinal);
+        // ::slotted() selectors can query containers inside the shadow tree, including the slot itself.
+        if (scopeOrdinal >= ScopeOrdinal::FirstSlot && scopeOrdinal <= ScopeOrdinal::SlotLimit)
+            return assignedSlotForScopeOrdinal(element, scopeOrdinal);
+        return nullptr;
+    };
+
+    if (auto* originatingElement = findOriginatingElement()) {
+        // For selectors with pseudo elements, query containers can be established by the shadow-including inclusive ancestors of the ultimate originating element.
+        for (auto* ancestor = originatingElement; ancestor; ancestor = ancestor->parentOrShadowHostElement()) {
+            if (isContainerForQuery(*ancestor))
+                return ancestor;
+        }
+        return nullptr;
+    }
+
     if (cachedQueryContainers) {
         for (auto& container : makeReversedRange(*cachedQueryContainers)) {
             if (isContainerForQuery(container))

Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.h (292634 => 292635)


--- trunk/Source/WebCore/style/ContainerQueryEvaluator.h	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.h	2022-04-08 21:35:00 UTC (rev 292635)
@@ -26,6 +26,7 @@
 
 #include "ContainerQuery.h"
 #include "SelectorMatchingState.h"
+#include "StyleScopeOrdinal.h"
 #include <wtf/Ref.h>
 
 namespace WebCore {
@@ -38,11 +39,11 @@
 
 class ContainerQueryEvaluator {
 public:
-    ContainerQueryEvaluator(const Element&, PseudoId, SelectorMatchingState*);
+    ContainerQueryEvaluator(const Element&, PseudoId, ScopeOrdinal, SelectorMatchingState*);
 
     bool evaluate(const FilteredContainerQuery&) const;
 
-    static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None);
+    static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None, ScopeOrdinal = ScopeOrdinal::Element);
 
 private:
     struct SelectedContainer;
@@ -54,6 +55,7 @@
 
     const Ref<const Element> m_element;
     const PseudoId m_pseudoId;
+    ScopeOrdinal m_scopeOrdinal;
     SelectorMatchingState* m_selectorMatchingState;
 };
 

Modified: trunk/Source/WebCore/style/ElementRuleCollector.cpp (292634 => 292635)


--- trunk/Source/WebCore/style/ElementRuleCollector.cpp	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/Source/WebCore/style/ElementRuleCollector.cpp	2022-04-08 21:35:00 UTC (rev 292635)
@@ -487,7 +487,7 @@
         if (m_selectorMatchingState && m_selectorMatchingState->selectorFilter.fastRejectSelector(ruleData.descendantSelectorIdentifierHashes()))
             continue;
 
-        if (matchRequest.ruleSet.hasContainerQueries() && !containerQueriesMatch(matchRequest.ruleSet.containerQueriesFor(ruleData)))
+        if (matchRequest.ruleSet.hasContainerQueries() && !containerQueriesMatch(ruleData, matchRequest))
             continue;
 
         auto& rule = ruleData.styleRule();
@@ -505,13 +505,15 @@
     }
 }
 
-bool ElementRuleCollector::containerQueriesMatch(const Vector<const FilteredContainerQuery*>& queries)
+bool ElementRuleCollector::containerQueriesMatch(const RuleData& ruleData, const MatchRequest& matchRequest)
 {
+    auto queries = matchRequest.ruleSet.containerQueriesFor(ruleData);
+
     if (queries.isEmpty())
         return true;
 
     // "Style rules defined on an element inside multiple nested container queries apply when all of the wrapping container queries are true for that element."
-    ContainerQueryEvaluator evaluator(element(), m_pseudoElementRequest.pseudoId, m_selectorMatchingState);
+    ContainerQueryEvaluator evaluator(element(), m_pseudoElementRequest.pseudoId, matchRequest.styleScopeOrdinal, m_selectorMatchingState);
     for (auto* query : queries) {
         if (!evaluator.evaluate(*query))
             return false;

Modified: trunk/Source/WebCore/style/ElementRuleCollector.h (292634 => 292635)


--- trunk/Source/WebCore/style/ElementRuleCollector.h	2022-04-08 20:36:57 UTC (rev 292634)
+++ trunk/Source/WebCore/style/ElementRuleCollector.h	2022-04-08 21:35:00 UTC (rev 292635)
@@ -114,7 +114,7 @@
     void collectMatchingRules(const MatchRequest&);
     void collectMatchingRulesForList(const RuleSet::RuleDataVector*, const MatchRequest&);
     bool ruleMatches(const RuleData&, unsigned& specificity, ScopeOrdinal);
-    bool containerQueriesMatch(const Vector<const FilteredContainerQuery*>&);
+    bool containerQueriesMatch(const RuleData&, const MatchRequest&);
 
     void sortMatchedRules();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to