зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
43f303198b
Коммит
e6b913a5da
|
@ -365,14 +365,12 @@ public:
|
||||||
void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID,
|
void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID,
|
||||||
const nsAttrValue* aClassList,
|
const nsAttrValue* aClassList,
|
||||||
RuleEnumFunc aFunc, RuleProcessorData* aData);
|
RuleEnumFunc aFunc, RuleProcessorData* aData);
|
||||||
void EnumerateTagRules(nsIAtom* aTag,
|
|
||||||
RuleEnumFunc aFunc, void* aData);
|
|
||||||
PLArenaPool& Arena() { return mArena; }
|
PLArenaPool& Arena() { return mArena; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PrependRuleToTable(PLDHashTable* aTable, const void* aKey,
|
void PrependRuleToTable(PLDHashTable* aTable, const void* aKey,
|
||||||
RuleValue* aRuleInfo);
|
RuleValue* aRuleInfo);
|
||||||
void PrependRuleToTagTable(const void* aKey, RuleValue* aRuleInfo);
|
void PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo);
|
||||||
void PrependUniversalRule(RuleValue* aRuleInfo);
|
void PrependUniversalRule(RuleValue* aRuleInfo);
|
||||||
|
|
||||||
// All rule values in these hashtables are arena allocated
|
// All rule values in these hashtables are arena allocated
|
||||||
|
@ -396,15 +394,12 @@ protected:
|
||||||
PRUint32 mIdSelectors;
|
PRUint32 mIdSelectors;
|
||||||
|
|
||||||
PRUint32 mElementsMatched;
|
PRUint32 mElementsMatched;
|
||||||
PRUint32 mPseudosMatched;
|
|
||||||
|
|
||||||
PRUint32 mElementUniversalCalls;
|
PRUint32 mElementUniversalCalls;
|
||||||
PRUint32 mElementNameSpaceCalls;
|
PRUint32 mElementNameSpaceCalls;
|
||||||
PRUint32 mElementTagCalls;
|
PRUint32 mElementTagCalls;
|
||||||
PRUint32 mElementClassCalls;
|
PRUint32 mElementClassCalls;
|
||||||
PRUint32 mElementIdCalls;
|
PRUint32 mElementIdCalls;
|
||||||
|
|
||||||
PRUint32 mPseudoTagCalls;
|
|
||||||
#endif // RULE_HASH_STATS
|
#endif // RULE_HASH_STATS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -420,13 +415,11 @@ RuleHash::RuleHash(PRBool aQuirksMode)
|
||||||
mClassSelectors(0),
|
mClassSelectors(0),
|
||||||
mIdSelectors(0),
|
mIdSelectors(0),
|
||||||
mElementsMatched(0),
|
mElementsMatched(0),
|
||||||
mPseudosMatched(0),
|
|
||||||
mElementUniversalCalls(0),
|
mElementUniversalCalls(0),
|
||||||
mElementNameSpaceCalls(0),
|
mElementNameSpaceCalls(0),
|
||||||
mElementTagCalls(0),
|
mElementTagCalls(0),
|
||||||
mElementClassCalls(0),
|
mElementClassCalls(0),
|
||||||
mElementIdCalls(0),
|
mElementIdCalls(0)
|
||||||
mPseudoTagCalls(0)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(RuleHash);
|
MOZ_COUNT_CTOR(RuleHash);
|
||||||
|
@ -454,17 +447,14 @@ RuleHash::~RuleHash()
|
||||||
printf(
|
printf(
|
||||||
"RuleHash(%p):\n"
|
"RuleHash(%p):\n"
|
||||||
" Selectors: Universal (%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\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"
|
" Element Calls: Universal(%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\n"
|
||||||
" Pseudo-Element Calls: Tag(%u)\n",
|
|
||||||
static_cast<void*>(this),
|
static_cast<void*>(this),
|
||||||
mUniversalSelectors, mNameSpaceSelectors, mTagSelectors,
|
mUniversalSelectors, mNameSpaceSelectors, mTagSelectors,
|
||||||
mClassSelectors, mIdSelectors,
|
mClassSelectors, mIdSelectors,
|
||||||
mElementsMatched,
|
mElementsMatched,
|
||||||
mPseudosMatched,
|
|
||||||
mElementUniversalCalls, mElementNameSpaceCalls, mElementTagCalls,
|
mElementUniversalCalls, mElementNameSpaceCalls, mElementTagCalls,
|
||||||
mElementClassCalls, mElementIdCalls,
|
mElementClassCalls, mElementIdCalls);
|
||||||
mPseudoTagCalls);
|
|
||||||
#ifdef PRINT_UNIVERSAL_RULES
|
#ifdef PRINT_UNIVERSAL_RULES
|
||||||
{
|
{
|
||||||
RuleValue* value = mUniversalRules;
|
RuleValue* value = mUniversalRules;
|
||||||
|
@ -511,19 +501,26 @@ void RuleHash::PrependRuleToTable(PLDHashTable* aTable, const void* aKey,
|
||||||
entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules);
|
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
|
// Get a new or exisiting entry
|
||||||
RuleHashTagTableEntry *entry = static_cast<RuleHashTagTableEntry*>
|
RuleHashTagTableEntry *entry = static_cast<RuleHashTagTableEntry*>
|
||||||
(PL_DHashTableOperate(&mTagTable, aKey, PL_DHASH_ADD));
|
(PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD));
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return;
|
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
|
// 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.
|
// because we never combine two different entries in a tag table.
|
||||||
entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules);
|
entry->mRules = aRuleInfo->Add(aBackwardsIndex, entry->mRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuleHash::PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo)
|
||||||
|
{
|
||||||
|
DoPrependRuleToTagTable(&mTagTable, aKey, aRuleInfo, mRuleCount++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuleHash::PrependUniversalRule(RuleValue *aRuleInfo)
|
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.
|
// Attribute selectors hash table.
|
||||||
|
@ -730,12 +711,17 @@ struct RuleCascadeData {
|
||||||
PL_DHashTableInit(&mAnonBoxRules, &RuleHash_TagTable_Ops, nsnull,
|
PL_DHashTableInit(&mAnonBoxRules, &RuleHash_TagTable_Ops, nsnull,
|
||||||
sizeof(RuleHashTagTableEntry), 16);
|
sizeof(RuleHashTagTableEntry), 16);
|
||||||
memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes));
|
memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes));
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
PL_DHashTableInit(&mXULTreeRules, &RuleHash_TagTable_Ops, nsnull,
|
||||||
|
sizeof(RuleHashTagTableEntry), 16);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~RuleCascadeData()
|
~RuleCascadeData()
|
||||||
{
|
{
|
||||||
PL_DHashTableFinish(&mAttributeSelectors);
|
PL_DHashTableFinish(&mAttributeSelectors);
|
||||||
PL_DHashTableFinish(&mAnonBoxRules);
|
PL_DHashTableFinish(&mAnonBoxRules);
|
||||||
|
PL_DHashTableFinish(&mXULTreeRules);
|
||||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
|
||||||
delete mPseudoElementRuleHashes[i];
|
delete mPseudoElementRuleHashes[i];
|
||||||
}
|
}
|
||||||
|
@ -748,6 +734,9 @@ struct RuleCascadeData {
|
||||||
nsTArray<nsCSSSelector*> mIDSelectors;
|
nsTArray<nsCSSSelector*> mIDSelectors;
|
||||||
PLDHashTable mAttributeSelectors;
|
PLDHashTable mAttributeSelectors;
|
||||||
PLDHashTable mAnonBoxRules;
|
PLDHashTable mAnonBoxRules;
|
||||||
|
#ifdef MOZ_XUL
|
||||||
|
PLDHashTable mXULTreeRules;
|
||||||
|
#endif
|
||||||
|
|
||||||
nsTArray<nsFontFaceRuleContainer> mFontFaceRules;
|
nsTArray<nsFontFaceRuleContainer> mFontFaceRules;
|
||||||
|
|
||||||
|
@ -2090,68 +2079,34 @@ nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
|
#ifdef MOZ_XUL
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData)
|
nsCSSRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aData->mContent->IsNodeOfType(nsINode::eELEMENT),
|
NS_PRECONDITION(aData->mContent->IsNodeOfType(nsINode::eELEMENT),
|
||||||
"content must be element");
|
"content must be element");
|
||||||
|
|
||||||
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
|
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
|
||||||
|
|
||||||
if (cascade) {
|
if (cascade && cascade->mXULTreeRules.entryCount) {
|
||||||
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag,
|
RuleHashTagTableEntry* entry = static_cast<RuleHashTagTableEntry*>
|
||||||
PseudoEnumFunc, aData);
|
(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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline PRBool
|
inline PRBool
|
||||||
IsSiblingOperator(PRUnichar oper)
|
IsSiblingOperator(PRUnichar oper)
|
||||||
|
@ -2407,9 +2362,9 @@ PRBool IsStateSelector(nsCSSSelector& aSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRBool
|
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.
|
// Build the rule hash.
|
||||||
nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType();
|
nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType();
|
||||||
|
@ -2429,18 +2384,34 @@ AddRule(RuleValue* aRuleInfo, void* aCascade)
|
||||||
aRuleInfo->mSelector = aRuleInfo->mSelector->mNext;
|
aRuleInfo->mSelector = aRuleInfo->mSelector->mNext;
|
||||||
ruleHash->PrependRule(aRuleInfo);
|
ruleHash->PrependRule(aRuleInfo);
|
||||||
} else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
|
} else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) {
|
||||||
RuleHashTagTableEntry *entry = static_cast<RuleHashTagTableEntry*>
|
NS_ASSERTION(!aRuleInfo->mSelector->mCasedTag &&
|
||||||
(PL_DHashTableOperate(&cascade->mAnonBoxRules,
|
!aRuleInfo->mSelector->mIDList &&
|
||||||
aRuleInfo->mSelector->mLowercaseTag,
|
!aRuleInfo->mSelector->mClassList &&
|
||||||
PL_DHASH_ADD));
|
!aRuleInfo->mSelector->mPseudoClassList &&
|
||||||
if (!entry)
|
!aRuleInfo->mSelector->mAttrList &&
|
||||||
return PR_FALSE;
|
!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
|
// Index doesn't matter here, since we'll just be walking these
|
||||||
// rules in order; just pass 0.
|
// rules in order; just pass 0.
|
||||||
entry->mRules = aRuleInfo->Add(0, entry->mRules);
|
DoPrependRuleToTagTable(&cascade->mAnonBoxRules,
|
||||||
} else {
|
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);
|
cascade->mRuleHash.PrependRule(aRuleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,9 @@ public:
|
||||||
|
|
||||||
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* 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,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
|
|
|
@ -93,7 +93,9 @@ public:
|
||||||
|
|
||||||
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* 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,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
|
@ -170,11 +172,13 @@ HTMLCSSStyleSheetImpl::RulesMatching(AnonBoxRuleProcessorData* aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
|
HTMLCSSStyleSheetImpl::RulesMatching(XULTreeRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
|
HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
|
||||||
|
|
|
@ -581,12 +581,13 @@ nsHTMLStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
|
nsHTMLStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// nsIStyleSheet api
|
// nsIStyleSheet api
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -81,7 +81,9 @@ public:
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* 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,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
virtual nsReStyleHint
|
virtual nsReStyleHint
|
||||||
|
|
|
@ -53,15 +53,18 @@ struct RuleProcessorData;
|
||||||
struct ElementRuleProcessorData;
|
struct ElementRuleProcessorData;
|
||||||
struct PseudoElementRuleProcessorData;
|
struct PseudoElementRuleProcessorData;
|
||||||
struct AnonBoxRuleProcessorData;
|
struct AnonBoxRuleProcessorData;
|
||||||
struct PseudoRuleProcessorData;
|
#ifdef MOZ_XUL
|
||||||
|
struct XULTreeRuleProcessorData;
|
||||||
|
#endif
|
||||||
struct StateRuleProcessorData;
|
struct StateRuleProcessorData;
|
||||||
struct AttributeRuleProcessorData;
|
struct AttributeRuleProcessorData;
|
||||||
class nsPresContext;
|
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 \
|
#define NS_ISTYLE_RULE_PROCESSOR_IID \
|
||||||
{ 0xa4ec760e, 0x6bfb, 0x4b9f, \
|
{ 0xec92bc0c, 0x9518, 0x48ea, \
|
||||||
{ 0xbd, 0x08, 0x9d, 0x1c, 0x23, 0xb7, 0x00, 0xf6 } }
|
{ 0x92, 0x89, 0x74, 0xe6, 0x54, 0x65, 0x9b, 0xe9 } }
|
||||||
|
|
||||||
/* The style rule processor interface is a mechanism to separate the matching
|
/* The style rule processor interface is a mechanism to separate the matching
|
||||||
* of style rules from style sheet instances.
|
* of style rules from style sheet instances.
|
||||||
|
@ -98,11 +101,13 @@ public:
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData) = 0;
|
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* aData) = 0;
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
/**
|
/**
|
||||||
* Just like the previous |RulesMatching|, except for a given content
|
* 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
|
* Return how (as described by nsReStyleHint) style can depend on a
|
||||||
|
|
|
@ -211,24 +211,27 @@ struct AnonBoxRuleProcessorData {
|
||||||
nsRuleWalker* mRuleWalker;
|
nsRuleWalker* mRuleWalker;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PseudoRuleProcessorData : public RuleProcessorData {
|
#ifdef MOZ_XUL
|
||||||
PseudoRuleProcessorData(nsPresContext* aPresContext,
|
struct XULTreeRuleProcessorData : public RuleProcessorData {
|
||||||
nsIContent* aParentContent,
|
XULTreeRuleProcessorData(nsPresContext* aPresContext,
|
||||||
nsIAtom* aPseudoTag,
|
nsIContent* aParentContent,
|
||||||
nsICSSPseudoComparator* aComparator,
|
nsRuleWalker* aRuleWalker,
|
||||||
nsRuleWalker* aRuleWalker)
|
nsIAtom* aPseudoTag,
|
||||||
: RuleProcessorData(aPresContext, aParentContent, aRuleWalker)
|
nsICSSPseudoComparator* aComparator)
|
||||||
|
: RuleProcessorData(aPresContext, aParentContent, aRuleWalker),
|
||||||
|
mPseudoTag(aPseudoTag),
|
||||||
|
mComparator(aComparator)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aPresContext, "null pointer");
|
NS_PRECONDITION(aPresContext, "null pointer");
|
||||||
NS_PRECONDITION(aPseudoTag, "null pointer");
|
NS_PRECONDITION(aPseudoTag, "null pointer");
|
||||||
NS_PRECONDITION(aRuleWalker, "null pointer");
|
NS_PRECONDITION(aRuleWalker, "null pointer");
|
||||||
mPseudoTag = aPseudoTag;
|
NS_PRECONDITION(aComparator, "must have a comparator");
|
||||||
mComparator = aComparator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom* mPseudoTag;
|
nsIAtom* mPseudoTag;
|
||||||
nsICSSPseudoComparator* mComparator;
|
nsICSSPseudoComparator* mComparator;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct StateRuleProcessorData : public RuleProcessorData {
|
struct StateRuleProcessorData : public RuleProcessorData {
|
||||||
StateRuleProcessorData(nsPresContext* aPresContext,
|
StateRuleProcessorData(nsPresContext* aPresContext,
|
||||||
|
|
|
@ -411,12 +411,11 @@ nsStyleSet::EnableQuirkStyleSheet(PRBool aEnable)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
static PRBool
|
static PRBool
|
||||||
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
|
EnumRulesMatching(nsIStyleRuleProcessor* aProcessor, void* aData)
|
||||||
{
|
{
|
||||||
ElementRuleProcessorData* data =
|
T* data = static_cast<T*>(aData);
|
||||||
static_cast<ElementRuleProcessorData*>(aData);
|
|
||||||
|
|
||||||
aProcessor->RulesMatching(data);
|
aProcessor->RulesMatching(data);
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -748,7 +747,8 @@ nsStyleSet::ResolveStyleFor(nsIContent* aContent,
|
||||||
if (aContent && presContext) {
|
if (aContent && presContext) {
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
ElementRuleProcessorData data(presContext, aContent, &ruleWalker);
|
ElementRuleProcessorData data(presContext, aContent, &ruleWalker);
|
||||||
FileRules(EnumRulesMatching, &data, aContent, &ruleWalker);
|
FileRules(EnumRulesMatching<ElementRuleProcessorData>, &data, aContent,
|
||||||
|
&ruleWalker);
|
||||||
result = GetContext(presContext, aParentContext,
|
result = GetContext(presContext, aParentContext,
|
||||||
ruleWalker.GetCurrentNode(), nsnull,
|
ruleWalker.GetCurrentNode(), nsnull,
|
||||||
nsCSSPseudoElements::ePseudo_NotPseudoElement).get();
|
nsCSSPseudoElements::ePseudo_NotPseudoElement).get();
|
||||||
|
@ -812,65 +812,6 @@ nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType,
|
||||||
aRuleWalker->Forward(mFirstLineRule);
|
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>
|
already_AddRefed<nsStyleContext>
|
||||||
nsStyleSet::ResolvePseudoElementStyle(nsIContent* aParentContent,
|
nsStyleSet::ResolvePseudoElementStyle(nsIContent* aParentContent,
|
||||||
nsCSSPseudoElements::Type aType,
|
nsCSSPseudoElements::Type aType,
|
||||||
|
@ -889,7 +830,8 @@ nsStyleSet::ResolvePseudoElementStyle(nsIContent* aParentContent,
|
||||||
PseudoElementRuleProcessorData data(presContext, aParentContent, &ruleWalker,
|
PseudoElementRuleProcessorData data(presContext, aParentContent, &ruleWalker,
|
||||||
aType);
|
aType);
|
||||||
WalkRestrictionRule(aType, &ruleWalker);
|
WalkRestrictionRule(aType, &ruleWalker);
|
||||||
FileRules(EnumPseudoElementRulesMatching, &data, aParentContent, &ruleWalker);
|
FileRules(EnumRulesMatching<PseudoElementRuleProcessorData>, &data,
|
||||||
|
aParentContent, &ruleWalker);
|
||||||
|
|
||||||
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
|
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
|
||||||
nsCSSPseudoElements::GetPseudoAtom(aType), aType);
|
nsCSSPseudoElements::GetPseudoAtom(aType), aType);
|
||||||
|
@ -918,7 +860,8 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
||||||
WalkRestrictionRule(aType, &ruleWalker);
|
WalkRestrictionRule(aType, &ruleWalker);
|
||||||
// not the root if there was a restriction rule
|
// not the root if there was a restriction rule
|
||||||
nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode();
|
nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode();
|
||||||
FileRules(EnumPseudoElementRulesMatching, &data, aParentContent, &ruleWalker);
|
FileRules(EnumRulesMatching<PseudoElementRuleProcessorData>, &data,
|
||||||
|
aParentContent, &ruleWalker);
|
||||||
|
|
||||||
nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
|
nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
|
||||||
if (ruleNode == adjustedRoot) {
|
if (ruleNode == adjustedRoot) {
|
||||||
|
@ -946,16 +889,6 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
||||||
return result.forget();
|
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>
|
already_AddRefed<nsStyleContext>
|
||||||
nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
|
nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
|
||||||
nsStyleContext* aParentContext)
|
nsStyleContext* aParentContext)
|
||||||
|
@ -974,12 +907,41 @@ nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag,
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
nsPresContext *presContext = PresContext();
|
nsPresContext *presContext = PresContext();
|
||||||
AnonBoxRuleProcessorData data(presContext, aPseudoTag, &ruleWalker);
|
AnonBoxRuleProcessorData data(presContext, aPseudoTag, &ruleWalker);
|
||||||
FileRules(EnumAnonBoxRulesMatching, &data, nsnull, &ruleWalker);
|
FileRules(EnumRulesMatching<AnonBoxRuleProcessorData>, &data, nsnull,
|
||||||
|
&ruleWalker);
|
||||||
|
|
||||||
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
|
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
|
||||||
aPseudoTag, nsCSSPseudoElements::ePseudo_AnonBox);
|
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
|
PRBool
|
||||||
nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext,
|
nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext,
|
||||||
nsTArray<nsFontFaceRuleContainer>& aArray)
|
nsTArray<nsFontFaceRuleContainer>& aArray)
|
||||||
|
|
|
@ -150,27 +150,9 @@ class nsStyleSet
|
||||||
ResolveXULTreePseudoStyle(nsIContent* aParentContent,
|
ResolveXULTreePseudoStyle(nsIContent* aParentContent,
|
||||||
nsIAtom* aPseudoTag,
|
nsIAtom* aPseudoTag,
|
||||||
nsStyleContext* aParentContext,
|
nsStyleContext* aParentContext,
|
||||||
nsICSSPseudoComparator* aComparator) {
|
nsICSSPseudoComparator* aComparator);
|
||||||
NS_PRECONDITION(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag),
|
|
||||||
"Unexpected pseudo");
|
|
||||||
return ResolvePseudoStyleFor(aParentContent, aPseudoTag,
|
|
||||||
nsCSSPseudoElements::ePseudo_XULTree,
|
|
||||||
aParentContext, aComparator);
|
|
||||||
}
|
|
||||||
#endif
|
#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
|
// Append all the currently-active font face rules to aArray. Return
|
||||||
// true for success and false for failure.
|
// true for success and false for failure.
|
||||||
PRBool AppendFontFaceRules(nsPresContext* aPresContext,
|
PRBool AppendFontFaceRules(nsPresContext* aPresContext,
|
||||||
|
|
|
@ -767,11 +767,13 @@ nsTransitionManager::RulesMatching(AnonBoxRuleProcessorData* aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_XUL
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsTransitionManager::RulesMatching(PseudoRuleProcessorData* aData)
|
nsTransitionManager::RulesMatching(XULTreeRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsTransitionManager::HasStateDependentStyle(StateRuleProcessorData* aData,
|
nsTransitionManager::HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
|
|
|
@ -88,7 +88,9 @@ public:
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(AnonBoxRuleProcessorData* 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,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
virtual nsReStyleHint
|
virtual nsReStyleHint
|
||||||
|
|
Загрузка…
Ссылка в новой задаче