Bug 525608 part 7. Make tree pseudos use a separate hashtable instead of riding along on the rulehash. r=dbaron

This commit is contained in:
Boris Zbarsky 2009-12-11 02:37:40 -05:00
Родитель 43f303198b
Коммит e6b913a5da
11 изменённых файлов: 156 добавлений и 220 удалений

Просмотреть файл

@ -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<void*>(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<RuleHashTagTableEntry*>
(PL_DHashTableOperate(&mTagTable, aKey, PL_DHASH_ADD));
if (!entry)
return;
RuleHashTagTableEntry *entry = static_cast<RuleHashTagTableEntry*>
(PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD));
if (!entry)
return;
entry->mTag = const_cast<nsIAtom*>(static_cast<const nsIAtom*>(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<RuleHashTableEntry*>
(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<nsCSSSelector*> mIDSelectors;
PLDHashTable mAttributeSelectors;
PLDHashTable mAnonBoxRules;
#ifdef MOZ_XUL
PLDHashTable mXULTreeRules;
#endif
nsTArray<nsFontFaceRuleContainer> 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<nsIStyleRule> iRule = do_QueryInterface(aRule);
NS_ASSERTION(static_cast<nsIStyleRule*>(aRule) == iRule.get(),
"Please fix QI so this performance optimization is valid");
#endif
data->mRuleWalker->Forward(static_cast<nsIStyleRule*>(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<RuleHashTagTableEntry*>
(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<RuleProcessorData*>(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<RuleCascadeData*>(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<RuleHashTagTableEntry*>
(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);
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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)

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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 <em>and pseudo</em>.
* node <em>and tree pseudo</em>.
*/
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0;
NS_IMETHOD RulesMatching(XULTreeRuleProcessorData* aData) = 0;
#endif
/**
* Return how (as described by nsReStyleHint) style can depend on a

Просмотреть файл

@ -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,

Просмотреть файл

@ -411,12 +411,11 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable)
#endif
}
template<class T>
static PRBool
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
{
ElementRuleProcessorData* data =
static_cast<ElementRuleProcessorData*>(aData);
T* data = static_cast<T*>(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<ElementRuleProcessorData>, &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<PseudoRuleProcessorData*>(aData);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
already_AddRefed<nsStyleContext>
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<PseudoElementRuleProcessorData*>(aData);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
already_AddRefed<nsStyleContext>
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<PseudoElementRuleProcessorData>, &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<PseudoElementRuleProcessorData>, &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<AnonBoxRuleProcessorData*>(aData);
aProcessor->RulesMatching(data);
return PR_TRUE;
}
already_AddRefed<nsStyleContext>
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<AnonBoxRuleProcessorData>, &data, nsnull,
&ruleWalker);
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
aPseudoTag, nsCSSPseudoElements::ePseudo_AnonBox);
}
#ifdef MOZ_XUL
already_AddRefed<nsStyleContext>
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<XULTreeRuleProcessorData>, &data, aParentContent,
&ruleWalker);
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
aPseudoTag, nsCSSPseudoElements::ePseudo_XULTree);
}
#endif
PRBool
nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext,
nsTArray<nsFontFaceRuleContainer>& aArray)

Просмотреть файл

@ -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<nsIAtom>(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<nsStyleContext>
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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -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