diff options
author | FranklinDM <mrmineshafter17@gmail.com> | 2023-02-26 01:24:12 +0800 |
---|---|---|
committer | FranklinDM <mrmineshafter17@gmail.com> | 2023-02-26 01:32:13 +0800 |
commit | 468a37eab8cae1b56f94c8d83338fcfe8a92758e (patch) | |
tree | 2330847e2750b43680114d29c86cdc28b91900a7 /layout | |
parent | fc408bf1e2574e0ec651450756699e855ce75309 (diff) | |
download | uxp-468a37eab8cae1b56f94c8d83338fcfe8a92758e.tar.gz |
Issue #1593 - Follow-up: Fix :host selector matching
Previously, we would match `:host` if:
(a) we don't have any arguments and our parent is the shadow root, or;
(b) if any of the arguments match, then reject if we don't have a containing shadow
Revised, we would match `:host` if:
(Preconditions) The element must have a shadow root, the selector must not have any feature selectors, and it is not blocked from matching `:host` (e.g. .matches outside of the shadow root context)
(a) The selector does not have any arguments, or;
(b) It matches any of its arguments in the functional part of the pseudo-class
With this, we now pass these tests that were previously failing:
http://wpt.live/css/css-scoping/css-scoping-shadow-host-rule.html
http://wpt.live/css/css-scoping/host-descendant-002.html
http://wpt.live/css/css-scoping/host-multiple-001.html
Improved (1 less red box):
http://wpt.live/css/css-scoping/css-scoping-shadow-host-namespace.html
Diffstat (limited to 'layout')
-rw-r--r-- | layout/style/nsCSSRuleProcessor.cpp | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 03ab4f6b94..f637a063a6 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1357,7 +1357,10 @@ enum class SelectorMatchesFlags : uint8_t { // The selector is part of an argument to a functional pseudo-class or // pseudo-element. - IS_PSEUDO_CLASS_ARGUMENT = 1 << 2 + IS_PSEUDO_CLASS_ARGUMENT = 1 << 2, + + // The selector should be blocked from matching the :host pseudo-class. + IS_HOST_INACCESSIBLE = 1 << 3 }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SelectorMatchesFlags) @@ -1374,7 +1377,8 @@ static inline bool ActiveHoverQuirkMatches(nsCSSSelector* aSelector, // flags are unknown). aSelectorFlags & (SelectorMatchesFlags::UNKNOWN | SelectorMatchesFlags::HAS_PSEUDO_ELEMENT | - SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT)) { + SelectorMatchesFlags::IS_PSEUDO_CLASS_ARGUMENT | + SelectorMatchesFlags::IS_HOST_INACCESSIBLE)) { return false; } @@ -1933,17 +1937,17 @@ static bool SelectorMatches(Element* aElement, // we must be matching only against host pseudo selectors, and the // selector's context must be the shadow root (the selector must be // featureless, the left-most selector, and be in a shadow root - // style). The :host selector may also be be functional, with a - // compound selector. If this is the case, then also ensure that the - // host element matches against the compound - // selector. - - // We match automatically if GetParent() and GetShadowRoot() have - // the same result iff our selector list is empty. Without special - // casing this ahead of all other selector matching, it fails. - // Have not determined the cause. - if (!pseudoClass->u.mSelectorList && - aElement->GetParent() == aElement->GetShadowRoot()) { + // style). + if (!aElement->GetShadowRoot() || + aSelector->HasFeatureSelectors() || + aSelectorFlags & SelectorMatchesFlags::IS_HOST_INACCESSIBLE) { + return false; + } + + // The :host selector may also be be functional, with a compound + // selector. If this is the case, then also ensure that the host + // element matches against the compound selector. + if (!pseudoClass->u.mSelectorList) { break; } @@ -1952,25 +1956,15 @@ static bool SelectorMatches(Element* aElement, // selector check under SelectorMatches. NodeMatchContext nodeContext(EventStates(), aNodeMatchContext.mIsRelevantLink); - if (SelectorListMatches(aElement, - pseudoClass, - nodeContext, - aTreeMatchContext)) { - break; - } - - // Finally, with the exception of the two above cases, make sure we - // don't match if GetContainingShadow() returns null. For whatever - // reason, we can't test for this case first. - - if (aElement->GetContainingShadow() == nullptr) { + if (!SelectorListMatches(aElement, + pseudoClass, + nodeContext, + aTreeMatchContext)) { return false; } - } break; - case CSSPseudoClassType::hostContext: { // In order to match host-context, the element must be a @@ -4135,11 +4129,14 @@ nsCSSRuleProcessor::RestrictedSelectorListMatches(Element* aElement, "SelectorMatchesTree call"); NodeMatchContext nodeContext(EventStates(), false); + SelectorMatchesFlags flags = aElement->IsInShadowTree() ? + SelectorMatchesFlags::NONE : + SelectorMatchesFlags::IS_HOST_INACCESSIBLE; return SelectorListMatches(aElement, aSelectorList, nodeContext, aTreeMatchContext, - SelectorMatchesFlags::NONE); + flags); } void |