mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 525608 part 4. Change pseudo-element probing and resolution to not use EnumerateTagRules. r=dbaron
This commit is contained in:
parent
6eb3c28de7
commit
fbb842ae93
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -562,6 +562,12 @@ nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLStyleSheet::RulesMatching(PseudoRuleProcessorData* aData)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user