Diff
Modified: trunk/LayoutTests/ChangeLog (292818 => 292819)
--- trunk/LayoutTests/ChangeLog 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/LayoutTests/ChangeLog 2022-04-13 19:12:47 UTC (rev 292819)
@@ -1,3 +1,12 @@
+2022-04-13 Antti Koivisto <[email protected]>
+
+ [CSS Container Queries] Correct container selection for pseudo-elements
+ https://bugs.webkit.org/show_bug.cgi?id=239279
+
+ Reviewed by Simon Fraser.
+
+ * TestExpectations:
+
2022-04-13 Alan Bujtas <[email protected]>
REGRESSION (r292043): [ Mac ] fast/block/positioning/fixed-container-with-relative-parent.html is a flaky image failure
Modified: trunk/LayoutTests/TestExpectations (292818 => 292819)
--- trunk/LayoutTests/TestExpectations 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/LayoutTests/TestExpectations 2022-04-13 19:12:47 UTC (rev 292819)
@@ -4701,7 +4701,6 @@
# Container queries
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/custom-layout-container-001.https.html [ ImageOnlyFailure ]
-webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/pseudo-elements-002.html [ ImageOnlyFailure ]
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/svg-foreignobject-no-size-container.html [ Skip ]
webkit.org/b/229659 imported/w3c/web-platform-tests/css/css-contain/container-queries/inline-size-bfc-floats.html [ ImageOnlyFailure ]
Modified: trunk/Source/WebCore/ChangeLog (292818 => 292819)
--- trunk/Source/WebCore/ChangeLog 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/Source/WebCore/ChangeLog 2022-04-13 19:12:47 UTC (rev 292819)
@@ -1,3 +1,30 @@
+2022-04-13 Antti Koivisto <[email protected]>
+
+ [CSS Container Queries] Correct container selection for pseudo-elements
+ https://bugs.webkit.org/show_bug.cgi?id=239279
+
+ Reviewed by Simon Fraser.
+
+ The element itself may be the container for its pseudo-elements.
+
+ * css/CSSPrimitiveValue.cpp:
+ (WebCore::CSSPrimitiveValue::computeNonCalcLengthDouble):
+ * style/ContainerQueryEvaluator.cpp:
+ (WebCore::Style::ContainerQueryEvaluator::ContainerQueryEvaluator):
+ (WebCore::Style::ContainerQueryEvaluator::selectContainer const):
+ (WebCore::Style::ContainerQueryEvaluator::selectContainer):
+ * style/ContainerQueryEvaluator.h:
+
+ Instead of passing the pseudo-element being matched, pass a container selection mode flag. The exact pseudo-element type
+ doesn't matter.
+
+ * style/ElementRuleCollector.cpp:
+ (WebCore::Style::ElementRuleCollector::containerQueriesMatch):
+
+ We need to use the pseudo-element mode when matching a rule that matches a pseudo-element, even when we are not actually resolving
+ the pseudo element. This is because regular element rule matching sets the style bits that indicate what pseudo-elements the
+ element has.
+
2022-04-13 Alan Bujtas <[email protected]>
REGRESSION (r292043): [ Mac ] fast/block/positioning/fixed-container-with-relative-parent.html is a flaky image failure
Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.cpp (292818 => 292819)
--- trunk/Source/WebCore/css/CSSPrimitiveValue.cpp 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.cpp 2022-04-13 19:12:47 UTC (rev 292819)
@@ -826,7 +826,7 @@
if (!conversionData.element())
return nullptr;
// FIXME: Use cached query containers when available.
- auto* container = Style::ContainerQueryEvaluator::selectContainer(axis, nullString(), *conversionData.element(), nullptr);
+ auto* container = Style::ContainerQueryEvaluator::selectContainer(axis, nullString(), *conversionData.element());
if (!container)
return nullptr;
return dynamicDowncast<RenderBox>(container->renderer());
Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp (292818 => 292819)
--- trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.cpp 2022-04-13 19:12:47 UTC (rev 292819)
@@ -44,9 +44,9 @@
CSSToLengthConversionData conversionData;
};
-ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, PseudoId pseudoId, ScopeOrdinal scopeOrdinal, SelectorMatchingState* selectorMatchingState)
+ContainerQueryEvaluator::ContainerQueryEvaluator(const Element& element, SelectionMode selectionMode, ScopeOrdinal scopeOrdinal, SelectorMatchingState* selectorMatchingState)
: m_element(element)
- , m_pseudoId(pseudoId)
+ , m_selectionMode(selectionMode)
, m_scopeOrdinal(scopeOrdinal)
, m_selectorMatchingState(selectorMatchingState)
{
@@ -82,7 +82,7 @@
auto* cachedQueryContainers = m_selectorMatchingState ? &m_selectorMatchingState->queryContainers : nullptr;
- auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), cachedQueryContainers, m_pseudoId, m_scopeOrdinal);
+ auto* container = selectContainer(filteredContainerQuery.axisFilter, filteredContainerQuery.nameFilter, m_element.get(), m_selectionMode, m_scopeOrdinal, cachedQueryContainers);
if (!container)
return { };
@@ -89,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, ScopeOrdinal scopeOrdinal)
+const Element* ContainerQueryEvaluator::selectContainer(OptionSet<CQ::Axis> axes, const String& name, const Element& element, SelectionMode selectionMode, ScopeOrdinal scopeOrdinal, const CachedQueryContainers* cachedQueryContainers)
{
// "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
@@ -144,6 +144,11 @@
return nullptr;
}
+ if (selectionMode == SelectionMode::PseudoElement) {
+ if (isContainerForQuery(element))
+ return &element;
+ }
+
if (cachedQueryContainers) {
for (auto& container : makeReversedRange(*cachedQueryContainers)) {
if (isContainerForQuery(container))
@@ -152,11 +157,6 @@
return { };
}
- if (pseudoId != PseudoId::None) {
- if (isContainerForQuery(element))
- return &element;
- }
-
for (auto* ancestor = element.parentOrShadowHostElement(); ancestor; ancestor = ancestor->parentOrShadowHostElement()) {
if (isContainerForQuery(*ancestor))
return ancestor;
Modified: trunk/Source/WebCore/style/ContainerQueryEvaluator.h (292818 => 292819)
--- trunk/Source/WebCore/style/ContainerQueryEvaluator.h 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/Source/WebCore/style/ContainerQueryEvaluator.h 2022-04-13 19:12:47 UTC (rev 292819)
@@ -39,11 +39,12 @@
class ContainerQueryEvaluator {
public:
- ContainerQueryEvaluator(const Element&, PseudoId, ScopeOrdinal, SelectorMatchingState*);
+ enum class SelectionMode : bool { Element, PseudoElement };
+ ContainerQueryEvaluator(const Element&, SelectionMode, ScopeOrdinal, SelectorMatchingState*);
bool evaluate(const FilteredContainerQuery&) const;
- static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, const CachedQueryContainers*, PseudoId = PseudoId::None, ScopeOrdinal = ScopeOrdinal::Element);
+ static const Element* selectContainer(OptionSet<CQ::Axis>, const String& name, const Element&, SelectionMode = SelectionMode::Element, ScopeOrdinal = ScopeOrdinal::Element, const CachedQueryContainers* = nullptr);
private:
struct SelectedContainer;
@@ -54,8 +55,8 @@
EvaluationResult evaluateSizeFeature(const CQ::SizeFeature&, const SelectedContainer&) const;
const Ref<const Element> m_element;
- const PseudoId m_pseudoId;
- ScopeOrdinal m_scopeOrdinal;
+ const SelectionMode m_selectionMode;
+ const ScopeOrdinal m_scopeOrdinal;
SelectorMatchingState* m_selectorMatchingState;
};
Modified: trunk/Source/WebCore/style/ElementRuleCollector.cpp (292818 => 292819)
--- trunk/Source/WebCore/style/ElementRuleCollector.cpp 2022-04-13 18:53:13 UTC (rev 292818)
+++ trunk/Source/WebCore/style/ElementRuleCollector.cpp 2022-04-13 19:12:47 UTC (rev 292819)
@@ -512,8 +512,11 @@
if (queries.isEmpty())
return true;
+ // Style bits indicating which pseudo-elements match are set during regular element matching. Container queries need to be evaluate in the right mode.
+ auto selectionMode = ruleData.canMatchPseudoElement() ? ContainerQueryEvaluator::SelectionMode::PseudoElement : ContainerQueryEvaluator::SelectionMode::Element;
+
// "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, matchRequest.styleScopeOrdinal, m_selectorMatchingState);
+ ContainerQueryEvaluator evaluator(element(), selectionMode, matchRequest.styleScopeOrdinal, m_selectorMatchingState);
for (auto* query : queries) {
if (!evaluator.evaluate(*query))
return false;