From 2f9d6df5b4224933ec5e4f8feaba45681a67e0df Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 11 Dec 2009 02:37:40 -0500 Subject: [PATCH] Bug 525608 part 7. Make tree pseudos use a separate hashtable instead of riding along on the rulehash. r=dbaron --- layout/style/nsCSSRuleProcessor.cpp | 175 +++++++++++---------------- layout/style/nsCSSRuleProcessor.h | 4 +- layout/style/nsHTMLCSSStyleSheet.cpp | 8 +- layout/style/nsHTMLStyleSheet.cpp | 5 +- layout/style/nsHTMLStyleSheet.h | 4 +- layout/style/nsIStyleRuleProcessor.h | 17 ++- layout/style/nsRuleProcessorData.h | 21 ++-- layout/style/nsStyleSet.cpp | 114 ++++++----------- layout/style/nsStyleSet.h | 20 +-- layout/style/nsTransitionManager.cpp | 4 +- layout/style/nsTransitionManager.h | 4 +- 11 files changed, 156 insertions(+), 220 deletions(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 60f2a4e4f38..aa1d884c36b 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -365,14 +365,12 @@ public: void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID, const nsAttrValue* aClassList, RuleEnumFunc aFunc, RuleProcessorData* aData); - void EnumerateTagRules(nsIAtom* aTag, - RuleEnumFunc aFunc, void* aData); PLArenaPool& Arena() { return mArena; } protected: void PrependRuleToTable(PLDHashTable* aTable, const void* aKey, RuleValue* aRuleInfo); - void PrependRuleToTagTable(const void* aKey, RuleValue* aRuleInfo); + void PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo); void PrependUniversalRule(RuleValue* aRuleInfo); // All rule values in these hashtables are arena allocated @@ -396,15 +394,12 @@ protected: PRUint32 mIdSelectors; PRUint32 mElementsMatched; - PRUint32 mPseudosMatched; PRUint32 mElementUniversalCalls; PRUint32 mElementNameSpaceCalls; PRUint32 mElementTagCalls; PRUint32 mElementClassCalls; PRUint32 mElementIdCalls; - - PRUint32 mPseudoTagCalls; #endif // RULE_HASH_STATS }; @@ -420,13 +415,11 @@ RuleHash::RuleHash(PRBool aQuirksMode) mClassSelectors(0), mIdSelectors(0), mElementsMatched(0), - mPseudosMatched(0), mElementUniversalCalls(0), mElementNameSpaceCalls(0), mElementTagCalls(0), mElementClassCalls(0), - mElementIdCalls(0), - mPseudoTagCalls(0) + mElementIdCalls(0) #endif { MOZ_COUNT_CTOR(RuleHash); @@ -454,17 +447,14 @@ RuleHash::~RuleHash() printf( "RuleHash(%p):\n" " Selectors: Universal (%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\n" -" Content Nodes: Elements(%u) Pseudo-Elements(%u)\n" +" Content Nodes: Elements(%u)\n" " Element Calls: Universal(%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\n" -" Pseudo-Element Calls: Tag(%u)\n", static_cast(this), mUniversalSelectors, mNameSpaceSelectors, mTagSelectors, mClassSelectors, mIdSelectors, mElementsMatched, - mPseudosMatched, mElementUniversalCalls, mElementNameSpaceCalls, mElementTagCalls, - mElementClassCalls, mElementIdCalls, - mPseudoTagCalls); + mElementClassCalls, mElementIdCalls); #ifdef PRINT_UNIVERSAL_RULES { RuleValue* value = mUniversalRules; @@ -511,19 +501,26 @@ void RuleHash::PrependRuleToTable(PLDHashTable* aTable, const void* aKey, entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules); } -void RuleHash::PrependRuleToTagTable(const void* aKey, RuleValue* aRuleInfo) +static void +DoPrependRuleToTagTable(PLDHashTable* aTable, nsIAtom* aKey, + RuleValue* aRuleInfo, PRInt32 aBackwardsIndex) { // Get a new or exisiting entry - RuleHashTagTableEntry *entry = static_cast - (PL_DHashTableOperate(&mTagTable, aKey, PL_DHASH_ADD)); - if (!entry) - return; + RuleHashTagTableEntry *entry = static_cast + (PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD)); + if (!entry) + return; - entry->mTag = const_cast(static_cast(aKey)); + entry->mTag = aKey; - // This may give the same rule two different rule counts, but that is OK - // because we never combine two different entries in the tag table. - entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules); + // This may give the same rule two different rule counts, but that is OK + // because we never combine two different entries in a tag table. + entry->mRules = aRuleInfo->Add(aBackwardsIndex, entry->mRules); +} + +void RuleHash::PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo) +{ + DoPrependRuleToTagTable(&mTagTable, aKey, aRuleInfo, mRuleCount++); } void RuleHash::PrependUniversalRule(RuleValue *aRuleInfo) @@ -671,22 +668,6 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, } } -void RuleHash::EnumerateTagRules(nsIAtom* aTag, RuleEnumFunc aFunc, void* aData) -{ - RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP)); - - RULE_HASH_STAT_INCREMENT(mPseudosMatched); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - RuleValue *tagValue = entry->mRules; - do { - RULE_HASH_STAT_INCREMENT(mPseudoTagCalls); - (*aFunc)(tagValue->mRule, tagValue->mSelector, aData); - tagValue = tagValue->mNext; - } while (tagValue); - } -} - //-------------------------------- // Attribute selectors hash table. @@ -730,12 +711,17 @@ struct RuleCascadeData { PL_DHashTableInit(&mAnonBoxRules, &RuleHash_TagTable_Ops, nsnull, sizeof(RuleHashTagTableEntry), 16); memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes)); +#ifdef MOZ_XUL + PL_DHashTableInit(&mXULTreeRules, &RuleHash_TagTable_Ops, nsnull, + sizeof(RuleHashTagTableEntry), 16); +#endif } ~RuleCascadeData() { PL_DHashTableFinish(&mAttributeSelectors); PL_DHashTableFinish(&mAnonBoxRules); + PL_DHashTableFinish(&mXULTreeRules); for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) { delete mPseudoElementRuleHashes[i]; } @@ -748,6 +734,9 @@ struct RuleCascadeData { nsTArray mIDSelectors; PLDHashTable mAttributeSelectors; PLDHashTable mAnonBoxRules; +#ifdef MOZ_XUL + PLDHashTable mXULTreeRules; +#endif nsTArray mFontFaceRules; @@ -2090,68 +2079,34 @@ nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData) return NS_OK; } -static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector, - void* aData) -{ - PseudoRuleProcessorData* data = (PseudoRuleProcessorData*)aData; - - if (!aSelector->IsPseudoElement()) - return; - - NS_ASSERTION(aSelector->mLowercaseTag == data->mPseudoTag, "RuleHash failure"); - PRBool matches = PR_TRUE; - if (data->mComparator) - data->mComparator->PseudoMatches(data->mPseudoTag, aSelector, &matches); - - if (matches) { - nsCSSSelector *selector = aSelector->mNext; - - if (selector) { // test next selector specially - if (PRUnichar('+') == selector->mOperator) { - return; // not valid here, can't match - } - if (SelectorMatches(*data, selector, 0, PR_TRUE)) { - selector = selector->mNext; - } - else { - if (PRUnichar('>') == selector->mOperator) { - return; // immediate parent didn't match - } - } - } - - if (selector && - (! SelectorMatchesTree(*data, selector, PR_TRUE))) { - return; // remaining selectors didn't match - } - - // for performance, require that every implementation of - // nsICSSStyleRule return the same pointer for nsIStyleRule (why - // would anything multiply inherit nsIStyleRule anyway?) -#ifdef DEBUG - nsCOMPtr iRule = do_QueryInterface(aRule); - NS_ASSERTION(static_cast(aRule) == iRule.get(), - "Please fix QI so this performance optimization is valid"); -#endif - data->mRuleWalker->Forward(static_cast(aRule)); - // nsStyleSet will deal with the !important rule - } -} - +#ifdef MOZ_XUL NS_IMETHODIMP -nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData) +nsCSSRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData) { NS_PRECONDITION(aData->mContent->IsNodeOfType(nsINode::eELEMENT), "content must be element"); RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext); - if (cascade) { - cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag, - PseudoEnumFunc, aData); + if (cascade && cascade->mXULTreeRules.entryCount) { + RuleHashTagTableEntry* entry = static_cast + (PL_DHashTableOperate(&cascade->mXULTreeRules, aData->mPseudoTag, + PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + for (RuleValue *value = entry->mRules; value; value = value->mNext) { + PRBool matches = PR_TRUE; + aData->mComparator->PseudoMatches(aData->mPseudoTag, value->mSelector, + &matches); + if (matches) { + ContentEnumFunc(value->mRule, value->mSelector->mNext, + static_cast(aData)); + } + } + } } return NS_OK; } +#endif inline PRBool IsSiblingOperator(PRUnichar oper) @@ -2407,9 +2362,9 @@ PRBool IsStateSelector(nsCSSSelector& aSelector) } static PRBool -AddRule(RuleValue* aRuleInfo, void* aCascade) +AddRule(RuleValue* aRuleInfo, RuleCascadeData* aCascade) { - RuleCascadeData *cascade = static_cast(aCascade); + RuleCascadeData * const cascade = aCascade; // Build the rule hash. nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType(); @@ -2429,18 +2384,34 @@ AddRule(RuleValue* aRuleInfo, void* aCascade) aRuleInfo->mSelector = aRuleInfo->mSelector->mNext; ruleHash->PrependRule(aRuleInfo); } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { - RuleHashTagTableEntry *entry = static_cast - (PL_DHashTableOperate(&cascade->mAnonBoxRules, - aRuleInfo->mSelector->mLowercaseTag, - PL_DHASH_ADD)); - if (!entry) - return PR_FALSE; + NS_ASSERTION(!aRuleInfo->mSelector->mCasedTag && + !aRuleInfo->mSelector->mIDList && + !aRuleInfo->mSelector->mClassList && + !aRuleInfo->mSelector->mPseudoClassList && + !aRuleInfo->mSelector->mAttrList && + !aRuleInfo->mSelector->mNegations && + !aRuleInfo->mSelector->mNext && + aRuleInfo->mSelector->mNameSpace == kNameSpaceID_Unknown, + "Parser messed up with anon box selector"); - entry->mTag = aRuleInfo->mSelector->mLowercaseTag; // Index doesn't matter here, since we'll just be walking these // rules in order; just pass 0. - entry->mRules = aRuleInfo->Add(0, entry->mRules); - } else { + DoPrependRuleToTagTable(&cascade->mAnonBoxRules, + aRuleInfo->mSelector->mLowercaseTag, + aRuleInfo, 0); + } +#ifdef MOZ_XUL + else if (pseudoType == nsCSSPseudoElements::ePseudo_XULTree) { + // Index doesn't matter here, since we'll just be walking these + // rules in order; just pass 0. + DoPrependRuleToTagTable(&cascade->mXULTreeRules, + aRuleInfo->mSelector->mLowercaseTag, + aRuleInfo, 0); + } +#endif + else { + NS_ASSERTION(pseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement, + "Unexpected pseudoType"); cascade->mRuleHash.PrependRule(aRuleInfo); } diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index e3b2626e657..9bfe38f0720 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -95,7 +95,9 @@ public: NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData); - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData); +#ifdef MOZ_XUL + NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData); +#endif NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, nsReStyleHint* aResult); diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 8140804be67..e8352989934 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -93,7 +93,9 @@ public: NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData); - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData); +#ifdef MOZ_XUL + NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData); +#endif NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, nsReStyleHint* aResult); @@ -170,11 +172,13 @@ HTMLCSSStyleSheetImpl::RulesMatching(AnonBoxRuleProcessorData* aData) return NS_OK; } +#ifdef MOZ_XUL NS_IMETHODIMP -HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData) +HTMLCSSStyleSheetImpl::RulesMatching(XULTreeRuleProcessorData* aData) { return NS_OK; } +#endif NS_IMETHODIMP HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument) diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 2183bdf1081..301ba8c4eaf 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -581,12 +581,13 @@ nsHTMLStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData) return NS_OK; } +#ifdef MOZ_XUL NS_IMETHODIMP -nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData) +nsHTMLStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData) { return NS_OK; } - +#endif // nsIStyleSheet api NS_IMETHODIMP diff --git a/layout/style/nsHTMLStyleSheet.h b/layout/style/nsHTMLStyleSheet.h index 46b69abf7c9..8f35a136ab0 100644 --- a/layout/style/nsHTMLStyleSheet.h +++ b/layout/style/nsHTMLStyleSheet.h @@ -81,7 +81,9 @@ public: NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData); NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData); NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData); - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData); +#ifdef MOZ_XUL + NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData); +#endif NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, nsReStyleHint* aResult); virtual nsReStyleHint diff --git a/layout/style/nsIStyleRuleProcessor.h b/layout/style/nsIStyleRuleProcessor.h index 8acba443e7b..63e95249b64 100644 --- a/layout/style/nsIStyleRuleProcessor.h +++ b/layout/style/nsIStyleRuleProcessor.h @@ -53,15 +53,18 @@ struct RuleProcessorData; struct ElementRuleProcessorData; struct PseudoElementRuleProcessorData; struct AnonBoxRuleProcessorData; -struct PseudoRuleProcessorData; +#ifdef MOZ_XUL +struct XULTreeRuleProcessorData; +#endif struct StateRuleProcessorData; struct AttributeRuleProcessorData; class nsPresContext; -// IID for the nsIStyleRuleProcessor interface {a4ec760e-6bfb-4b9f-bd08-9d1c23b700f6} +// IID for the nsIStyleRuleProcessor interface +// {ec92bc0c-9518-48ea-9289-74e654659be9} #define NS_ISTYLE_RULE_PROCESSOR_IID \ -{ 0xa4ec760e, 0x6bfb, 0x4b9f, \ - { 0xbd, 0x08, 0x9d, 0x1c, 0x23, 0xb7, 0x00, 0xf6 } } +{ 0xec92bc0c, 0x9518, 0x48ea, \ + { 0x92, 0x89, 0x74, 0xe6, 0x54, 0x65, 0x9b, 0xe9 } } /* The style rule processor interface is a mechanism to separate the matching * of style rules from style sheet instances. @@ -98,11 +101,13 @@ public: */ NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData) = 0; +#ifdef MOZ_XUL /** * Just like the previous |RulesMatching|, except for a given content - * node and pseudo. + * node and tree pseudo. */ - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0; + NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData) = 0; +#endif /** * Return how (as described by nsReStyleHint) style can depend on a diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index 54e0fb878ca..26e21b8c529 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -211,24 +211,27 @@ struct AnonBoxRuleProcessorData { nsRuleWalker* mRuleWalker; }; -struct PseudoRuleProcessorData : public RuleProcessorData { - PseudoRuleProcessorData(nsPresContext* aPresContext, - nsIContent* aParentContent, - nsIAtom* aPseudoTag, - nsICSSPseudoComparator* aComparator, - nsRuleWalker* aRuleWalker) - : RuleProcessorData(aPresContext, aParentContent, aRuleWalker) +#ifdef MOZ_XUL +struct XULTreeRuleProcessorData : public RuleProcessorData { + XULTreeRuleProcessorData(nsPresContext* aPresContext, + nsIContent* aParentContent, + nsRuleWalker* aRuleWalker, + nsIAtom* aPseudoTag, + nsICSSPseudoComparator* aComparator) + : RuleProcessorData(aPresContext, aParentContent, aRuleWalker), + mPseudoTag(aPseudoTag), + mComparator(aComparator) { NS_PRECONDITION(aPresContext, "null pointer"); NS_PRECONDITION(aPseudoTag, "null pointer"); NS_PRECONDITION(aRuleWalker, "null pointer"); - mPseudoTag = aPseudoTag; - mComparator = aComparator; + NS_PRECONDITION(aComparator, "must have a comparator"); } nsIAtom* mPseudoTag; nsICSSPseudoComparator* mComparator; }; +#endif struct StateRuleProcessorData : public RuleProcessorData { StateRuleProcessorData(nsPresContext* aPresContext, diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 4be43f91407..8224f3c4f3c 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -411,12 +411,11 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable) #endif } +template static PRBool EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData) { - ElementRuleProcessorData* data = - static_cast(aData); - + T* data = static_cast(aData); aProcessor->RulesMatching(data); return PR_TRUE; } @@ -748,7 +747,8 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent, if (aContent && presContext) { nsRuleWalker ruleWalker(mRuleTree); ElementRuleProcessorData data(presContext, aContent, &ruleWalker); - FileRules(EnumRulesMatching, &data, aContent, &ruleWalker); + FileRules(EnumRulesMatching, &data, aContent, + &ruleWalker); result = GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(), nsnull, nsCSSPseudoElements::ePseudo_NotPseudoElement).get(); @@ -812,65 +812,6 @@ nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType, aRuleWalker->Forward(mFirstLineRule); } -static PRBool -EnumPseudoRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData) -{ - PseudoRuleProcessorData* data = - static_cast(aData); - - aProcessor->RulesMatching(data); - return PR_TRUE; -} - -already_AddRefed -nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent, - nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, - nsStyleContext* aParentContext, - nsICSSPseudoComparator* aComparator) -{ - NS_ENSURE_FALSE(mInShutdown, nsnull); - - nsStyleContext* result = nsnull; - nsPresContext *presContext = PresContext(); - - NS_ASSERTION(aPseudoTag, "must have pseudo tag"); - NS_ASSERTION(!aParentContent || - aParentContent->IsNodeOfType(nsINode::eELEMENT), - "content (if non-null) must be element"); - NS_ASSERTION(aParentContent || - nsCSSAnonBoxes::IsAnonBox(aPseudoTag), - "null content must correspond to anonymous box"); - NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) || - nsCSSPseudoElements::IsPseudoElement(aPseudoTag), - "aPseudoTag must be pseudo-element or anonymous box"); - NS_ASSERTION(nsCSSPseudoElements::GetPseudoType(aPseudoTag) == aPseudoType, - "Incorrect pseudo type"); - - if (aPseudoTag && presContext) { - nsRuleWalker ruleWalker(mRuleTree); - PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag, - aComparator, &ruleWalker); - FileRules(EnumPseudoRulesMatching, &data, aParentContent, &ruleWalker); - - result = GetContext(presContext, aParentContext, - ruleWalker.GetCurrentNode(), aPseudoTag, - aPseudoType).get(); - } - - return result; -} - -static PRBool -EnumPseudoElementRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData) -{ - PseudoElementRuleProcessorData* data = - static_cast(aData); - - aProcessor->RulesMatching(data); - return PR_TRUE; -} - already_AddRefed nsStyleSet::ResolvePseudoElementStyle(nsIContent* aParentContent, nsCSSPseudoElements::Type aType, @@ -889,7 +830,8 @@ nsStyleSet::ResolvePseudoElementStyle(nsIContent* aParentContent, PseudoElementRuleProcessorData data(presContext, aParentContent, &ruleWalker, aType); WalkRestrictionRule(aType, &ruleWalker); - FileRules(EnumPseudoElementRulesMatching, &data, aParentContent, &ruleWalker); + FileRules(EnumRulesMatching, &data, + aParentContent, &ruleWalker); return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(), nsCSSPseudoElements::GetPseudoAtom(aType), aType); @@ -918,7 +860,8 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent, WalkRestrictionRule(aType, &ruleWalker); // not the root if there was a restriction rule nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode(); - FileRules(EnumPseudoElementRulesMatching, &data, aParentContent, &ruleWalker); + FileRules(EnumRulesMatching, &data, + aParentContent, &ruleWalker); nsRuleNode *ruleNode = ruleWalker.GetCurrentNode(); if (ruleNode == adjustedRoot) { @@ -946,16 +889,6 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent, return result.forget(); } -static PRBool -EnumAnonBoxRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData) -{ - AnonBoxRuleProcessorData* data = - static_cast(aData); - - aProcessor->RulesMatching(data); - return PR_TRUE; -} - already_AddRefed nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext) @@ -974,12 +907,41 @@ nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsRuleWalker ruleWalker(mRuleTree); nsPresContext *presContext = PresContext(); AnonBoxRuleProcessorData data(presContext, aPseudoTag, &ruleWalker); - FileRules(EnumAnonBoxRulesMatching, &data, nsnull, &ruleWalker); + FileRules(EnumRulesMatching, &data, nsnull, + &ruleWalker); return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(), aPseudoTag, nsCSSPseudoElements::ePseudo_AnonBox); } +#ifdef MOZ_XUL +already_AddRefed +nsStyleSet::ResolveXULTreePseudoStyle(nsIContent* aParentContent, + nsIAtom* aPseudoTag, + nsStyleContext* aParentContext, + nsICSSPseudoComparator* aComparator) +{ + NS_ENSURE_FALSE(mInShutdown, nsnull); + + NS_ASSERTION(aPseudoTag, "must have pseudo tag"); + NS_ASSERTION(aParentContent->IsNodeOfType(nsINode::eELEMENT), + "content (if non-null) must be element"); + NS_ASSERTION(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag), + "Unexpected pseudo"); + + nsRuleWalker ruleWalker(mRuleTree); + nsPresContext *presContext = PresContext(); + + XULTreeRuleProcessorData data(presContext, aParentContent, &ruleWalker, + aPseudoTag, aComparator); + FileRules(EnumRulesMatching, &data, aParentContent, + &ruleWalker); + + return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(), + aPseudoTag, nsCSSPseudoElements::ePseudo_XULTree); +} +#endif + PRBool nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext, nsTArray& aArray) diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 671de095ebe..30d1d4c44bc 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -150,27 +150,9 @@ class nsStyleSet ResolveXULTreePseudoStyle(nsIContent* aParentContent, nsIAtom* aPseudoTag, nsStyleContext* aParentContext, - nsICSSPseudoComparator* aComparator) { - NS_PRECONDITION(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag), - "Unexpected pseudo"); - return ResolvePseudoStyleFor(aParentContent, aPseudoTag, - nsCSSPseudoElements::ePseudo_XULTree, - aParentContext, aComparator); - } + nsICSSPseudoComparator* aComparator); #endif -private: - // get a style context for a pseudo-element (i.e., - // |aPseudoTag == nsCOMPtr(do_GetAtom(":first-line"))|, in - // which case aParentContent must be non-null, or an anonymous box, in - // which case it may be null or non-null. - already_AddRefed - ResolvePseudoStyleFor(nsIContent* aParentContent, - nsIAtom* aPseudoTag, - nsCSSPseudoElements::Type aPseudoType, - nsStyleContext* aParentContext, - nsICSSPseudoComparator* aComparator = nsnull); -public: // Append all the currently-active font face rules to aArray. Return // true for success and false for failure. PRBool AppendFontFaceRules(nsPresContext* aPresContext, diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index ab65dff15ee..c041dc97432 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -767,11 +767,13 @@ nsTransitionManager::RulesMatching(AnonBoxRuleProcessorData* aData) return NS_OK; } +#ifdef MOZ_XUL NS_IMETHODIMP -nsTransitionManager::RulesMatching(PseudoRuleProcessorData* aData) +nsTransitionManager::RulesMatching(XULTreeRuleProcessorData* aData) { return NS_OK; } +#endif NS_IMETHODIMP nsTransitionManager::HasStateDependentStyle(StateRuleProcessorData* aData, diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index e62e3fe5000..53e919b3d84 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -88,7 +88,9 @@ public: NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData); NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData); NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData); - NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData); +#ifdef MOZ_XUL + NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData); +#endif NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData, nsReStyleHint* aResult); virtual nsReStyleHint