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();