From 13249de7f6955cca9387b087e18b56c0789fc73e Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Sat, 12 Sep 2015 19:08:10 +1000 Subject: [PATCH] Bug 1202512 - Part 2: Make SelectorMatchesTree take a flags argument. r=bzbarsky --- layout/style/nsCSSRuleProcessor.cpp | 52 ++++++++++++++++++----------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index bf6dd8e1c52d..b3f2474899bb 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2384,10 +2384,20 @@ nsCSSRuleProcessor::RestrictedSelectorMatches( #define NS_IS_GREEDY_OPERATOR(ch) \ ((ch) == char16_t(' ') || (ch) == char16_t('~')) -static bool SelectorMatchesTree(Element* aPrevElement, - nsCSSSelector* aSelector, - TreeMatchContext& aTreeMatchContext, - bool aLookForRelevantLink) +/** + * Flags for SelectorMatchesTree. + */ +enum SelectorMatchesTreeFlags { + // Whether we still have not found the closest ancestor link element and + // thus have to check the current element for it. + eLookForRelevantLink = 0x1, +}; + +static bool +SelectorMatchesTree(Element* aPrevElement, + nsCSSSelector* aSelector, + TreeMatchContext& aTreeMatchContext, + SelectorMatchesTreeFlags aFlags) { MOZ_ASSERT(!aSelector || !aSelector->IsPseudoElement()); nsCSSSelector* selector = aSelector; @@ -2410,7 +2420,7 @@ static bool SelectorMatchesTree(Element* aPrevElement, if (char16_t('+') == selector->mOperator || char16_t('~') == selector->mOperator) { // The relevant link must be an ancestor of the node being matched. - aLookForRelevantLink = false; + aFlags = SelectorMatchesTreeFlags(aFlags & ~eLookForRelevantLink); nsIContent* parent = prevElement->GetParent(); if (parent) { if (aTreeMatchContext.mForStyling) @@ -2442,7 +2452,7 @@ static bool SelectorMatchesTree(Element* aPrevElement, if (selector->mOperator == '>' && element->IsActiveChildrenElement()) { Element* styleScope = aTreeMatchContext.mCurrentStyleScope; if (SelectorMatchesTree(element, selector, aTreeMatchContext, - aLookForRelevantLink)) { + aFlags)) { // It matched, don't try matching on the element at // all. return true; @@ -2458,10 +2468,10 @@ static bool SelectorMatchesTree(Element* aPrevElement, if (!element) { return false; } - NodeMatchContext nodeContext(EventStates(), - aLookForRelevantLink && - nsCSSRuleProcessor::IsLink(element)); - if (nodeContext.mIsRelevantLink) { + const bool isRelevantLink = (aFlags & eLookForRelevantLink) && + nsCSSRuleProcessor::IsLink(element); + NodeMatchContext nodeContext(EventStates(), isRelevantLink); + if (isRelevantLink) { // If we find an ancestor of the matched node that is a link // during the matching process, then it's the relevant link (see // constructor call above). @@ -2469,7 +2479,7 @@ static bool SelectorMatchesTree(Element* aPrevElement, // :visited (they'll just fail), we will always find such a node // during the selector matching process if there is a relevant // link that can influence selector matching. - aLookForRelevantLink = false; + aFlags = SelectorMatchesTreeFlags(aFlags & ~eLookForRelevantLink); aTreeMatchContext.SetHaveRelevantLink(); } if (SelectorMatches(element, selector, nodeContext, aTreeMatchContext, @@ -2493,8 +2503,7 @@ static bool SelectorMatchesTree(Element* aPrevElement, // doesn't matter much for performance since most selectors // don't match. (If most did, it might be faster...) Element* styleScope = aTreeMatchContext.mCurrentStyleScope; - if (SelectorMatchesTree(element, selector, aTreeMatchContext, - aLookForRelevantLink)) { + if (SelectorMatchesTree(element, selector, aTreeMatchContext, aFlags)) { return true; } // We want to reset mCurrentStyleScope on aTreeMatchContext @@ -2569,9 +2578,12 @@ void ContentEnumFunc(const RuleValue& value, nsCSSSelector* aSelector, if (SelectorMatches(data->mElement, selector, nodeContext, data->mTreeMatchContext, selectorFlags)) { nsCSSSelector *next = selector->mNext; - if (!next || SelectorMatchesTree(data->mElement, next, - data->mTreeMatchContext, - !nodeContext.mIsRelevantLink)) { + if (!next || + SelectorMatchesTree(data->mElement, next, + data->mTreeMatchContext, + nodeContext.mIsRelevantLink ? + SelectorMatchesTreeFlags(0) : + eLookForRelevantLink)) { css::StyleRule *rule = value.mRule; rule->RuleMatched(); data->mRuleWalker->Forward(rule); @@ -2745,7 +2757,7 @@ nsCSSRuleProcessor::HasStateDependentStyle(ElementDependentRuleProcessorData* aD aData->mTreeMatchContext, selectorFlags) && SelectorMatchesTree(aData->mElement, selector->mNext, aData->mTreeMatchContext, - false)) + SelectorMatchesTreeFlags(0))) { hint = nsRestyleHint(hint | possibleChange); } @@ -2881,7 +2893,8 @@ AttributeEnumFunc(nsCSSSelector* aSelector, SelectorMatches(data->mElement, aSelector, nodeContext, data->mTreeMatchContext, SelectorMatchesFlags::UNKNOWN) && SelectorMatchesTree(data->mElement, aSelector->mNext, - data->mTreeMatchContext, false)) { + data->mTreeMatchContext, + SelectorMatchesTreeFlags(0))) { aData->change = nsRestyleHint(aData->change | possibleChange); if (possibleChange & eRestyle_SomeDescendants) { aData->hintData.mSelectorsForDescendants.AppendElement(aRightmostSelector); @@ -3914,7 +3927,8 @@ nsCSSRuleProcessor::SelectorListMatches(Element* aElement, SelectorMatchesFlags::NONE)) { nsCSSSelector* next = sel->mNext; if (!next || - SelectorMatchesTree(aElement, next, aTreeMatchContext, false)) { + SelectorMatchesTree(aElement, next, aTreeMatchContext, + SelectorMatchesTreeFlags(0))) { return true; } }