From 7374ca671633ac13b36b9c0be660c5c96690b302 Mon Sep 17 00:00:00 2001 From: FranklinDM Date: Mon, 20 Mar 2023 20:08:13 +0800 Subject: [PATCH] Issue #1593 - Follow-up: Fix :host matching from inside the shadow tree Previously, we'd match :host despite the element having a different shadow root from the one that we currently have. Also, there's a test where :host should be blocked from matching if it is a descendant of an explicit universal selector. --- layout/style/nsCSSRuleProcessor.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 692419b566..5618cfa6ac 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1965,17 +1965,35 @@ static bool SelectorMatches(Element* aElement, case CSSPseudoClassType::host: { + ShadowRoot* shadow = aElement->GetShadowRoot(); // In order to match :host, the element must be a shadow root host, // 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). - if (!aElement->GetShadowRoot() || + if (!shadow || aSelector->HasFeatureSelectors() || aSelectorFlags & SelectorMatchesFlags::IS_HOST_INACCESSIBLE) { return false; } + // We're matching :host from inside the shadow root. + if (!aTreeMatchContext.mOnlyMatchHostPseudo) { + // Check if the element has the same shadow root. + if (aTreeMatchContext.mScopedRoot) { + if (shadow != + aTreeMatchContext.mScopedRoot->GetShadowRoot()) { + return false; + } + } + // We were called elsewhere. + } + + // Reject if the next selector is an explicit universal selector. + if (aSelector->mNext && aSelector->mNext->mExplicitUniversal) { + 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.