Bug 525608 part 4. Change pseudo-element probing and resolution to not use EnumerateTagRules. r=dbaron

This commit is contained in:
Boris Zbarsky 2009-12-10 14:36:06 -08:00
parent 6eb3c28de7
commit fbb842ae93
11 changed files with 199 additions and 68 deletions

View File

@ -69,6 +69,7 @@
#include "nsDOMError.h"
#include "nsRuleWalker.h"
#include "nsCSSPseudoClasses.h"
#include "nsCSSPseudoElements.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
#include "nsHashKeys.h"
@ -363,7 +364,7 @@ public:
void PrependRule(RuleValue *aRuleInfo);
void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID,
const nsAttrValue* aClassList,
RuleEnumFunc aFunc, void* aData);
RuleEnumFunc aFunc, RuleProcessorData* aData);
void EnumerateTagRules(nsIAtom* aTag,
RuleEnumFunc aFunc, void* aData);
PLArenaPool& Arena() { return mArena; }
@ -428,6 +429,7 @@ RuleHash::RuleHash(PRBool aQuirksMode)
mPseudoTagCalls(0)
#endif
{
MOZ_COUNT_CTOR(RuleHash);
// Initialize our arena
PL_INIT_ARENA_POOL(&mArena, "RuleHashArena", NS_RULEHASH_ARENA_BLOCK_SIZE);
@ -447,6 +449,7 @@ RuleHash::RuleHash(PRBool aQuirksMode)
RuleHash::~RuleHash()
{
MOZ_COUNT_DTOR(RuleHash);
#ifdef RULE_HASH_STATS
printf(
"RuleHash(%p):\n"
@ -574,7 +577,7 @@ void RuleHash::PrependRule(RuleValue *aRuleInfo)
void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
nsIAtom* aID, const nsAttrValue* aClassList,
RuleEnumFunc aFunc, void* aData)
RuleEnumFunc aFunc, RuleProcessorData* aData)
{
PRInt32 classCount = aClassList ? aClassList->GetAtomCount() : 0;
@ -599,7 +602,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
}
}
// universal rules within the namespace
if (kNameSpaceID_Unknown != aNameSpace) {
if (kNameSpaceID_Unknown != aNameSpace && mNameSpaceTable.entryCount) {
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
(PL_DHashTableOperate(&mNameSpaceTable, NS_INT32_TO_PTR(aNameSpace),
PL_DHASH_LOOKUP));
@ -609,7 +612,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag,
RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementNameSpaceCalls);
}
}
if (nsnull != aTag) {
if (aTag && mTagTable.entryCount) {
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
(PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP));
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);
}
}
if (nsnull != aID) {
if (aID && mIdTable.entryCount) {
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
(PL_DHashTableOperate(&mIdTable, aID, PL_DHASH_LOOKUP));
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);
}
}
{ // extra scope to work around compiler bugs with |for| scoping.
if (mClassTable.entryCount) {
for (PRInt32 index = 0; index < classCount; ++index) {
RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*>
(PL_DHashTableOperate(&mClassTable, aClassList->AtomAt(index),
@ -719,17 +722,24 @@ struct RuleCascadeData {
: mRuleHash(aQuirksMode),
mStateSelectors(),
mCacheKey(aMedium),
mNext(nsnull)
mNext(nsnull),
mQuirksMode(aQuirksMode)
{
PL_DHashTableInit(&mAttributeSelectors, &AttributeSelectorOps, nsnull,
sizeof(AttributeSelectorEntry), 16);
memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes));
}
~RuleCascadeData()
{
PL_DHashTableFinish(&mAttributeSelectors);
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
delete mPseudoElementRuleHashes[i];
}
}
RuleHash mRuleHash;
RuleHash*
mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount];
nsTArray<nsCSSSelector*> mStateSelectors;
nsTArray<nsCSSSelector*> mClassSelectors;
nsTArray<nsCSSSelector*> mIDSelectors;
@ -743,6 +753,8 @@ struct RuleCascadeData {
nsMediaQueryResultCacheKey mCacheKey;
RuleCascadeData* mNext; // for a different medium
const PRBool mQuirksMode;
};
nsTArray<nsCSSSelector*>*
@ -2007,7 +2019,7 @@ static PRBool SelectorMatchesTree(RuleProcessorData& aPrevData,
static void ContentEnumFunc(nsICSSStyleRule* aRule, nsCSSSelector* aSelector,
void* aData)
{
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
RuleProcessorData* data = (RuleProcessorData*)aData;
if (SelectorMatches(*data, aSelector, 0, PR_TRUE)) {
nsCSSSelector *next = aSelector->mNext;
@ -2045,6 +2057,28 @@ nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
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,
void* aData)
{
@ -2368,7 +2402,25 @@ AddRule(RuleValue* aRuleInfo, void* aCascade)
RuleCascadeData *cascade = static_cast<RuleCascadeData*>(aCascade);
// 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*>* classArray = &cascade->mClassSelectors;

View File

@ -91,6 +91,8 @@ public:
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,

View File

@ -89,6 +89,8 @@ public:
// nsIStyleRuleProcessor api
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
@ -156,6 +158,12 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData)
return NS_OK;
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(PseudoElementRuleProcessorData* aData)
{
return NS_OK;
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData)
{

View File

@ -562,6 +562,12 @@ nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext,
}
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
{
return NS_OK;
}
NS_IMETHODIMP
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
{

View File

@ -79,6 +79,7 @@ public:
// nsIStyleRuleProcessor API
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsReStyleHint* aResult);

View File

@ -51,6 +51,7 @@
struct RuleProcessorData;
struct ElementRuleProcessorData;
struct PseudoElementRuleProcessorData;
struct PseudoRuleProcessorData;
struct StateRuleProcessorData;
struct AttributeRuleProcessorData;
@ -89,6 +90,12 @@ public:
* Just like the previous |RulesMatching|, except for a given content
* 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;
/**

View File

@ -48,6 +48,7 @@
#include "nsString.h"
#include "nsChangeHint.h"
#include "nsIContent.h"
#include "nsCSSPseudoElements.h"
class nsIStyleSheet;
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 {
PseudoRuleProcessorData(nsPresContext* aPresContext,
nsIContent* aParentContent,

View File

@ -799,17 +799,15 @@ nsStyleSet::ResolveStyleForNonElement(nsStyleContext* aParentContext)
}
void
nsStyleSet::WalkRestrictionRule(nsIAtom* aPseudoType,
nsStyleSet::WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker)
{
// This needs to match GetPseudoRestriction in nsRuleNode.cpp.
if (aPseudoType) {
aRuleWalker->SetLevel(eAgentSheet, PR_FALSE, PR_FALSE);
if (aPseudoType == nsCSSPseudoElements::firstLetter)
aRuleWalker->Forward(mFirstLetterRule);
else if (aPseudoType == nsCSSPseudoElements::firstLine)
aRuleWalker->Forward(mFirstLineRule);
}
aRuleWalker->SetLevel(eAgentSheet, PR_FALSE, PR_FALSE);
if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLetter)
aRuleWalker->Forward(mFirstLetterRule);
else if (aPseudoType == nsCSSPseudoElements::ePseudo_firstLine)
aRuleWalker->Forward(mFirstLineRule);
}
static PRBool
@ -851,7 +849,6 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
nsRuleWalker ruleWalker(mRuleTree);
PseudoRuleProcessorData data(presContext, aParentContent, aPseudoTag,
aComparator, &ruleWalker);
WalkRestrictionRule(aPseudoTag, &ruleWalker);
FileRules(EnumPseudoRulesMatching, &data, &ruleWalker);
result = GetContext(presContext, aParentContext,
@ -862,6 +859,40 @@ nsStyleSet::ResolvePseudoStyleFor(nsIContent* aParentContent,
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>
nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
nsCSSPseudoElements::Type aType,
@ -869,31 +900,32 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
{
NS_ENSURE_FALSE(mInShutdown, nsnull);
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
nsStyleContext* result = nsnull;
nsPresContext *presContext = PresContext();
NS_ASSERTION(pseudoTag, "must have pseudo tag");
NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount,
"must have pseudo element type");
NS_ASSERTION(aParentContent &&
aParentContent->IsNodeOfType(nsINode::eELEMENT),
"aParentContent must be element");
if (presContext) {
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);
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
nsRuleNode *ruleNode = ruleWalker.GetCurrentNode();
if (ruleNode != adjustedRoot)
result =
GetContext(presContext, aParentContext, ruleNode, pseudoTag, aType).get();
nsPresContext *presContext = PresContext();
nsRuleWalker ruleWalker(mRuleTree);
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
// 'content' property is equivalent to not having the pseudo-element
// at all.
@ -905,12 +937,11 @@ nsStyleSet::ProbePseudoElementStyle(nsIContent* aParentContent,
// XXXldb What is contentCount for |content: ""|?
if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
content->ContentCount() == 0) {
result->Release();
result = nsnull;
}
}
return result;
return result.forget();
}
PRBool

View File

@ -127,12 +127,7 @@ class nsStyleSet
already_AddRefed<nsStyleContext>
ResolvePseudoElementStyle(nsIContent* aParentContent,
nsCSSPseudoElements::Type aType,
nsStyleContext* aParentContext) {
return ResolvePseudoStyleFor(aParentContent,
nsCSSPseudoElements::GetPseudoAtom(aType),
aType,
aParentContext);
}
nsStyleContext* aParentContext);
// This functions just like ResolvePseudoElementStyle except that it will
// 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
// a rule due to property restrictions on pseudo-elements.
void WalkRestrictionRule(nsIAtom* aPseudoType,
void WalkRestrictionRule(nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker);
#ifdef DEBUG

View File

@ -49,7 +49,6 @@
#include "nsRuleData.h"
#include "nsSMILKeySpline.h"
#include "gfxColor.h"
#include "nsCSSPseudoElements.h"
#include "nsCSSPropertySet.h"
#include "nsStyleAnimation.h"
#include "nsCSSDataBlock.h"
@ -373,9 +372,10 @@ nsTransitionManager::StyleContextChanged(nsIContent *aElement,
return nsnull;
}
nsIAtom *pseudo = aNewStyleContext->GetPseudo();
if (pseudo && (pseudo != nsCSSPseudoElements::before &&
pseudo != nsCSSPseudoElements::after)) {
nsCSSPseudoElements::Type pseudoType = aNewStyleContext->GetPseudoType();
if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement &&
pseudoType != nsCSSPseudoElements::ePseudo_before &&
pseudoType != nsCSSPseudoElements::ePseudo_after) {
return nsnull;
}
if (aNewStyleContext->GetParent() &&
@ -398,9 +398,7 @@ nsTransitionManager::StyleContextChanged(nsIContent *aElement,
// Check delay and duration first, since they default to zero, and
// when they're both zero, we can ignore the transition.
if (t.GetDelay() != 0.0f || t.GetDuration() != 0.0f) {
et = GetElementTransitions(aElement,
aNewStyleContext->GetPseudo(),
PR_FALSE);
et = GetElementTransitions(aElement, pseudoType, PR_FALSE);
// We might have something to transition. See if any of the
// properties in question changed and are animatable.
@ -614,7 +612,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
if (!aElementTransitions) {
aElementTransitions =
GetElementTransitions(aElement, aNewStyleContext->GetPseudo(),
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
PR_TRUE);
if (!aElementTransitions) {
NS_WARNING("allocating ElementTransitions failed");
@ -648,16 +646,17 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
ElementTransitions*
nsTransitionManager::GetElementTransitions(nsIContent *aElement,
nsIAtom *aPseudo,
nsCSSPseudoElements::Type aPseudoType,
PRBool aCreateIfNeeded)
{
nsIAtom *propName;
if (aPseudo == nsCSSPseudoElements::before) {
if (aPseudoType == nsCSSPseudoElements::ePseudo_before) {
propName = nsGkAtoms::transitionsOfBeforeProperty;
} else if (aPseudo == nsCSSPseudoElements::after) {
} else if (aPseudoType == nsCSSPseudoElements::ePseudo_after) {
propName = nsGkAtoms::transitionsOfAfterProperty;
} else {
NS_ASSERTION(!aPseudo || !aCreateIfNeeded,
NS_ASSERTION(aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement ||
!aCreateIfNeeded,
"should never try to create transitions for pseudo "
"other than :before or :after");
propName = nsGkAtoms::transitionsProperty;
@ -711,7 +710,7 @@ NS_IMPL_QUERY_INTERFACE1(nsTransitionManager, nsIStyleRuleProcessor)
nsresult
nsTransitionManager::WalkTransitionRule(RuleProcessorData* aData,
nsIAtom *aPseudo)
nsCSSPseudoElements::Type aPseudoType)
{
if (!aData->mPresContext->IsProcessingAnimationStyleChange()) {
// If we're processing a normal style change rather than one from
@ -726,7 +725,7 @@ nsTransitionManager::WalkTransitionRule(RuleProcessorData* aData,
}
ElementTransitions *et =
GetElementTransitions(aData->mContent, aPseudo, PR_FALSE);
GetElementTransitions(aData->mContent, aPseudoType, PR_FALSE);
if (!et) {
return NS_OK;
}
@ -746,18 +745,26 @@ nsTransitionManager::RulesMatching(ElementRuleProcessorData* aData)
{
NS_ABORT_IF_FALSE(aData->mPresContext == mPresContext,
"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
nsTransitionManager::RulesMatching(PseudoRuleProcessorData* 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->mPseudoTag);
return NS_OK;
}
NS_IMETHODIMP

View File

@ -44,6 +44,7 @@
#include "nsCSSProperty.h"
#include "nsIStyleRuleProcessor.h"
#include "nsRefreshDriver.h"
#include "nsCSSPseudoElements.h"
class nsStyleContext;
class nsPresContext;
@ -85,6 +86,7 @@ public:
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoElementRuleProcessorData* aData);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsReStyleHint* aResult);
@ -108,11 +110,12 @@ private:
PRBool *aStartedAny,
nsCSSPropertySet *aWhichStarted);
ElementTransitions* GetElementTransitions(nsIContent *aElement,
nsIAtom *aPseudo,
nsCSSPseudoElements::Type aPseudoType,
PRBool aCreateIfNeeded);
void AddElementTransitions(ElementTransitions* aElementTransitions);
void TransitionsRemoved();
nsresult WalkTransitionRule(RuleProcessorData* aData, nsIAtom *aPseudo);
nsresult WalkTransitionRule(RuleProcessorData* aData,
nsCSSPseudoElements::Type aPseudoType);
PRCList mElementTransitions;
nsPresContext *mPresContext;