зеркало из https://github.com/mozilla/pjs.git
Bug 525608 part 4. Change pseudo-element probing and resolution to not use EnumerateTagRules. r=dbaron
This commit is contained in:
Родитель
db9b2aaefe
Коммит
cfac13a4b6
|
@ -69,6 +69,7 @@
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsRuleWalker.h"
|
#include "nsRuleWalker.h"
|
||||||
#include "nsCSSPseudoClasses.h"
|
#include "nsCSSPseudoClasses.h"
|
||||||
|
#include "nsCSSPseudoElements.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
|
@ -363,7 +364,7 @@ public:
|
||||||
void PrependRule(RuleValue *aRuleInfo);
|
void PrependRule(RuleValue *aRuleInfo);
|
||||||
void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID,
|
void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID,
|
||||||
const nsAttrValue* aClassList,
|
const nsAttrValue* aClassList,
|
||||||
RuleEnumFunc aFunc, void* aData);
|
RuleEnumFunc aFunc, RuleProcessorData* aData);
|
||||||
void EnumerateTagRules(nsIAtom* aTag,
|
void EnumerateTagRules(nsIAtom* aTag,
|
||||||
RuleEnumFunc aFunc, void* aData);
|
RuleEnumFunc aFunc, void* aData);
|
||||||
PLArenaPool& Arena() { return mArena; }
|
PLArenaPool& Arena() { return mArena; }
|
||||||
|
@ -428,6 +429,7 @@ RuleHash::RuleHash(PRBool aQuirksMode)
|
||||||
mPseudoTagCalls(0)
|
mPseudoTagCalls(0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
MOZ_COUNT_CTOR(RuleHash);
|
||||||
// Initialize our arena
|
// Initialize our arena
|
||||||
PL_INIT_ARENA_POOL(&mArena, "RuleHashArena", NS_RULEHASH_ARENA_BLOCK_SIZE);
|
PL_INIT_ARENA_POOL(&mArena, "RuleHashArena", NS_RULEHASH_ARENA_BLOCK_SIZE);
|
||||||
|
|
||||||
|
@ -447,6 +449,7 @@ RuleHash::RuleHash(PRBool aQuirksMode)
|
||||||
|
|
||||||
RuleHash::~RuleHash()
|
RuleHash::~RuleHash()
|
||||||
{
|
{
|
||||||
|
MOZ_COUNT_DTOR(RuleHash);
|
||||||
#ifdef RULE_HASH_STATS
|
#ifdef RULE_HASH_STATS
|
||||||
printf(
|
printf(
|
||||||
"RuleHash(%p):\n"
|
"RuleHash(%p):\n"
|
||||||
|
@ -574,7 +577,7 @@ void RuleHash::PrependRule(RuleValue *aRuleInfo)
|
||||||
|
|
||||||
void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
||||||
nsIAtom* aID, const nsAttrValue* aClassList,
|
nsIAtom* aID, const nsAttrValue* aClassList,
|
||||||
RuleEnumFunc aFunc, void* aData)
|
RuleEnumFunc aFunc, RuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
PRInt32 classCount = aClassList ? aClassList->GetAtomCount() : 0;
|
PRInt32 classCount = aClassList ? aClassList->GetAtomCount() : 0;
|
||||||
|
|
||||||
|
@ -599,7 +602,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// universal rules within the namespace
|
// universal rules within the namespace
|
||||||
if (kNameSpaceID_Unknown != aNameSpace) {
|
if (kNameSpaceID_Unknown != aNameSpace && mNameSpaceTable.entryCount) {
|
||||||
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
||||||
(PL_DHashTableOperate(&mNameSpaceTable, NS_INT32_TO_PTR(aNameSpace),
|
(PL_DHashTableOperate(&mNameSpaceTable, NS_INT32_TO_PTR(aNameSpace),
|
||||||
PL_DHASH_LOOKUP));
|
PL_DHASH_LOOKUP));
|
||||||
|
@ -609,7 +612,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
||||||
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementNameSpaceCalls);
|
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementNameSpaceCalls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsnull != aTag) {
|
if (aTag && mTagTable.entryCount) {
|
||||||
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
||||||
(PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP));
|
(PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP));
|
||||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||||
|
@ -618,7 +621,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
||||||
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementTagCalls);
|
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementTagCalls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsnull != aID) {
|
if (aID && mIdTable.entryCount) {
|
||||||
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
||||||
(PL_DHashTableOperate(&mIdTable, aID, PL_DHASH_LOOKUP));
|
(PL_DHashTableOperate(&mIdTable, aID, PL_DHASH_LOOKUP));
|
||||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||||
|
@ -627,7 +630,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
|
||||||
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementIdCalls);
|
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementIdCalls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // extra scope to work around compiler bugs with |for| scoping.
|
if (mClassTable.entryCount) {
|
||||||
for (PRInt32 index = 0; index < classCount; ++index) {
|
for (PRInt32 index = 0; index < classCount; ++index) {
|
||||||
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
|
||||||
(PL_DHashTableOperate(&mClassTable, aClassList->AtomAt(index),
|
(PL_DHashTableOperate(&mClassTable, aClassList->AtomAt(index),
|
||||||
|
@ -719,17 +722,24 @@ struct RuleCascadeData {
|
||||||
: mRuleHash(aQuirksMode),
|
: mRuleHash(aQuirksMode),
|
||||||
mStateSelectors(),
|
mStateSelectors(),
|
||||||
mCacheKey(aMedium),
|
mCacheKey(aMedium),
|
||||||
mNext(nsnull)
|
mNext(nsnull),
|
||||||
|
mQuirksMode(aQuirksMode)
|
||||||
{
|
{
|
||||||
PL_DHashTableInit(&mAttributeSelectors, &AttributeSelectorOps, nsnull,
|
PL_DHashTableInit(&mAttributeSelectors, &AttributeSelectorOps, nsnull,
|
||||||
sizeof(AttributeSelectorEntry), 16);
|
sizeof(AttributeSelectorEntry), 16);
|
||||||
|
memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes));
|
||||||
}
|
}
|
||||||
|
|
||||||
~RuleCascadeData()
|
~RuleCascadeData()
|
||||||
{
|
{
|
||||||
PL_DHashTableFinish(&mAttributeSelectors);
|
PL_DHashTableFinish(&mAttributeSelectors);
|
||||||
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
|
||||||
|
delete mPseudoElementRuleHashes[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RuleHash mRuleHash;
|
RuleHash mRuleHash;
|
||||||
|
RuleHash*
|
||||||
|
mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount];
|
||||||
nsTArray<nsCSSSelector*> mStateSelectors;
|
nsTArray<nsCSSSelector*> mStateSelectors;
|
||||||
nsTArray<nsCSSSelector*> mClassSelectors;
|
nsTArray<nsCSSSelector*> mClassSelectors;
|
||||||
nsTArray<nsCSSSelector*> mIDSelectors;
|
nsTArray<nsCSSSelector*> mIDSelectors;
|
||||||
|
@ -743,6 +753,8 @@ struct RuleCascadeData {
|
||||||
|
|
||||||
nsMediaQueryResultCacheKey mCacheKey;
|
nsMediaQueryResultCacheKey mCacheKey;
|
||||||
RuleCascadeData* mNext; // for a different medium
|
RuleCascadeData* mNext; // for a different medium
|
||||||
|
|
||||||
|
const PRBool mQuirksMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsTArray<nsCSSSelector*>*
|
nsTArray<nsCSSSelector*>*
|
||||||
|
@ -2007,7 +2019,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
|
||||||
static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
|
static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
|
||||||
void* aData)
|
void* aData)
|
||||||
{
|
{
|
||||||
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
|
RuleProcessorData* data = (RuleProcessorData*)aData;
|
||||||
|
|
||||||
if (SelectorMatches(*data, aSelector, 0, PR_TRUE)) {
|
if (SelectorMatches(*data, aSelector, 0, PR_TRUE)) {
|
||||||
nsCSSSelector *next = aSelector->mNext;
|
nsCSSSelector *next = aSelector->mNext;
|
||||||
|
@ -2045,6 +2057,28 @@ nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsCSSRuleProcessor::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aData->mContent->IsNodeOfType(nsINode::eELEMENT),
|
||||||
|
"content must be element");
|
||||||
|
|
||||||
|
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
|
||||||
|
|
||||||
|
if (cascade) {
|
||||||
|
RuleHash* ruleHash = cascade->mPseudoElementRuleHashes[aData->mPseudoType];
|
||||||
|
if (ruleHash) {
|
||||||
|
ruleHash->EnumerateAllRules(aData->mNameSpaceID,
|
||||||
|
aData->mContentTag,
|
||||||
|
aData->mContentID,
|
||||||
|
aData->mClasses,
|
||||||
|
ContentEnumFunc,
|
||||||
|
aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
|
static void PseudoEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
|
||||||
void* aData)
|
void* aData)
|
||||||
{
|
{
|
||||||
|
@ -2368,7 +2402,25 @@ AddRule(RuleValue* aRuleInfo, void* aCascade)
|
||||||
RuleCascadeData *cascade = static_cast<RuleCascadeData*>(aCascade);
|
RuleCascadeData *cascade = static_cast<RuleCascadeData*>(aCascade);
|
||||||
|
|
||||||
// Build the rule hash.
|
// Build the rule hash.
|
||||||
cascade->mRuleHash.PrependRule(aRuleInfo);
|
nsCSSPseudoElements::Type pseudoType = aRuleInfo->mSelector->PseudoType();
|
||||||
|
if (pseudoType < nsCSSPseudoElements::ePseudo_PseudoElementCount) {
|
||||||
|
RuleHash*& ruleHash = cascade->mPseudoElementRuleHashes[pseudoType];
|
||||||
|
if (!ruleHash) {
|
||||||
|
ruleHash = new RuleHash(cascade->mQuirksMode);
|
||||||
|
if (!ruleHash) {
|
||||||
|
// Out of memory; give up
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NS_ASSERTION(aRuleInfo->mSelector->mNext,
|
||||||
|
"Must have mNext; parser screwed up");
|
||||||
|
NS_ASSERTION(aRuleInfo->mSelector->mNext->mOperator == '>',
|
||||||
|
"Unexpected mNext combinator");
|
||||||
|
aRuleInfo->mSelector = aRuleInfo->mSelector->mNext;
|
||||||
|
ruleHash->PrependRule(aRuleInfo);
|
||||||
|
} else {
|
||||||
|
cascade->mRuleHash.PrependRule(aRuleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
nsTArray<nsCSSSelector*>* stateArray = &cascade->mStateSelectors;
|
nsTArray<nsCSSSelector*>* stateArray = &cascade->mStateSelectors;
|
||||||
nsTArray<nsCSSSelector*>* classArray = &cascade->mClassSelectors;
|
nsTArray<nsCSSSelector*>* classArray = &cascade->mClassSelectors;
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
// nsIStyleRuleProcessor
|
// nsIStyleRuleProcessor
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
|
|
||||||
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
|
|
||||||
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
||||||
|
|
||||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
|
|
|
@ -89,6 +89,8 @@ public:
|
||||||
// nsIStyleRuleProcessor api
|
// nsIStyleRuleProcessor api
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
|
|
||||||
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
|
|
||||||
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
||||||
|
|
||||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
|
@ -156,6 +158,12 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HTMLCSSStyleSheetImpl::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
|
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -562,6 +562,12 @@ nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
|
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
|
|
||||||
// nsIStyleRuleProcessor API
|
// nsIStyleRuleProcessor API
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
||||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
|
|
||||||
struct RuleProcessorData;
|
struct RuleProcessorData;
|
||||||
struct ElementRuleProcessorData;
|
struct ElementRuleProcessorData;
|
||||||
|
struct PseudoElementRuleProcessorData;
|
||||||
struct PseudoRuleProcessorData;
|
struct PseudoRuleProcessorData;
|
||||||
struct StateRuleProcessorData;
|
struct StateRuleProcessorData;
|
||||||
struct AttributeRuleProcessorData;
|
struct AttributeRuleProcessorData;
|
||||||
|
@ -89,6 +90,12 @@ public:
|
||||||
* Just like the previous |RulesMatching|, except for a given content
|
* Just like the previous |RulesMatching|, except for a given content
|
||||||
* node <em>and pseudo-element</em>.
|
* node <em>and pseudo-element</em>.
|
||||||
*/
|
*/
|
||||||
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just like the previous |RulesMatching|, except for a given content
|
||||||
|
* node <em>and pseudo</em>.
|
||||||
|
*/
|
||||||
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0;
|
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
#include "nsCSSPseudoElements.h"
|
||||||
|
|
||||||
class nsIStyleSheet;
|
class nsIStyleSheet;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
|
@ -174,6 +175,24 @@ struct ElementRuleProcessorData : public RuleProcessorData {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PseudoElementRuleProcessorData : public RuleProcessorData {
|
||||||
|
PseudoElementRuleProcessorData(nsPresContext* aPresContext,
|
||||||
|
nsIContent* aParentContent,
|
||||||
|
nsRuleWalker* aRuleWalker,
|
||||||
|
nsCSSPseudoElements::Type aPseudoType)
|
||||||
|
: RuleProcessorData(aPresContext, aParentContent, aRuleWalker),
|
||||||
|
mPseudoType(aPseudoType)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aPresContext, "null pointer");
|
||||||
|
NS_PRECONDITION(aPseudoType <
|
||||||
|
nsCSSPseudoElements::ePseudo_PseudoElementCount,
|
||||||
|
"null pointer");
|
||||||
|
NS_PRECONDITION(aRuleWalker, "null pointer");
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCSSPseudoElements::Type mPseudoType;
|
||||||
|
};
|
||||||
|
|
||||||
struct PseudoRuleProcessorData : public RuleProcessorData {
|
struct PseudoRuleProcessorData : public RuleProcessorData {
|
||||||
PseudoRuleProcessorData(nsPresContext* aPresContext,
|
PseudoRuleProcessorData(nsPresContext* aPresContext,
|
||||||
nsIContent* aParentContent,
|
nsIContent* aParentContent,
|
||||||
|
|
|
@ -799,17 +799,15 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsStyleSet::WalkRestrictionRule(nsIAtom* aPseudoType,
|
nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType,
|
||||||
nsRuleWalker* aRuleWalker)
|
nsRuleWalker* aRuleWalker)
|
||||||
{
|
{
|
||||||
// This needs to match GetPseudoRestriction in nsRuleNode.cpp.
|
// This needs to match GetPseudoRestriction in nsRuleNode.cpp.
|
||||||
if (aPseudoType) {
|
aRuleWalker->SetLevel(eAgentSheet, PR_FALSE, PR_FALSE);
|
||||||
aRuleWalker->SetLevel(eAgentSheet, PR_FALSE, PR_FALSE);
|
if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLetter)
|
||||||
if (aPseudoType == nsCSSPseudoElements::firstLetter)
|
aRuleWalker->Forward(mFirstLetterRule);
|
||||||
aRuleWalker->Forward(mFirstLetterRule);
|
else if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLine)
|
||||||
else if (aPseudoType == nsCSSPseudoElements::firstLine)
|
aRuleWalker->Forward(mFirstLineRule);
|
||||||
aRuleWalker->Forward(mFirstLineRule);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
|
@ -851,7 +849,6 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
|
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
|
||||||
aComparator, &ruleWalker);
|
aComparator, &ruleWalker);
|
||||||
WalkRestrictionRule(aPseudoTag, &ruleWalker);
|
|
||||||
FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
|
FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
|
||||||
|
|
||||||
result = GetContext(presContext, aParentContext,
|
result = GetContext(presContext, aParentContext,
|
||||||
|
@ -862,6 +859,40 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
|
||||||
return result;
|
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,
|
||||||
|
nsStyleContext* aParentContext)
|
||||||
|
{
|
||||||
|
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
||||||
|
|
||||||
|
NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount,
|
||||||
|
"must have pseudo element type");
|
||||||
|
NS_ASSERTION(aParentContent &&
|
||||||
|
aParentContent->IsNodeOfType(nsINode::eELEMENT),
|
||||||
|
"aParentContent must be element");
|
||||||
|
|
||||||
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
|
nsPresContext *presContext = PresContext();
|
||||||
|
PseudoElementRuleProcessorData data(presContext, aParentContent, &ruleWalker,
|
||||||
|
aType);
|
||||||
|
WalkRestrictionRule(aType, &ruleWalker);
|
||||||
|
FileRules(EnumPseudoElementRulesMatching, &data, &ruleWalker);
|
||||||
|
|
||||||
|
return GetContext(presContext, aParentContext, ruleWalker.GetCurrentNode(),
|
||||||
|
nsCSSPseudoElements::GetPseudoAtom(aType), aType);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
||||||
nsCSSPseudoElements::Type aType,
|
nsCSSPseudoElements::Type aType,
|
||||||
|
@ -869,31 +900,32 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
||||||
{
|
{
|
||||||
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
NS_ENSURE_FALSE(mInShutdown, nsnull);
|
||||||
|
|
||||||
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
|
NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount,
|
||||||
|
"must have pseudo element type");
|
||||||
nsStyleContext* result = nsnull;
|
|
||||||
nsPresContext *presContext = PresContext();
|
|
||||||
|
|
||||||
NS_ASSERTION(pseudoTag, "must have pseudo tag");
|
|
||||||
NS_ASSERTION(aParentContent &&
|
NS_ASSERTION(aParentContent &&
|
||||||
aParentContent->IsNodeOfType(nsINode::eELEMENT),
|
aParentContent->IsNodeOfType(nsINode::eELEMENT),
|
||||||
"aParentContent must be element");
|
"aParentContent must be element");
|
||||||
|
|
||||||
if (presContext) {
|
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
|
||||||
nsRuleWalker ruleWalker(mRuleTree);
|
|
||||||
PseudoRuleProcessorData data(presContext, aParentContent, pseudoTag,
|
|
||||||
nsnull, &ruleWalker);
|
|
||||||
WalkRestrictionRule(pseudoTag, &ruleWalker);
|
|
||||||
// not the root if there was a restriction rule
|
|
||||||
nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode();
|
|
||||||
FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
|
|
||||||
|
|
||||||
nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
|
nsPresContext *presContext = PresContext();
|
||||||
if (ruleNode != adjustedRoot)
|
|
||||||
result =
|
nsRuleWalker ruleWalker(mRuleTree);
|
||||||
GetContext(presContext, aParentContext, ruleNode, pseudoTag, aType).get();
|
PseudoElementRuleProcessorData data(presContext, aParentContent, &ruleWalker,
|
||||||
|
aType);
|
||||||
|
WalkRestrictionRule(aType, &ruleWalker);
|
||||||
|
// not the root if there was a restriction rule
|
||||||
|
nsRuleNode *adjustedRoot = ruleWalker.GetCurrentNode();
|
||||||
|
FileRules(EnumPseudoElementRulesMatching, &data, &ruleWalker);
|
||||||
|
|
||||||
|
nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
|
||||||
|
if (ruleNode == adjustedRoot) {
|
||||||
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRefPtr<nsStyleContext> result =
|
||||||
|
GetContext(presContext, aParentContext, ruleNode, pseudoTag, aType);
|
||||||
|
|
||||||
// For :before and :after pseudo-elements, having display: none or no
|
// For :before and :after pseudo-elements, having display: none or no
|
||||||
// 'content' property is equivalent to not having the pseudo-element
|
// 'content' property is equivalent to not having the pseudo-element
|
||||||
// at all.
|
// at all.
|
||||||
|
@ -905,12 +937,11 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
|
||||||
// XXXldb What is contentCount for |content: ""|?
|
// XXXldb What is contentCount for |content: ""|?
|
||||||
if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
|
if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
|
||||||
content->ContentCount() == 0) {
|
content->ContentCount() == 0) {
|
||||||
result->Release();
|
|
||||||
result = nsnull;
|
result = nsnull;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
|
|
@ -127,12 +127,7 @@ class nsStyleSet
|
||||||
already_AddRefed<nsStyleContext>
|
already_AddRefed<nsStyleContext>
|
||||||
ResolvePseudoElementStyle(nsIContent* aParentContent,
|
ResolvePseudoElementStyle(nsIContent* aParentContent,
|
||||||
nsCSSPseudoElements::Type aType,
|
nsCSSPseudoElements::Type aType,
|
||||||
nsStyleContext* aParentContext) {
|
nsStyleContext* aParentContext);
|
||||||
return ResolvePseudoStyleFor(aParentContent,
|
|
||||||
nsCSSPseudoElements::GetPseudoAtom(aType),
|
|
||||||
aType,
|
|
||||||
aParentContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This functions just like ResolvePseudoElementStyle except that it will
|
// This functions just like ResolvePseudoElementStyle except that it will
|
||||||
// return nsnull if there are no explicit style rules for that
|
// return nsnull if there are no explicit style rules for that
|
||||||
|
@ -334,7 +329,7 @@ public:
|
||||||
|
|
||||||
// Move aRuleWalker forward by the appropriate rule if we need to add
|
// Move aRuleWalker forward by the appropriate rule if we need to add
|
||||||
// a rule due to property restrictions on pseudo-elements.
|
// a rule due to property restrictions on pseudo-elements.
|
||||||
void WalkRestrictionRule(nsIAtom* aPseudoType,
|
void WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType,
|
||||||
nsRuleWalker* aRuleWalker);
|
nsRuleWalker* aRuleWalker);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
#include "nsRuleData.h"
|
#include "nsRuleData.h"
|
||||||
#include "nsSMILKeySpline.h"
|
#include "nsSMILKeySpline.h"
|
||||||
#include "gfxColor.h"
|
#include "gfxColor.h"
|
||||||
#include "nsCSSPseudoElements.h"
|
|
||||||
#include "nsCSSPropertySet.h"
|
#include "nsCSSPropertySet.h"
|
||||||
#include "nsStyleAnimation.h"
|
#include "nsStyleAnimation.h"
|
||||||
#include "nsCSSDataBlock.h"
|
#include "nsCSSDataBlock.h"
|
||||||
|
@ -373,9 +372,10 @@ nsTransitionManager::StyleContextChanged(nsIContent *aElement,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom *pseudo = aNewStyleContext->GetPseudo();
|
nsCSSPseudoElements::Type pseudoType = aNewStyleContext->GetPseudoType();
|
||||||
if (pseudo && (pseudo != nsCSSPseudoElements::before &&
|
if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement &&
|
||||||
pseudo != nsCSSPseudoElements::after)) {
|
pseudoType != nsCSSPseudoElements::ePseudo_before &&
|
||||||
|
pseudoType != nsCSSPseudoElements::ePseudo_after) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
if (aNewStyleContext->GetParent() &&
|
if (aNewStyleContext->GetParent() &&
|
||||||
|
@ -398,9 +398,7 @@ nsTransitionManager::StyleContextChanged(nsIContent *aElement,
|
||||||
// Check delay and duration first, since they default to zero, and
|
// Check delay and duration first, since they default to zero, and
|
||||||
// when they're both zero, we can ignore the transition.
|
// when they're both zero, we can ignore the transition.
|
||||||
if (t.GetDelay() != 0.0f || t.GetDuration() != 0.0f) {
|
if (t.GetDelay() != 0.0f || t.GetDuration() != 0.0f) {
|
||||||
et = GetElementTransitions(aElement,
|
et = GetElementTransitions(aElement, pseudoType, PR_FALSE);
|
||||||
aNewStyleContext->GetPseudo(),
|
|
||||||
PR_FALSE);
|
|
||||||
|
|
||||||
// We might have something to transition. See if any of the
|
// We might have something to transition. See if any of the
|
||||||
// properties in question changed and are animatable.
|
// properties in question changed and are animatable.
|
||||||
|
@ -614,7 +612,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||||
|
|
||||||
if (!aElementTransitions) {
|
if (!aElementTransitions) {
|
||||||
aElementTransitions =
|
aElementTransitions =
|
||||||
GetElementTransitions(aElement, aNewStyleContext->GetPseudo(),
|
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
|
||||||
PR_TRUE);
|
PR_TRUE);
|
||||||
if (!aElementTransitions) {
|
if (!aElementTransitions) {
|
||||||
NS_WARNING("allocating ElementTransitions failed");
|
NS_WARNING("allocating ElementTransitions failed");
|
||||||
|
@ -648,16 +646,17 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||||
|
|
||||||
ElementTransitions*
|
ElementTransitions*
|
||||||
nsTransitionManager::GetElementTransitions(nsIContent *aElement,
|
nsTransitionManager::GetElementTransitions(nsIContent *aElement,
|
||||||
nsIAtom *aPseudo,
|
nsCSSPseudoElements::Type aPseudoType,
|
||||||
PRBool aCreateIfNeeded)
|
PRBool aCreateIfNeeded)
|
||||||
{
|
{
|
||||||
nsIAtom *propName;
|
nsIAtom *propName;
|
||||||
if (aPseudo == nsCSSPseudoElements::before) {
|
if (aPseudoType == nsCSSPseudoElements::ePseudo_before) {
|
||||||
propName = nsGkAtoms::transitionsOfBeforeProperty;
|
propName = nsGkAtoms::transitionsOfBeforeProperty;
|
||||||
} else if (aPseudo == nsCSSPseudoElements::after) {
|
} else if (aPseudoType == nsCSSPseudoElements::ePseudo_after) {
|
||||||
propName = nsGkAtoms::transitionsOfAfterProperty;
|
propName = nsGkAtoms::transitionsOfAfterProperty;
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(!aPseudo || !aCreateIfNeeded,
|
NS_ASSERTION(aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement ||
|
||||||
|
!aCreateIfNeeded,
|
||||||
"should never try to create transitions for pseudo "
|
"should never try to create transitions for pseudo "
|
||||||
"other than :before or :after");
|
"other than :before or :after");
|
||||||
propName = nsGkAtoms::transitionsProperty;
|
propName = nsGkAtoms::transitionsProperty;
|
||||||
|
@ -711,7 +710,7 @@ NS_IMPL_QUERY_INTERFACE1(nsTransitionManager, nsIStyleRuleProcessor)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsTransitionManager::WalkTransitionRule(RuleProcessorData* aData,
|
nsTransitionManager::WalkTransitionRule(RuleProcessorData* aData,
|
||||||
nsIAtom *aPseudo)
|
nsCSSPseudoElements::Type aPseudoType)
|
||||||
{
|
{
|
||||||
if (!aData->mPresContext->IsProcessingAnimationStyleChange()) {
|
if (!aData->mPresContext->IsProcessingAnimationStyleChange()) {
|
||||||
// If we're processing a normal style change rather than one from
|
// If we're processing a normal style change rather than one from
|
||||||
|
@ -726,7 +725,7 @@ nsTransitionManager::WalkTransitionRule(RuleProcessorData* aData,
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementTransitions *et =
|
ElementTransitions *et =
|
||||||
GetElementTransitions(aData->mContent, aPseudo, PR_FALSE);
|
GetElementTransitions(aData->mContent, aPseudoType, PR_FALSE);
|
||||||
if (!et) {
|
if (!et) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -746,18 +745,26 @@ nsTransitionManager::RulesMatching(ElementRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
|
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
|
||||||
"pres context mismatch");
|
"pres context mismatch");
|
||||||
return WalkTransitionRule(aData, nsnull);
|
return WalkTransitionRule(aData,
|
||||||
|
nsCSSPseudoElements::ePseudo_NotPseudoElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTransitionManager::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
|
||||||
|
"pres context mismatch");
|
||||||
|
|
||||||
|
// Note: If we're the only thing keeping a pseudo-element frame alive
|
||||||
|
// (per ProbePseudoStyleContext), we still want to keep it alive, so
|
||||||
|
// this is ok.
|
||||||
|
return WalkTransitionRule(aData, aData->mPseudoType);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsTransitionManager::RulesMatching(PseudoRuleProcessorData* aData)
|
nsTransitionManager::RulesMatching(PseudoRuleProcessorData* aData)
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
|
return NS_OK;
|
||||||
"pres context mismatch");
|
|
||||||
// Note: If we're the only thing keeping a pseudo-element frame alive
|
|
||||||
// (per ProbePseudoStyleContext), we still want to keep it alive, so
|
|
||||||
// this is ok.
|
|
||||||
return WalkTransitionRule(aData, aData->mPseudoTag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "nsCSSProperty.h"
|
#include "nsCSSProperty.h"
|
||||||
#include "nsIStyleRuleProcessor.h"
|
#include "nsIStyleRuleProcessor.h"
|
||||||
#include "nsRefreshDriver.h"
|
#include "nsRefreshDriver.h"
|
||||||
|
#include "nsCSSPseudoElements.h"
|
||||||
|
|
||||||
class nsStyleContext;
|
class nsStyleContext;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
|
@ -85,6 +86,7 @@ public:
|
||||||
|
|
||||||
// nsIStyleRuleProcessor
|
// nsIStyleRuleProcessor
|
||||||
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
|
||||||
|
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
|
||||||
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
|
||||||
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
|
||||||
nsReStyleHint* aResult);
|
nsReStyleHint* aResult);
|
||||||
|
@ -108,11 +110,12 @@ private:
|
||||||
PRBool *aStartedAny,
|
PRBool *aStartedAny,
|
||||||
nsCSSPropertySet *aWhichStarted);
|
nsCSSPropertySet *aWhichStarted);
|
||||||
ElementTransitions* GetElementTransitions(nsIContent *aElement,
|
ElementTransitions* GetElementTransitions(nsIContent *aElement,
|
||||||
nsIAtom *aPseudo,
|
nsCSSPseudoElements::Type aPseudoType,
|
||||||
PRBool aCreateIfNeeded);
|
PRBool aCreateIfNeeded);
|
||||||
void AddElementTransitions(ElementTransitions* aElementTransitions);
|
void AddElementTransitions(ElementTransitions* aElementTransitions);
|
||||||
void TransitionsRemoved();
|
void TransitionsRemoved();
|
||||||
nsresult WalkTransitionRule(RuleProcessorData* aData, nsIAtom *aPseudo);
|
nsresult WalkTransitionRule(RuleProcessorData* aData,
|
||||||
|
nsCSSPseudoElements::Type aPseudoType);
|
||||||
|
|
||||||
PRCList mElementTransitions;
|
PRCList mElementTransitions;
|
||||||
nsPresContext *mPresContext;
|
nsPresContext *mPresContext;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче