1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 13:58:49 +00:00

Issue #1592 - Part 4: Walk ::slotted()-containing rules for slottables

- Check against all selector parts and not the leftmost selector only for ::slotted()
- Walk rules for ::slotted() regardless if the shadow root is opened/closed
- Ensure that ::slotted() rules are walked in the right order
- Fix ::slotted inheritance from topmost shadow root
This commit is contained in:
FranklinDM
2023-03-18 12:43:51 +08:00
committed by roytam1
parent 92b31dd255
commit 518c41fd7a
3 changed files with 104 additions and 47 deletions
+57 -47
View File
@@ -2686,6 +2686,12 @@ SelectorMatchesTree(Element* aPrevElement,
aTreeMatchContext.mCurrentStyleScope = styleScope;
}
selector = selector->mNext;
if (!selector &&
!aTreeMatchContext.mIsTopmostScope &&
aTreeMatchContext.mRestrictToSlottedPseudo &&
aTreeMatchContext.mScopedRoot != element) {
return false;
}
}
else {
// for adjacent sibling and child combinators, if we didn't find
@@ -2764,6 +2770,52 @@ static bool SelectorListMatches(Element* aElement,
aPreventComplexSelectors);
}
static
inline bool LookForTargetPseudo(nsCSSSelector* aSelector,
TreeMatchContext* aMatchContext,
nsRestyleHint* possibleChange) {
if (aMatchContext->mOnlyMatchHostPseudo) {
while (aSelector && aSelector->mNext != nullptr) {
aSelector = aSelector->mNext;
}
for (nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList;
pseudoClass;
pseudoClass = pseudoClass->mNext) {
if (pseudoClass->mType == CSSPseudoClassType::host ||
pseudoClass->mType == CSSPseudoClassType::hostContext) {
if (possibleChange) {
// :host-context will walk ancestors looking for a match of a
// compound selector, thus any changes to ancestors may require
// restyling the subtree.
*possibleChange |= eRestyle_Subtree;
}
return true;
}
}
return false;
}
else if (aMatchContext->mRestrictToSlottedPseudo) {
for (nsCSSSelector* selector = aSelector;
selector;
selector = selector->mNext) {
if (!selector->mPseudoClassList) {
continue;
}
for (nsPseudoClassList* pseudoClass = selector->mPseudoClassList;
pseudoClass;
pseudoClass = pseudoClass->mNext) {
if (pseudoClass->mType == CSSPseudoClassType::slotted) {
return true;
}
}
}
return false;
}
// We're not restricted to a specific pseudo-class.
return true;
}
static inline
void ContentEnumFunc(const RuleValue& value, nsCSSSelector* aSelector,
ElementDependentRuleProcessorData* data, NodeMatchContext& nodeContext,
@@ -2778,29 +2830,11 @@ void ContentEnumFunc(const RuleValue& value, nsCSSSelector* aSelector,
// We won't match; nothing else to do here
return;
}
// If mOnlyMatchHostPseudo is set, then we only want to match against
// selectors that contain a :host-context pseudo class.
if (data->mTreeMatchContext.mOnlyMatchHostPseudo) {
nsCSSSelector* selector = aSelector;
while (selector && selector->mNext != nullptr) {
selector = selector->mNext;
}
bool seenHostPseudo = false;
for (nsPseudoClassList* pseudoClass = selector->mPseudoClassList;
pseudoClass;
pseudoClass = pseudoClass->mNext) {
if (pseudoClass->mType == CSSPseudoClassType::host ||
pseudoClass->mType == CSSPseudoClassType::hostContext) {
seenHostPseudo = true;
break;
}
}
if (!seenHostPseudo) {
return;
}
if (!LookForTargetPseudo(aSelector, &data->mTreeMatchContext, nullptr)) {
return;
}
if (!data->mTreeMatchContext.SetStyleScopeForSelectorMatching(data->mElement,
data->mScope)) {
// The selector is for a rule in a scoped style sheet, and the subject
@@ -3145,35 +3179,11 @@ AttributeEnumFunc(nsCSSSelector* aSelector,
nsRestyleHint possibleChange =
RestyleHintForSelectorWithAttributeChange(aData->change,
aSelector, aRightmostSelector);
// If mOnlyMatchHostPseudo is set, then we only want to match against
// selectors that contain a :host-context pseudo class.
if (data->mTreeMatchContext.mOnlyMatchHostPseudo) {
nsCSSSelector* selector = aSelector;
while (selector && selector->mNext != nullptr) {
selector = selector->mNext;
}
bool seenHostPseudo = false;
for (nsPseudoClassList* pseudoClass = selector->mPseudoClassList;
pseudoClass;
pseudoClass = pseudoClass->mNext) {
if (pseudoClass->mType == CSSPseudoClassType::host ||
pseudoClass->mType == CSSPseudoClassType::hostContext) {
// :host-context will walk ancestors looking for a match of a compound
// selector, thus any changes to ancestors may require restyling the
// subtree.
possibleChange |= eRestyle_Subtree;
seenHostPseudo = true;
break;
}
}
if (!seenHostPseudo) {
return;
}
if (!LookForTargetPseudo(aSelector, &data->mTreeMatchContext, &possibleChange)) {
return;
}
// If, ignoring eRestyle_SomeDescendants, enumData->change already includes
// all the bits of possibleChange, don't bother calling SelectorMatches, since
// even if it returns false enumData->change won't change. If possibleChange