Pull computation of loop invariants for rule matching out of outer loop (over rule processors) as well, from SelectorMatchesData in nsCSSStyleSheet to RuleProcessorData in nsStyleSet. Use the RuleProcessorData structure in nsHTMLStyleSheet as well. Simplify matching of :-moz-bound-element pseudo-class. b=83836 r=waterson, pierre sr=hyatt

This commit is contained in:
dbaron%fas.harvard.edu 2001-11-10 23:51:45 +00:00
Родитель 5556328edb
Коммит ee1bd92fab
13 изменённых файлов: 663 добавлений и 962 удалений

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

@ -41,6 +41,8 @@
#include <stdio.h>
#include "nsISupports.h"
#include "nsIPresContext.h" // for nsCompatability
#include "nsILinkHandler.h"
class nsISizeOfHandler;
@ -48,11 +50,93 @@ class nsIStyleSheet;
class nsIStyleContext;
class nsIPresContext;
class nsIContent;
class nsIStyledContent;
class nsISupportsArray;
class nsIAtom;
class nsICSSPseudoComparator;
class nsRuleWalker;
// The implementation of the constructor and destructor are currently in
// nsCSSStyleSheet.cpp.
struct RuleProcessorData {
RuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat = nsnull);
virtual ~RuleProcessorData();
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
}
void Destroy(nsIPresContext* aContext) {
this->~RuleProcessorData();
aContext->FreeToShell(sizeof(RuleProcessorData), this);
};
nsIPresContext* mPresContext;
nsIContent* mContent;
nsIContent* mParentContent; // if content, content->GetParent()
nsRuleWalker* mRuleWalker; // Used to add rules to our results.
nsIContent* mScopedRoot; // Root of scoped stylesheet (set and unset by the supplier of the scoped stylesheet
nsIAtom* mContentTag; // if content, then content->GetTag()
nsIAtom* mContentID; // if styled content, then styledcontent->GetID()
nsIStyledContent* mStyledContent; // if content, content->QI(nsIStyledContent)
PRBool mIsHTMLContent; // if content, then does QI on HTMLContent, true or false
PRBool mIsHTMLLink; // if content, calls nsStyleUtil::IsHTMLLink
PRBool mIsSimpleXLink; // if content, calls nsStyleUtil::IsSimpleXLink
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
PRBool mIsQuirkMode; // Possibly remove use of this in SelectorMatches?
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
PRBool mHasAttributes; // if content, content->GetAttrCount() > 0
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
RuleProcessorData* mPreviousSiblingData;
RuleProcessorData* mParentData;
};
struct ElementRuleProcessorData : public RuleProcessorData {
ElementRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: RuleProcessorData(aPresContext,aContent,aRuleWalker)
{
NS_PRECONDITION(aContent, "null pointer");
NS_PRECONDITION(aRuleWalker, "null pointer");
}
};
struct PseudoRuleProcessorData : public RuleProcessorData {
PseudoRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: RuleProcessorData(aPresContext, aParentContent, aRuleWalker)
{
NS_PRECONDITION(aPseudoTag, "null pointer");
NS_PRECONDITION(aRuleWalker, "null pointer");
mPseudoTag = aPseudoTag;
mComparator = aComparator;
}
nsIAtom* mPseudoTag;
nsICSSPseudoComparator* mComparator;
};
struct StateRuleProcessorData : public RuleProcessorData {
StateRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent)
: RuleProcessorData(aPresContext, aContent, nsnull)
{
NS_PRECONDITION(aContent, "null pointer");
}
};
// IID for the nsIStyleRuleProcessor interface {015575fe-7b6c-11d3-ba05-001083023c2b}
#define NS_ISTYLE_RULE_PROCESSOR_IID \
{0x015575fe, 0x7b6c, 0x11d3, {0xba, 0x05, 0x00, 0x10, 0x83, 0x02, 0x3c, 0x2b}}
@ -69,24 +153,15 @@ public:
// populate rule node tree with nsIStyleRule*
// rules are ordered, those with higher precedence are farthest from the root of the tree
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
// Test if style is dependent on content state
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent) = 0;
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;

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

@ -3,6 +3,7 @@
#include "nsISupports.h"
#include "nsISupportsArray.h"
#include "nsIStyleRuleProcessor.h"
// {2D77A45B-4F3A-4203-A7D2-F4B84D0C1EE4}
#define NS_ISTYLERULESUPPLIER_IID \
@ -17,11 +18,12 @@ class nsIStyleRuleSupplier : public nsISupports {
NS_IMETHOD UseDocumentRules(nsIContent* aContent, PRBool* aResult)=0;
NS_IMETHOD WalkRules(nsIStyleSet* aStyleSet,
nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent)=0;
NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult)=0;
nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData)=0;
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent,
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc,
void* aData,
nsIContent* aContent,
PRBool* aAffects)=0;
};

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

@ -255,9 +255,6 @@ public:
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
PRBool &aAffects);
void WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent);
private:
static nsrefcnt gInstances;
static nsIURI *gQuirkURI;
@ -282,7 +279,16 @@ protected:
nsresult GatherRuleProcessors(void);
void AddImportantRules(nsRuleNode* aCurrLevelNode, nsRuleNode* aLastPrevLevelNode);
void FileRules(nsISupportsArrayEnumFunc aCollectorFunc, void* aData, nsIContent* aContent);
// Enumerate the rules in a way that cares about the order of the
// rules.
void FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
RuleProcessorData* aData);
// Enumerate all the rules in a way that doesn't care about the order
// of the rules and break out if the enumeration is halted.
void WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData);
nsIStyleContext* GetContext(nsIPresContext* aPresContext,
nsIStyleContext* aParentContext,
@ -424,8 +430,8 @@ StyleSetImpl::ClearOverrideRuleProcessors(void)
RecycleArray(mOverrideRuleProcessors);
}
struct RuleProcessorData {
RuleProcessorData(nsISupportsArray* aRuleProcessors)
struct RuleProcessorEnumData {
RuleProcessorEnumData(nsISupportsArray* aRuleProcessors)
: mRuleProcessors(aRuleProcessors),
mPrevProcessor(nsnull)
{}
@ -438,7 +444,7 @@ static PRBool
EnumRuleProcessor(nsISupports* aSheet, void* aData)
{
nsIStyleSheet* sheet = (nsIStyleSheet*)aSheet;
RuleProcessorData* data = (RuleProcessorData*)aData;
RuleProcessorEnumData* data = (RuleProcessorEnumData*)aData;
nsIStyleRuleProcessor* processor = nsnull;
nsresult result = sheet->GetStyleRuleProcessor(processor, data->mPrevProcessor);
@ -458,7 +464,7 @@ StyleSetImpl::GatherRuleProcessors(void)
nsresult result = NS_ERROR_OUT_OF_MEMORY;
if (mAgentSheets && !mAgentRuleProcessors) {
if (EnsureArray(mAgentRuleProcessors)) {
RuleProcessorData data(mAgentRuleProcessors);
RuleProcessorEnumData data(mAgentRuleProcessors);
mAgentSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mAgentRuleProcessors->Count(&count);
@ -470,7 +476,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mUserSheets && !mUserRuleProcessors) {
if (EnsureArray(mUserRuleProcessors)) {
RuleProcessorData data(mUserRuleProcessors);
RuleProcessorEnumData data(mUserRuleProcessors);
mUserSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mUserRuleProcessors->Count(&count);
@ -482,7 +488,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mDocSheets && !mDocRuleProcessors) {
if (EnsureArray(mDocRuleProcessors)) {
RuleProcessorData data(mDocRuleProcessors);
RuleProcessorEnumData data(mDocRuleProcessors);
mDocSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mDocRuleProcessors->Count(&count);
@ -494,7 +500,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mOverrideSheets && !mOverrideRuleProcessors) {
if (EnsureArray(mOverrideRuleProcessors)) {
RuleProcessorData data(mOverrideRuleProcessors);
RuleProcessorEnumData data(mOverrideRuleProcessors);
mOverrideSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mOverrideRuleProcessors->Count(&count);
@ -840,24 +846,16 @@ StyleSetImpl::NotifyStyleSheetStateChanged(PRBool aDisabled)
}
struct RulesMatchingData {
struct RulesMatchingData : public ElementRuleProcessorData {
RulesMatchingData(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
: mPresContext(aPresContext),
mMedium(aMedium),
mContent(aContent),
mParentContext(aParentContext),
mRuleWalker(aRuleWalker)
: ElementRuleProcessorData(aPresContext, aContent, aRuleWalker),
mMedium(aMedium)
{
}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mContent;
nsIStyleContext* mParentContext;
nsRuleWalker* mRuleWalker;
};
static PRBool
@ -866,8 +864,7 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData)
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
RulesMatchingData* data = (RulesMatchingData*)aData;
processor->RulesMatching(data->mPresContext, data->mMedium, data->mContent,
data->mParentContext, data->mRuleWalker);
processor->RulesMatching(data, data->mMedium);
return PR_TRUE;
}
@ -921,10 +918,10 @@ StyleSetImpl::AddImportantRules(nsRuleNode* aCurrLevelNode,
}
}
// Enumerate the rules in a way that cares about the order of the rules.
void
StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
void* aData,
nsIContent* aContent)
RuleProcessorData* aData)
{
// Cascading order:
@ -955,8 +952,8 @@ StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData, aContent);
mStyleRuleSupplier->UseDocumentRules(aContent, &useRuleProcessors);
mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData);
mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors);
}
if (mDocRuleProcessors) {
mDocRuleProcessors->EnumerateForwards(aCollectorFunc, aData);
@ -976,6 +973,40 @@ StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
}
// Enumerate all the rules in a way that doesn't care about the order
// of the rules and break out if the enumeration is halted.
void
StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData)
{
// Walk the agent rules first.
if (mAgentRuleProcessors)
if (!mAgentRuleProcessors->EnumerateForwards(aFunc, aData))
return;
// Walk the user rules next.
if (mUserRuleProcessors)
if (!mUserRuleProcessors->EnumerateForwards(aFunc, aData))
return;
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
// XXX We ignore whether the enumerator wants to halt here!
mStyleRuleSupplier->WalkRules(this, aFunc, aData);
mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors);
}
// Now walk the doc rules.
if (mDocRuleProcessors && useRuleProcessors)
if (!mDocRuleProcessors->EnumerateForwards(aFunc, aData))
return;
// Walk the override rules last.
if (mOverrideRuleProcessors)
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}
#ifdef NS_DEBUG
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) { \
nsrefcnt count = ptr->AddRef(); \
@ -1019,8 +1050,8 @@ nsIStyleContext* StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
EnsureRuleWalker(aPresContext);
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
RulesMatchingData data(aPresContext, medium, aContent, aParentContext, mRuleWalker);
FileRules(EnumRulesMatching, &data, aContent);
RulesMatchingData data(aPresContext, medium, aContent, mRuleWalker);
FileRules(EnumRulesMatching, &data);
result = GetContext(aPresContext, aParentContext, nsnull, aForceUnique);
// Now reset the walker back to the root of the tree.
@ -1063,30 +1094,19 @@ nsIStyleContext* StyleSetImpl::ResolveStyleForNonElement(
}
struct PseudoRulesMatchingData {
struct PseudoRulesMatchingData : public PseudoRuleProcessorData {
PseudoRulesMatchingData(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aWalker)
: mPresContext(aPresContext),
mMedium(aMedium),
mParentContent(aParentContent),
mPseudoTag(aPseudoTag),
mParentContext(aParentContext),
mComparator(aComparator),
mRuleWalker(aWalker)
nsRuleWalker* aRuleWalker)
: PseudoRuleProcessorData(aPresContext, aParentContent, aPseudoTag, aComparator,
aRuleWalker),
mMedium(aMedium)
{
}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mParentContent;
nsIAtom* mPseudoTag;
nsIStyleContext* mParentContext;
nsICSSPseudoComparator* mComparator;
nsRuleWalker* mRuleWalker;
};
static PRBool
@ -1095,9 +1115,7 @@ EnumPseudoRulesMatching(nsISupports* aProcessor, void* aData)
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
PseudoRulesMatchingData* data = (PseudoRulesMatchingData*)aData;
processor->RulesMatching(data->mPresContext, data->mMedium,
data->mParentContent, data->mPseudoTag,
data->mParentContext, data->mComparator, data->mRuleWalker);
processor->RulesMatching(data, data->mMedium);
return PR_TRUE;
}
@ -1129,8 +1147,8 @@ nsIStyleContext* StyleSetImpl::ResolvePseudoStyleFor(nsIPresContext* aPresContex
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aParentContext, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data, aParentContent);
aPseudoTag, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
@ -1171,8 +1189,8 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aParentContext, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data, aParentContent);
aPseudoTag, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
if (!mRuleWalker->AtRoot())
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
@ -1325,16 +1343,13 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
return result;
}
struct StatefulData {
struct StatefulData : public StateRuleProcessorData {
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent)
: mPresContext(aPresContext),
: StateRuleProcessorData(aPresContext, aContent),
mMedium(aMedium),
mContent(aContent),
mStateful(PR_FALSE)
{}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mContent;
PRBool mStateful;
};
@ -1342,8 +1357,7 @@ static PRBool SheetHasStatefulStyle(nsISupports* aProcessor, void *aData)
{
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
StatefulData* data = (StatefulData*)aData;
if (NS_OK == processor->HasStateDependentStyle(data->mPresContext, data->mMedium,
data->mContent)) {
if (NS_OK == processor->HasStateDependentStyle(data, data->mMedium)) {
data->mStateful = PR_TRUE;
return PR_FALSE; // stop iteration
}
@ -1365,7 +1379,7 @@ StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* medium = nsnull;
aPresContext->GetMedium(&medium);
StatefulData data(aPresContext, medium, aContent);
WalkRuleProcessors(SheetHasStatefulStyle, &data, aContent);
WalkRuleProcessors(SheetHasStatefulStyle, &data);
NS_IF_RELEASE(medium);
return ((data.mStateful) ? NS_OK : NS_COMFALSE);
}
@ -1739,8 +1753,9 @@ EnumAffectsStyle(nsISupports *aElement, void *aData)
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
AttributeContentPair *pair = (AttributeContentPair *)aData;
PRBool affects;
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
affects)) || affects)
nsresult res =
sheet->AttributeAffectsStyle(pair->attribute, pair->content, affects);
if (NS_FAILED(res) || affects)
return PR_FALSE; // stop checking
return PR_TRUE;
@ -1965,31 +1980,3 @@ void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
// - none
}
#endif
void
StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent)
{
// Walk the agent rules first.
if (mAgentRuleProcessors)
mAgentRuleProcessors->EnumerateForwards(aFunc, aData);
// Walk the user rules next.
if (mUserRuleProcessors)
mUserRuleProcessors->EnumerateForwards(aFunc, aData);
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
mStyleRuleSupplier->WalkRules(this, aFunc, aData, aContent);
mStyleRuleSupplier->UseDocumentRules(aContent, &useRuleProcessors);
}
// Now walk the doc rules.
if (mDocRuleProcessors && useRuleProcessors)
mDocRuleProcessors->EnumerateForwards(aFunc, aData);
// Walk the override rules last.
if (mOverrideRuleProcessors)
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}

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

@ -88,7 +88,6 @@
#include "prlog.h"
#include "nsCOMPtr.h"
#include "nsIStyleSet.h"
#include "nsIStyleRuleSupplier.h"
#include "nsISizeOfHandler.h"
#include "nsStyleUtil.h"
#include "nsQuickSort.h"
@ -713,23 +712,14 @@ public:
NS_IMETHOD ClearRuleCascades(void);
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
@ -3222,66 +3212,16 @@ CSSRuleProcessor::AppendStyleSheet(nsICSSStyleSheet* aStyleSheet)
return result;
}
MOZ_DECL_CTOR_COUNTER(SelectorMatchesData)
MOZ_DECL_CTOR_COUNTER(RuleProcessorData)
struct SelectorMatchesData {
SelectorMatchesData(nsIPresContext* aPresContext, nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat = nsnull);
virtual ~SelectorMatchesData()
{
MOZ_COUNT_DTOR(SelectorMatchesData);
if (mPreviousSiblingData)
mPreviousSiblingData->Destroy(mPresContext);
if (mParentData)
mParentData->Destroy(mPresContext);
NS_IF_RELEASE(mParentContent);
NS_IF_RELEASE(mContentTag);
NS_IF_RELEASE(mContentID);
NS_IF_RELEASE(mStyledContent);
}
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
}
void Destroy(nsIPresContext* aContext) {
this->~SelectorMatchesData();
aContext->FreeToShell(sizeof(SelectorMatchesData), this);
};
nsIPresContext* mPresContext;
nsIContent* mContent;
nsIContent* mParentContent; // if content, content->GetParent()
nsRuleWalker* mRuleWalker; // Used to add rules to our results.
nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier; // used to query for the current scope
nsIAtom* mContentTag; // if content, then content->GetTag()
nsIAtom* mContentID; // if styled content, then styledcontent->GetID()
nsIStyledContent* mStyledContent; // if content, content->QI(nsIStyledContent)
PRBool mIsHTMLContent; // if content, then does QI on HTMLContent, true or false
PRBool mIsHTMLLink; // if content, calls nsStyleUtil::IsHTMLLink
PRBool mIsSimpleXLink; // if content, calls nsStyleUtil::IsSimpleXLink
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
PRBool mIsQuirkMode; // Possibly remove use of this in SelectorMatches?
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
PRBool mHasAttributes; // if content, content->GetAttrCount() > 0
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
SelectorMatchesData* mPreviousSiblingData;
SelectorMatchesData* mParentData;
};
SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat /*= nsnull*/)
RuleProcessorData::RuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat /*= nsnull*/)
{
MOZ_COUNT_CTOR(SelectorMatchesData);
MOZ_COUNT_CTOR(RuleProcessorData);
NS_PRECONDITION(aPresContext, "null pointer");
NS_ASSERTION(!aContent || aContent->IsContentOfType(nsIContent::eELEMENT),
"non-element leaked into SelectorMatches");
@ -3289,6 +3229,7 @@ SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
mContent = aContent;
mParentContent = nsnull;
mRuleWalker = aRuleWalker;
mScopedRoot = nsnull;
mContentTag = nsnull;
mContentID = nsnull;
@ -3366,6 +3307,21 @@ SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
}
}
RuleProcessorData::~RuleProcessorData()
{
MOZ_COUNT_DTOR(RuleProcessorData);
if (mPreviousSiblingData)
mPreviousSiblingData->Destroy(mPresContext);
if (mParentData)
mParentData->Destroy(mPresContext);
NS_IF_RELEASE(mParentContent);
NS_IF_RELEASE(mContentTag);
NS_IF_RELEASE(mContentID);
NS_IF_RELEASE(mStyledContent);
}
static const PRUnichar kNullCh = PRUnichar('\0');
static PRBool ValueIncludes(const nsString& aValueList, const nsString& aValue, PRBool aCaseSensitive)
@ -3476,7 +3432,7 @@ static PRBool IsSignificantChild(nsIContent* aChild, PRBool aAcceptNonWhitespace
}
static PRBool SelectorMatches(SelectorMatchesData &data,
static PRBool SelectorMatches(RuleProcessorData &data,
nsCSSSelector* aSelector,
PRBool aTestState,
PRInt8 aNegationIndex)
@ -3588,18 +3544,8 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
}
}
else if (nsCSSAtoms::xblBoundElementPseudo == pseudoClass->mAtom) {
if (!data.mStyleRuleSupplier) {
nsCOMPtr<nsIPresShell> shell;
data.mPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIStyleSet> styleSet;
shell->GetStyleSet(getter_AddRefs(styleSet));
styleSet->GetStyleRuleSupplier(getter_AddRefs(data.mStyleRuleSupplier));
}
if (data.mStyleRuleSupplier)
data.mStyleRuleSupplier->MatchesScopedRoot(data.mContent, &result);
else
result = localFalse;
result = (data.mScopedRoot && data.mScopedRoot == data.mContent)
? localTrue : localFalse;
}
else if (nsCSSAtoms::langPseudo == pseudoClass->mAtom) {
// XXX not yet implemented
@ -3796,14 +3742,7 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
return result;
}
struct ContentEnumData : public SelectorMatchesData {
ContentEnumData(nsIPresContext* aPresContext, nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: SelectorMatchesData(aPresContext,aContent,aRuleWalker)
{}
};
static PRBool SelectorMatchesTree(SelectorMatchesData &data,
static PRBool SelectorMatchesTree(RuleProcessorData &data,
nsCSSSelector* aSelector)
{
nsCSSSelector* selector = aSelector;
@ -3812,16 +3751,16 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
nsIContent* content = nsnull;
nsIContent* lastContent = data.mContent;
NS_ADDREF(lastContent);
SelectorMatchesData* curdata = &data;
RuleProcessorData* curdata = &data;
while (nsnull != selector) { // check compound selectors
// Find the appropriate content (whether parent or previous sibling)
// to check next, and if we don't already have a SelectorMatchesData
// to check next, and if we don't already have a RuleProcessorData
// for it, create one.
// for adjacent sibling combinators, the content to test against the
// selector is the previous sibling
nsCompatibility compat = curdata->mIsQuirkMode ? eCompatibility_NavQuirks : eCompatibility_Standard;
SelectorMatchesData* newdata;
RuleProcessorData* newdata;
if (PRUnichar('+') == selector->mOperator) {
newdata = curdata->mPreviousSiblingData;
if (!newdata) {
@ -3838,7 +3777,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
(tag != nsLayoutAtoms::commentTagName)) {
NS_IF_RELEASE(tag);
newdata =
new (curdata->mPresContext) SelectorMatchesData(curdata->mPresContext, content,
new (curdata->mPresContext) RuleProcessorData(curdata->mPresContext, content,
curdata->mRuleWalker, &compat);
curdata->mPreviousSiblingData = newdata;
break;
@ -3860,7 +3799,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
if (!newdata) {
lastContent->GetParent(content);
if (content) {
newdata = new (curdata->mPresContext) SelectorMatchesData(curdata->mPresContext, content,
newdata = new (curdata->mPresContext) RuleProcessorData(curdata->mPresContext, content,
curdata->mRuleWalker, &compat);
curdata->mParentData = newdata;
}
@ -3914,7 +3853,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
static void ContentEnumFunc(nsICSSStyleRule* aRule, void* aData)
{
ContentEnumData* data = (ContentEnumData*)aData;
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
nsCSSSelector* selector = aRule->FirstSelector();
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
@ -3944,35 +3883,22 @@ static PRBool ContentEnumWrap(nsISupports* aRule, void* aData)
#endif
NS_IMETHODIMP
CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
CSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
NS_PRECONDITION(aContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
nsIAtom* idAtom = nsnull;
nsAutoVoidArray classArray;
// setup the ContentEnumData
ContentEnumData data(aPresContext, aContent, aRuleWalker);
nsIStyledContent* styledContent;
if (NS_SUCCEEDED(aContent->QueryInterface(NS_GET_IID(nsIStyledContent), (void**)&styledContent))) {
styledContent->GetID(idAtom);
nsIStyledContent* styledContent = aData->mStyledContent;
if (styledContent)
styledContent->GetClasses(classArray);
NS_RELEASE(styledContent);
}
cascade->mRuleHash.EnumerateAllRules(data.mNameSpaceID, data.mContentTag, idAtom, classArray, ContentEnumFunc, &data);
cascade->mRuleHash.EnumerateAllRules(aData->mNameSpaceID, aData->mContentTag, aData->mContentID, classArray, ContentEnumFunc, aData);
#ifdef DEBUG_RULES
nsISupportsArray* list1;
@ -3980,37 +3906,21 @@ CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
NS_NewISupportsArray(&list1);
NS_NewISupportsArray(&list2);
data.mResults = list1;
cascade->mRuleHash.EnumerateAllRules(data.mNameSpaceID, data.mContentTag, idAtom, classArray, ContentEnumFunc, &data);
data.mResults = list2;
aData->mResults = list1;
cascade->mRuleHash.EnumerateAllRules(aData->mNameSpaceID, aData->mContentTag, aData->mContentID, classArray, ContentEnumFunc, &data);
aData->mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(ContentEnumWrap, &data);
NS_ASSERTION(list1->Equals(list2), "lists not equal");
NS_RELEASE(list1);
NS_RELEASE(list2);
#endif
NS_IF_RELEASE(idAtom);
}
return NS_OK;
}
struct PseudoEnumData : public SelectorMatchesData {
PseudoEnumData(nsIPresContext* aPresContext, nsIContent* aParentContent,
nsIAtom* aPseudoTag, nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: SelectorMatchesData(aPresContext, aParentContent, aRuleWalker)
{
mPseudoTag = aPseudoTag;
mComparator = aComparator;
}
nsIAtom* mPseudoTag;
nsICSSPseudoComparator* mComparator;
};
static void PseudoEnumFunc(nsICSSStyleRule* aRule, void* aData)
{
PseudoEnumData* data = (PseudoEnumData*)aData;
PseudoRuleProcessorData* data = (PseudoRuleProcessorData*)aData;
nsCSSSelector* selector = aRule->FirstSelector();
@ -4058,36 +3968,28 @@ static PRBool PseudoEnumWrap(nsISupports* aRule, void* aData)
#endif
NS_IMETHODIMP
CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
CSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aPseudoTag, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
NS_PRECONDITION(!aParentContent ||
aParentContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(!aData->mContent ||
aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content (if present) must be element");
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
PseudoEnumData data(aPresContext, aParentContent, aPseudoTag, aComparator, aRuleWalker);
cascade->mRuleHash.EnumerateTagRules(aPseudoTag, PseudoEnumFunc, &data);
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag,
PseudoEnumFunc, aData);
#ifdef DEBUG_RULES
nsISupportsArray* list1;
nsISupportsArray* list2;
NS_NewISupportsArray(&list1);
NS_NewISupportsArray(&list2);
data.mResults = list1;
cascade->mRuleHash.EnumerateTagRules(aPseudoTag, PseudoEnumFunc, &data);
data.mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(PseudoEnumWrap, &data);
aData->mResults = list1;
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag, PseudoEnumFunc, aData);
aData->mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(PseudoEnumWrap, aData);
NS_ASSERTION(list1->Equals(list2), "lists not equal");
NS_RELEASE(list1);
NS_RELEASE(list2);
@ -4096,16 +3998,10 @@ CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
return NS_OK;
}
struct StateEnumData : public SelectorMatchesData {
StateEnumData(nsIPresContext* aPresContext, nsIContent* aContent)
: SelectorMatchesData(aPresContext, aContent, nsnull)
{ }
};
static
PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
{
StateEnumData* data = (StateEnumData*)aData;
StateRuleProcessorData* data = (StateRuleProcessorData*)aData;
nsCSSSelector* selector = (nsCSSSelector*)aSelector;
if (SelectorMatches(*data, selector, PR_FALSE, 0)) {
@ -4118,21 +4014,19 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
}
NS_IMETHODIMP
CSSRuleProcessor::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(aContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
PRBool isStateful = PR_FALSE;
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
// look up content in state rule list
StateEnumData data(aPresContext, aContent);
isStateful = (! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, &data)); // if stopped, have state
isStateful = ! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData); // if stopped, have state
}
return ((isStateful) ? NS_OK : NS_COMFALSE);

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

@ -244,23 +244,14 @@ public:
nsIStyleRuleProcessor* aPrevProcessor);
// nsIStyleRuleProcessor api
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
// XXX style rule enumerations
@ -336,7 +327,7 @@ HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl()
mFirstLineRule(nsnull),
mFirstLetterRule(nsnull)
{
NS_INIT_REFCNT();
NS_INIT_ISUPPORTS();
}
HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl()
@ -352,39 +343,10 @@ HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl()
}
}
NS_IMPL_ADDREF(HTMLCSSStyleSheetImpl)
NS_IMPL_RELEASE(HTMLCSSStyleSheetImpl)
nsresult HTMLCSSStyleSheetImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIHTMLCSSStyleSheet))) {
*aInstancePtrResult = (void*) ((nsIHTMLCSSStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStyleSheet))) {
*aInstancePtrResult = (void*) ((nsIStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStyleRuleProcessor))) {
*aInstancePtrResult = (void*) ((nsIStyleRuleProcessor*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*) ((nsISupports*)(nsIStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl,
nsIHTMLCSSStyleSheet,
nsIStyleSheet,
nsIStyleRuleProcessor)
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
@ -396,63 +358,48 @@ HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent)
// just get the one and only style rule from the content's STYLE attribute
styledContent->WalkInlineStyleRules(aRuleWalker);
styledContent->WalkInlineStyleRules(aData->mRuleWalker);
return NS_OK;
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
if (aPseudoTag == nsHTMLAtoms::firstLinePseudo) {
if (!aRuleWalker->AtRoot()) {
if (nsnull == mFirstLineRule) {
mFirstLineRule = new CSSFirstLineRule(this);
if (mFirstLineRule) {
NS_ADDREF(mFirstLineRule);
}
}
if (mFirstLineRule) {
aRuleWalker->Forward(mFirstLineRule);
return NS_OK;
}
}
// We only want to add these rules if there are real :first-letter or
// :first-line rules that cause a pseudo-element frame to be created.
// Otherwise the use of ProbePseudoStyleContextFor will prevent frame
// creation, and adding rules here would cause it.
if (aData->mRuleWalker->AtRoot())
return NS_OK;
nsIAtom* pseudoTag = aData->mPseudoTag;
if (pseudoTag == nsHTMLAtoms::firstLinePseudo) {
if (!mFirstLineRule) {
mFirstLineRule = new CSSFirstLineRule(this);
if (!mFirstLineRule)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFirstLineRule);
}
aData->mRuleWalker->Forward(mFirstLineRule);
}
if (aPseudoTag == nsHTMLAtoms::firstLetterPseudo) {
if (!aRuleWalker->AtRoot()) {
if (nsnull == mFirstLetterRule) {
mFirstLetterRule = new CSSFirstLetterRule(this);
if (mFirstLetterRule) {
NS_ADDREF(mFirstLetterRule);
}
}
if (mFirstLetterRule) {
aRuleWalker->Forward(mFirstLetterRule);
return NS_OK;
}
}
}
// else no pseudo frame style...
else if (pseudoTag == nsHTMLAtoms::firstLetterPseudo) {
if (!mFirstLetterRule) {
mFirstLetterRule = new CSSFirstLetterRule(this);
if (!mFirstLetterRule)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFirstLetterRule);
}
aData->mRuleWalker->Forward(mFirstLetterRule);
}
return NS_OK;
}
@ -474,9 +421,8 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
return NS_COMFALSE;
}

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

@ -559,23 +559,14 @@ public:
nsIStyleRuleProcessor* aPrevProcessor);
// nsIStyleRuleProcessor API
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
// nsIHTMLStyleSheet api
NS_IMETHOD Init(nsIURI* aURL, nsIDocument* aDocument);
@ -750,7 +741,7 @@ NS_IMPL_RELEASE(HTMLStyleSheetImpl)
nsresult HTMLStyleSheetImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
NS_PRECONDITION(aInstancePtrResult, "null out param");
if (aIID.Equals(NS_GET_IID(nsIHTMLStyleSheet))) {
*aInstancePtrResult = NS_STATIC_CAST(nsIHTMLStyleSheet*, this);
@ -798,80 +789,54 @@ HTMLStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
}
NS_IMETHODIMP
HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent) {
nsRuleWalker *ruleWalker = aData->mRuleWalker;
if (styledContent->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIAtom> tag;
styledContent->GetTag(*getter_AddRefs(tag));
nsIAtom* tag = aData->mContentTag;
// if we have anchor colors, check if this is an anchor with an href
if (tag == nsHTMLAtoms::a) {
if (mLinkRule || mVisitedRule || mActiveRule) {
nsLinkState linkState;
if (nsStyleUtil::IsHTMLLink(aContent, tag, aPresContext,
&linkState)) {
switch (linkState) {
if (aData->mIsHTMLLink) {
switch (aData->mLinkState) {
case eLinkState_Unvisited:
if (mLinkRule)
aRuleWalker->Forward(mLinkRule);
ruleWalker->Forward(mLinkRule);
break;
case eLinkState_Visited:
if (mVisitedRule)
aRuleWalker->Forward(mVisitedRule);
ruleWalker->Forward(mVisitedRule);
break;
default:
break;
}
// No need to add to the active rule if it's not a link
if (mActiveRule) { // test active state of link
nsCOMPtr<nsIEventStateManager> eventStateManager;
aPresContext->GetEventStateManager(getter_AddRefs(eventStateManager));
if (eventStateManager) {
PRInt32 state;
if (NS_OK == eventStateManager->GetContentState(aContent,
state)) {
if (state & NS_EVENT_STATE_ACTIVE)
aRuleWalker->Forward(mActiveRule);
}
}
} // end active rule
if (mActiveRule && (aData->mEventState & NS_EVENT_STATE_ACTIVE))
ruleWalker->Forward(mActiveRule);
}
} // end link/visited/active rules
} // end A tag
// add the rule to handle text-align for a <th>
else if (tag == nsHTMLAtoms::th) {
aRuleWalker->Forward(mTableTHRule);
ruleWalker->Forward(mTableTHRule);
}
else if (tag == nsHTMLAtoms::table) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
aRuleWalker->Forward(mDocumentColorRule);
}
if (aData->mIsQuirkMode)
ruleWalker->Forward(mDocumentColorRule);
}
else if (tag == nsHTMLAtoms::html) {
aRuleWalker->Forward(mDocumentColorRule);
ruleWalker->Forward(mDocumentColorRule);
}
} // end html element
// just get the style rules from the content
styledContent->WalkContentStyleRules(aRuleWalker);
styledContent->WalkContentStyleRules(ruleWalker);
}
return NS_OK;
@ -879,31 +844,21 @@ HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
HTMLStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
nsresult result = NS_COMFALSE;
if (mActiveRule || mLinkRule || mVisitedRule) { // do we have any rules dependent on state?
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
if (styledContent) {
if (styledContent->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIAtom> tag;
styledContent->GetTag(*getter_AddRefs(tag));
// if we have anchor colors, check if this is an anchor with an href
if (tag == nsHTMLAtoms::a) {
nsAutoString href;
nsresult attrState = styledContent->GetAttr(kNameSpaceID_None,
nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == attrState) {
result = NS_OK; // yes, style will depend on link state
}
}
}
}
if ((mActiveRule || mLinkRule || mVisitedRule) &&
aData->mStyledContent &&
aData->mIsHTMLContent &&
aData->mContentTag == nsHTMLAtoms::a) {
nsAutoString href;
nsresult attrState =
aData->mStyledContent->GetAttr(kNameSpaceID_None,
nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == attrState)
result = NS_OK; // yes, style will depend on link state
}
return result;
@ -912,13 +867,8 @@ HTMLStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
NS_IMETHODIMP
HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
// no pseudo frame style
return NS_OK;

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

@ -289,10 +289,11 @@ public:
// nsIStyleRuleSupplier
NS_IMETHOD UseDocumentRules(nsIContent* aContent, PRBool* aResult);
NS_IMETHOD WalkRules(nsIStyleSet* aStyleSet,
nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent);
NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult);
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent, PRBool* aAffects);
nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData);
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc,
void* aData, nsIContent* aContent,
PRBool* aAffects);
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument* aDocument) { return NS_OK; }
@ -354,7 +355,7 @@ protected:
void GetEnclosingScope(nsIContent* aContent, nsIContent** aParent);
void GetOutermostStyleScope(nsIContent* aContent, nsIContent** aParent);
void WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData,
void WalkRules(nsISupportsArrayEnumFunc aFunc, RuleProcessorData* aData,
nsIContent* aParent, nsIContent* aCurrContent);
void AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData,
@ -402,9 +403,6 @@ protected:
// A queue of binding attached event handlers that are awaiting execution.
nsCOMPtr<nsISupportsArray> mAttachedQueue;
// A current scope. Used when walking style rules.
nsIContent* mCurrentStyleRoot;
};
// Implementation /////////////////////////////////////////////////////////////////
@ -416,7 +414,6 @@ NS_IMPL_ISUPPORTS3(nsBindingManager, nsIBindingManager, nsIStyleRuleSupplier, ns
// Constructors/Destructors
nsBindingManager::nsBindingManager(void)
:mCurrentStyleRoot(nsnull)
{
NS_INIT_REFCNT();
@ -1200,13 +1197,6 @@ nsBindingManager::InheritsStyle(nsIContent* aContent, PRBool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::MatchesScopedRoot(nsIContent* aContent, PRBool* aResult)
{
*aResult = (mCurrentStyleRoot == aContent);
return NS_OK;
}
NS_IMETHODIMP
nsBindingManager::UseDocumentRules(nsIContent* aContent, PRBool* aResult)
{
@ -1253,13 +1243,14 @@ nsBindingManager::GetOutermostStyleScope(nsIContent* aContent,
}
void
nsBindingManager::WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData,
nsBindingManager::WalkRules(nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData,
nsIContent* aParent, nsIContent* aCurrContent)
{
nsCOMPtr<nsIXBLBinding> binding;
GetBinding(aCurrContent, getter_AddRefs(binding));
if (binding) {
mCurrentStyleRoot = aCurrContent;
aData->mScopedRoot = aCurrContent;
binding->WalkRules(aFunc, aData);
}
if (aParent != aCurrContent) {
@ -1272,22 +1263,26 @@ nsBindingManager::WalkRules(nsISupportsArrayEnumFunc aFunc, void* aData,
NS_IMETHODIMP
nsBindingManager::WalkRules(nsIStyleSet* aStyleSet,
nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent)
nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData)
{
if (!aContent)
nsIContent *content = aData->mContent;
if (!content)
return NS_OK;
nsCOMPtr<nsIContent> parent;
GetOutermostStyleScope(aContent, getter_AddRefs(parent));
GetOutermostStyleScope(content, getter_AddRefs(parent));
WalkRules(aFunc, aData, parent, aContent);
WalkRules(aFunc, aData, parent, content);
// Null out the scoped root that we set repeatedly in the other |WalkRules|.
aData->mScopedRoot = nsnull;
if (parent) {
// We cut ourselves off, but we still need to walk the document's attribute sheet
// so that inline style continues to work on anonymous content.
nsCOMPtr<nsIDocument> document;
aContent->GetDocument(*getter_AddRefs(document));
content->GetDocument(*getter_AddRefs(document));
nsCOMPtr<nsIHTMLContentContainer> container(do_QueryInterface(document));
if (container) {
nsCOMPtr<nsIHTMLCSSStyleSheet> inlineSheet;
@ -1298,8 +1293,6 @@ nsBindingManager::WalkRules(nsIStyleSet* aStyleSet,
}
}
// Null out our mCurrentStyleRoot.
mCurrentStyleRoot = nsnull;
return NS_OK;
}

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

@ -88,7 +88,6 @@
#include "prlog.h"
#include "nsCOMPtr.h"
#include "nsIStyleSet.h"
#include "nsIStyleRuleSupplier.h"
#include "nsISizeOfHandler.h"
#include "nsStyleUtil.h"
#include "nsQuickSort.h"
@ -713,23 +712,14 @@ public:
NS_IMETHOD ClearRuleCascades(void);
// nsIStyleRuleProcessor
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
@ -3222,66 +3212,16 @@ CSSRuleProcessor::AppendStyleSheet(nsICSSStyleSheet* aStyleSheet)
return result;
}
MOZ_DECL_CTOR_COUNTER(SelectorMatchesData)
MOZ_DECL_CTOR_COUNTER(RuleProcessorData)
struct SelectorMatchesData {
SelectorMatchesData(nsIPresContext* aPresContext, nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat = nsnull);
virtual ~SelectorMatchesData()
{
MOZ_COUNT_DTOR(SelectorMatchesData);
if (mPreviousSiblingData)
mPreviousSiblingData->Destroy(mPresContext);
if (mParentData)
mParentData->Destroy(mPresContext);
NS_IF_RELEASE(mParentContent);
NS_IF_RELEASE(mContentTag);
NS_IF_RELEASE(mContentID);
NS_IF_RELEASE(mStyledContent);
}
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
}
void Destroy(nsIPresContext* aContext) {
this->~SelectorMatchesData();
aContext->FreeToShell(sizeof(SelectorMatchesData), this);
};
nsIPresContext* mPresContext;
nsIContent* mContent;
nsIContent* mParentContent; // if content, content->GetParent()
nsRuleWalker* mRuleWalker; // Used to add rules to our results.
nsCOMPtr<nsIStyleRuleSupplier> mStyleRuleSupplier; // used to query for the current scope
nsIAtom* mContentTag; // if content, then content->GetTag()
nsIAtom* mContentID; // if styled content, then styledcontent->GetID()
nsIStyledContent* mStyledContent; // if content, content->QI(nsIStyledContent)
PRBool mIsHTMLContent; // if content, then does QI on HTMLContent, true or false
PRBool mIsHTMLLink; // if content, calls nsStyleUtil::IsHTMLLink
PRBool mIsSimpleXLink; // if content, calls nsStyleUtil::IsSimpleXLink
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
PRBool mIsQuirkMode; // Possibly remove use of this in SelectorMatches?
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
PRBool mHasAttributes; // if content, content->GetAttrCount() > 0
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
SelectorMatchesData* mPreviousSiblingData;
SelectorMatchesData* mParentData;
};
SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat /*= nsnull*/)
RuleProcessorData::RuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat /*= nsnull*/)
{
MOZ_COUNT_CTOR(SelectorMatchesData);
MOZ_COUNT_CTOR(RuleProcessorData);
NS_PRECONDITION(aPresContext, "null pointer");
NS_ASSERTION(!aContent || aContent->IsContentOfType(nsIContent::eELEMENT),
"non-element leaked into SelectorMatches");
@ -3289,6 +3229,7 @@ SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
mContent = aContent;
mParentContent = nsnull;
mRuleWalker = aRuleWalker;
mScopedRoot = nsnull;
mContentTag = nsnull;
mContentID = nsnull;
@ -3366,6 +3307,21 @@ SelectorMatchesData::SelectorMatchesData(nsIPresContext* aPresContext,
}
}
RuleProcessorData::~RuleProcessorData()
{
MOZ_COUNT_DTOR(RuleProcessorData);
if (mPreviousSiblingData)
mPreviousSiblingData->Destroy(mPresContext);
if (mParentData)
mParentData->Destroy(mPresContext);
NS_IF_RELEASE(mParentContent);
NS_IF_RELEASE(mContentTag);
NS_IF_RELEASE(mContentID);
NS_IF_RELEASE(mStyledContent);
}
static const PRUnichar kNullCh = PRUnichar('\0');
static PRBool ValueIncludes(const nsString& aValueList, const nsString& aValue, PRBool aCaseSensitive)
@ -3476,7 +3432,7 @@ static PRBool IsSignificantChild(nsIContent* aChild, PRBool aAcceptNonWhitespace
}
static PRBool SelectorMatches(SelectorMatchesData &data,
static PRBool SelectorMatches(RuleProcessorData &data,
nsCSSSelector* aSelector,
PRBool aTestState,
PRInt8 aNegationIndex)
@ -3588,18 +3544,8 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
}
}
else if (nsCSSAtoms::xblBoundElementPseudo == pseudoClass->mAtom) {
if (!data.mStyleRuleSupplier) {
nsCOMPtr<nsIPresShell> shell;
data.mPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIStyleSet> styleSet;
shell->GetStyleSet(getter_AddRefs(styleSet));
styleSet->GetStyleRuleSupplier(getter_AddRefs(data.mStyleRuleSupplier));
}
if (data.mStyleRuleSupplier)
data.mStyleRuleSupplier->MatchesScopedRoot(data.mContent, &result);
else
result = localFalse;
result = (data.mScopedRoot && data.mScopedRoot == data.mContent)
? localTrue : localFalse;
}
else if (nsCSSAtoms::langPseudo == pseudoClass->mAtom) {
// XXX not yet implemented
@ -3796,14 +3742,7 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
return result;
}
struct ContentEnumData : public SelectorMatchesData {
ContentEnumData(nsIPresContext* aPresContext, nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: SelectorMatchesData(aPresContext,aContent,aRuleWalker)
{}
};
static PRBool SelectorMatchesTree(SelectorMatchesData &data,
static PRBool SelectorMatchesTree(RuleProcessorData &data,
nsCSSSelector* aSelector)
{
nsCSSSelector* selector = aSelector;
@ -3812,16 +3751,16 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
nsIContent* content = nsnull;
nsIContent* lastContent = data.mContent;
NS_ADDREF(lastContent);
SelectorMatchesData* curdata = &data;
RuleProcessorData* curdata = &data;
while (nsnull != selector) { // check compound selectors
// Find the appropriate content (whether parent or previous sibling)
// to check next, and if we don't already have a SelectorMatchesData
// to check next, and if we don't already have a RuleProcessorData
// for it, create one.
// for adjacent sibling combinators, the content to test against the
// selector is the previous sibling
nsCompatibility compat = curdata->mIsQuirkMode ? eCompatibility_NavQuirks : eCompatibility_Standard;
SelectorMatchesData* newdata;
RuleProcessorData* newdata;
if (PRUnichar('+') == selector->mOperator) {
newdata = curdata->mPreviousSiblingData;
if (!newdata) {
@ -3838,7 +3777,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
(tag != nsLayoutAtoms::commentTagName)) {
NS_IF_RELEASE(tag);
newdata =
new (curdata->mPresContext) SelectorMatchesData(curdata->mPresContext, content,
new (curdata->mPresContext) RuleProcessorData(curdata->mPresContext, content,
curdata->mRuleWalker, &compat);
curdata->mPreviousSiblingData = newdata;
break;
@ -3860,7 +3799,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
if (!newdata) {
lastContent->GetParent(content);
if (content) {
newdata = new (curdata->mPresContext) SelectorMatchesData(curdata->mPresContext, content,
newdata = new (curdata->mPresContext) RuleProcessorData(curdata->mPresContext, content,
curdata->mRuleWalker, &compat);
curdata->mParentData = newdata;
}
@ -3914,7 +3853,7 @@ static PRBool SelectorMatchesTree(SelectorMatchesData &data,
static void ContentEnumFunc(nsICSSStyleRule* aRule, void* aData)
{
ContentEnumData* data = (ContentEnumData*)aData;
ElementRuleProcessorData* data = (ElementRuleProcessorData*)aData;
nsCSSSelector* selector = aRule->FirstSelector();
if (SelectorMatches(*data, selector, PR_TRUE, 0)) {
@ -3944,35 +3883,22 @@ static PRBool ContentEnumWrap(nsISupports* aRule, void* aData)
#endif
NS_IMETHODIMP
CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
CSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
NS_PRECONDITION(aContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
nsIAtom* idAtom = nsnull;
nsAutoVoidArray classArray;
// setup the ContentEnumData
ContentEnumData data(aPresContext, aContent, aRuleWalker);
nsIStyledContent* styledContent;
if (NS_SUCCEEDED(aContent->QueryInterface(NS_GET_IID(nsIStyledContent), (void**)&styledContent))) {
styledContent->GetID(idAtom);
nsIStyledContent* styledContent = aData->mStyledContent;
if (styledContent)
styledContent->GetClasses(classArray);
NS_RELEASE(styledContent);
}
cascade->mRuleHash.EnumerateAllRules(data.mNameSpaceID, data.mContentTag, idAtom, classArray, ContentEnumFunc, &data);
cascade->mRuleHash.EnumerateAllRules(aData->mNameSpaceID, aData->mContentTag, aData->mContentID, classArray, ContentEnumFunc, aData);
#ifdef DEBUG_RULES
nsISupportsArray* list1;
@ -3980,37 +3906,21 @@ CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
NS_NewISupportsArray(&list1);
NS_NewISupportsArray(&list2);
data.mResults = list1;
cascade->mRuleHash.EnumerateAllRules(data.mNameSpaceID, data.mContentTag, idAtom, classArray, ContentEnumFunc, &data);
data.mResults = list2;
aData->mResults = list1;
cascade->mRuleHash.EnumerateAllRules(aData->mNameSpaceID, aData->mContentTag, aData->mContentID, classArray, ContentEnumFunc, &data);
aData->mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(ContentEnumWrap, &data);
NS_ASSERTION(list1->Equals(list2), "lists not equal");
NS_RELEASE(list1);
NS_RELEASE(list2);
#endif
NS_IF_RELEASE(idAtom);
}
return NS_OK;
}
struct PseudoEnumData : public SelectorMatchesData {
PseudoEnumData(nsIPresContext* aPresContext, nsIContent* aParentContent,
nsIAtom* aPseudoTag, nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: SelectorMatchesData(aPresContext, aParentContent, aRuleWalker)
{
mPseudoTag = aPseudoTag;
mComparator = aComparator;
}
nsIAtom* mPseudoTag;
nsICSSPseudoComparator* mComparator;
};
static void PseudoEnumFunc(nsICSSStyleRule* aRule, void* aData)
{
PseudoEnumData* data = (PseudoEnumData*)aData;
PseudoRuleProcessorData* data = (PseudoRuleProcessorData*)aData;
nsCSSSelector* selector = aRule->FirstSelector();
@ -4058,36 +3968,28 @@ static PRBool PseudoEnumWrap(nsISupports* aRule, void* aData)
#endif
NS_IMETHODIMP
CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
CSSRuleProcessor::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aPseudoTag, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
NS_PRECONDITION(!aParentContent ||
aParentContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(!aData->mContent ||
aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content (if present) must be element");
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
PseudoEnumData data(aPresContext, aParentContent, aPseudoTag, aComparator, aRuleWalker);
cascade->mRuleHash.EnumerateTagRules(aPseudoTag, PseudoEnumFunc, &data);
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag,
PseudoEnumFunc, aData);
#ifdef DEBUG_RULES
nsISupportsArray* list1;
nsISupportsArray* list2;
NS_NewISupportsArray(&list1);
NS_NewISupportsArray(&list2);
data.mResults = list1;
cascade->mRuleHash.EnumerateTagRules(aPseudoTag, PseudoEnumFunc, &data);
data.mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(PseudoEnumWrap, &data);
aData->mResults = list1;
cascade->mRuleHash.EnumerateTagRules(aData->mPseudoTag, PseudoEnumFunc, aData);
aData->mResults = list2;
cascade->mWeightedRules->EnumerateBackwards(PseudoEnumWrap, aData);
NS_ASSERTION(list1->Equals(list2), "lists not equal");
NS_RELEASE(list1);
NS_RELEASE(list2);
@ -4096,16 +3998,10 @@ CSSRuleProcessor::RulesMatching(nsIPresContext* aPresContext,
return NS_OK;
}
struct StateEnumData : public SelectorMatchesData {
StateEnumData(nsIPresContext* aPresContext, nsIContent* aContent)
: SelectorMatchesData(aPresContext, aContent, nsnull)
{ }
};
static
PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
{
StateEnumData* data = (StateEnumData*)aData;
StateRuleProcessorData* data = (StateRuleProcessorData*)aData;
nsCSSSelector* selector = (nsCSSSelector*)aSelector;
if (SelectorMatches(*data, selector, PR_FALSE, 0)) {
@ -4118,21 +4014,19 @@ PRBool PR_CALLBACK StateEnumFunc(void* aSelector, void* aData)
}
NS_IMETHODIMP
CSSRuleProcessor::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
CSSRuleProcessor::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(aContent->IsContentOfType(nsIContent::eELEMENT),
NS_PRECONDITION(aData->mContent->IsContentOfType(nsIContent::eELEMENT),
"content must be element");
PRBool isStateful = PR_FALSE;
RuleCascadeData* cascade = GetRuleCascade(aPresContext, aMedium);
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext, aMedium);
if (cascade) {
// look up content in state rule list
StateEnumData data(aPresContext, aContent);
isStateful = (! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, &data)); // if stopped, have state
isStateful = ! cascade->mStateSelectors.EnumerateForwards(StateEnumFunc, aData); // if stopped, have state
}
return ((isStateful) ? NS_OK : NS_COMFALSE);

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

@ -244,23 +244,14 @@ public:
nsIStyleRuleProcessor* aPrevProcessor);
// nsIStyleRuleProcessor api
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
// XXX style rule enumerations
@ -336,7 +327,7 @@ HTMLCSSStyleSheetImpl::HTMLCSSStyleSheetImpl()
mFirstLineRule(nsnull),
mFirstLetterRule(nsnull)
{
NS_INIT_REFCNT();
NS_INIT_ISUPPORTS();
}
HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl()
@ -352,39 +343,10 @@ HTMLCSSStyleSheetImpl::~HTMLCSSStyleSheetImpl()
}
}
NS_IMPL_ADDREF(HTMLCSSStyleSheetImpl)
NS_IMPL_RELEASE(HTMLCSSStyleSheetImpl)
nsresult HTMLCSSStyleSheetImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(NS_GET_IID(nsIHTMLCSSStyleSheet))) {
*aInstancePtrResult = (void*) ((nsIHTMLCSSStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStyleSheet))) {
*aInstancePtrResult = (void*) ((nsIStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStyleRuleProcessor))) {
*aInstancePtrResult = (void*) ((nsIStyleRuleProcessor*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtrResult = (void*) ((nsISupports*)(nsIStyleSheet*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ISUPPORTS3(HTMLCSSStyleSheetImpl,
nsIHTMLCSSStyleSheet,
nsIStyleSheet,
nsIStyleRuleProcessor)
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
@ -396,63 +358,48 @@ HTMLCSSStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent)
// just get the one and only style rule from the content's STYLE attribute
styledContent->WalkInlineStyleRules(aRuleWalker);
styledContent->WalkInlineStyleRules(aData->mRuleWalker);
return NS_OK;
}
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
HTMLCSSStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
if (aPseudoTag == nsHTMLAtoms::firstLinePseudo) {
if (!aRuleWalker->AtRoot()) {
if (nsnull == mFirstLineRule) {
mFirstLineRule = new CSSFirstLineRule(this);
if (mFirstLineRule) {
NS_ADDREF(mFirstLineRule);
}
}
if (mFirstLineRule) {
aRuleWalker->Forward(mFirstLineRule);
return NS_OK;
}
}
// We only want to add these rules if there are real :first-letter or
// :first-line rules that cause a pseudo-element frame to be created.
// Otherwise the use of ProbePseudoStyleContextFor will prevent frame
// creation, and adding rules here would cause it.
if (aData->mRuleWalker->AtRoot())
return NS_OK;
nsIAtom* pseudoTag = aData->mPseudoTag;
if (pseudoTag == nsHTMLAtoms::firstLinePseudo) {
if (!mFirstLineRule) {
mFirstLineRule = new CSSFirstLineRule(this);
if (!mFirstLineRule)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFirstLineRule);
}
aData->mRuleWalker->Forward(mFirstLineRule);
}
if (aPseudoTag == nsHTMLAtoms::firstLetterPseudo) {
if (!aRuleWalker->AtRoot()) {
if (nsnull == mFirstLetterRule) {
mFirstLetterRule = new CSSFirstLetterRule(this);
if (mFirstLetterRule) {
NS_ADDREF(mFirstLetterRule);
}
}
if (mFirstLetterRule) {
aRuleWalker->Forward(mFirstLetterRule);
return NS_OK;
}
}
}
// else no pseudo frame style...
else if (pseudoTag == nsHTMLAtoms::firstLetterPseudo) {
if (!mFirstLetterRule) {
mFirstLetterRule = new CSSFirstLetterRule(this);
if (!mFirstLetterRule)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFirstLetterRule);
}
aData->mRuleWalker->Forward(mFirstLetterRule);
}
return NS_OK;
}
@ -474,9 +421,8 @@ HTMLCSSStyleSheetImpl::Init(nsIURI* aURL, nsIDocument* aDocument)
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLCSSStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
HTMLCSSStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
return NS_COMFALSE;
}

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

@ -559,23 +559,14 @@ public:
nsIStyleRuleProcessor* aPrevProcessor);
// nsIStyleRuleProcessor API
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker);
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium);
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent);
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium);
// nsIHTMLStyleSheet api
NS_IMETHOD Init(nsIURI* aURL, nsIDocument* aDocument);
@ -750,7 +741,7 @@ NS_IMPL_RELEASE(HTMLStyleSheetImpl)
nsresult HTMLStyleSheetImpl::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
NS_PRECONDITION(aInstancePtrResult, "null out param");
if (aIID.Equals(NS_GET_IID(nsIHTMLStyleSheet))) {
*aInstancePtrResult = NS_STATIC_CAST(nsIHTMLStyleSheet*, this);
@ -798,80 +789,54 @@ HTMLStyleSheetImpl::GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
}
NS_IMETHODIMP
HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium)
{
NS_PRECONDITION(nsnull != aPresContext, "null arg");
NS_PRECONDITION(nsnull != aContent, "null arg");
NS_PRECONDITION(nsnull != aRuleWalker, "null arg");
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent) {
nsRuleWalker *ruleWalker = aData->mRuleWalker;
if (styledContent->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIAtom> tag;
styledContent->GetTag(*getter_AddRefs(tag));
nsIAtom* tag = aData->mContentTag;
// if we have anchor colors, check if this is an anchor with an href
if (tag == nsHTMLAtoms::a) {
if (mLinkRule || mVisitedRule || mActiveRule) {
nsLinkState linkState;
if (nsStyleUtil::IsHTMLLink(aContent, tag, aPresContext,
&linkState)) {
switch (linkState) {
if (aData->mIsHTMLLink) {
switch (aData->mLinkState) {
case eLinkState_Unvisited:
if (mLinkRule)
aRuleWalker->Forward(mLinkRule);
ruleWalker->Forward(mLinkRule);
break;
case eLinkState_Visited:
if (mVisitedRule)
aRuleWalker->Forward(mVisitedRule);
ruleWalker->Forward(mVisitedRule);
break;
default:
break;
}
// No need to add to the active rule if it's not a link
if (mActiveRule) { // test active state of link
nsCOMPtr<nsIEventStateManager> eventStateManager;
aPresContext->GetEventStateManager(getter_AddRefs(eventStateManager));
if (eventStateManager) {
PRInt32 state;
if (NS_OK == eventStateManager->GetContentState(aContent,
state)) {
if (state & NS_EVENT_STATE_ACTIVE)
aRuleWalker->Forward(mActiveRule);
}
}
} // end active rule
if (mActiveRule && (aData->mEventState & NS_EVENT_STATE_ACTIVE))
ruleWalker->Forward(mActiveRule);
}
} // end link/visited/active rules
} // end A tag
// add the rule to handle text-align for a <th>
else if (tag == nsHTMLAtoms::th) {
aRuleWalker->Forward(mTableTHRule);
ruleWalker->Forward(mTableTHRule);
}
else if (tag == nsHTMLAtoms::table) {
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
aRuleWalker->Forward(mDocumentColorRule);
}
if (aData->mIsQuirkMode)
ruleWalker->Forward(mDocumentColorRule);
}
else if (tag == nsHTMLAtoms::html) {
aRuleWalker->Forward(mDocumentColorRule);
ruleWalker->Forward(mDocumentColorRule);
}
} // end html element
// just get the style rules from the content
styledContent->WalkContentStyleRules(aRuleWalker);
styledContent->WalkContentStyleRules(ruleWalker);
}
return NS_OK;
@ -879,31 +844,21 @@ HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
// Test if style is dependent on content state
NS_IMETHODIMP
HTMLStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent)
HTMLStyleSheetImpl::HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium)
{
nsresult result = NS_COMFALSE;
if (mActiveRule || mLinkRule || mVisitedRule) { // do we have any rules dependent on state?
nsCOMPtr<nsIStyledContent> styledContent(do_QueryInterface(aContent));
if (styledContent) {
if (styledContent->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIAtom> tag;
styledContent->GetTag(*getter_AddRefs(tag));
// if we have anchor colors, check if this is an anchor with an href
if (tag == nsHTMLAtoms::a) {
nsAutoString href;
nsresult attrState = styledContent->GetAttr(kNameSpaceID_None,
nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == attrState) {
result = NS_OK; // yes, style will depend on link state
}
}
}
}
if ((mActiveRule || mLinkRule || mVisitedRule) &&
aData->mStyledContent &&
aData->mIsHTMLContent &&
aData->mContentTag == nsHTMLAtoms::a) {
nsAutoString href;
nsresult attrState =
aData->mStyledContent->GetAttr(kNameSpaceID_None,
nsHTMLAtoms::href, href);
if (NS_CONTENT_ATTR_HAS_VALUE == attrState)
result = NS_OK; // yes, style will depend on link state
}
return result;
@ -912,13 +867,8 @@ HTMLStyleSheetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
NS_IMETHODIMP
HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium)
{
// no pseudo frame style
return NS_OK;

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

@ -41,6 +41,8 @@
#include <stdio.h>
#include "nsISupports.h"
#include "nsIPresContext.h" // for nsCompatability
#include "nsILinkHandler.h"
class nsISizeOfHandler;
@ -48,11 +50,93 @@ class nsIStyleSheet;
class nsIStyleContext;
class nsIPresContext;
class nsIContent;
class nsIStyledContent;
class nsISupportsArray;
class nsIAtom;
class nsICSSPseudoComparator;
class nsRuleWalker;
// The implementation of the constructor and destructor are currently in
// nsCSSStyleSheet.cpp.
struct RuleProcessorData {
RuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker,
nsCompatibility* aCompat = nsnull);
virtual ~RuleProcessorData();
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
}
void Destroy(nsIPresContext* aContext) {
this->~RuleProcessorData();
aContext->FreeToShell(sizeof(RuleProcessorData), this);
};
nsIPresContext* mPresContext;
nsIContent* mContent;
nsIContent* mParentContent; // if content, content->GetParent()
nsRuleWalker* mRuleWalker; // Used to add rules to our results.
nsIContent* mScopedRoot; // Root of scoped stylesheet (set and unset by the supplier of the scoped stylesheet
nsIAtom* mContentTag; // if content, then content->GetTag()
nsIAtom* mContentID; // if styled content, then styledcontent->GetID()
nsIStyledContent* mStyledContent; // if content, content->QI(nsIStyledContent)
PRBool mIsHTMLContent; // if content, then does QI on HTMLContent, true or false
PRBool mIsHTMLLink; // if content, calls nsStyleUtil::IsHTMLLink
PRBool mIsSimpleXLink; // if content, calls nsStyleUtil::IsSimpleXLink
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
PRBool mIsQuirkMode; // Possibly remove use of this in SelectorMatches?
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
PRBool mHasAttributes; // if content, content->GetAttrCount() > 0
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
RuleProcessorData* mPreviousSiblingData;
RuleProcessorData* mParentData;
};
struct ElementRuleProcessorData : public RuleProcessorData {
ElementRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent,
nsRuleWalker* aRuleWalker)
: RuleProcessorData(aPresContext,aContent,aRuleWalker)
{
NS_PRECONDITION(aContent, "null pointer");
NS_PRECONDITION(aRuleWalker, "null pointer");
}
};
struct PseudoRuleProcessorData : public RuleProcessorData {
PseudoRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker)
: RuleProcessorData(aPresContext, aParentContent, aRuleWalker)
{
NS_PRECONDITION(aPseudoTag, "null pointer");
NS_PRECONDITION(aRuleWalker, "null pointer");
mPseudoTag = aPseudoTag;
mComparator = aComparator;
}
nsIAtom* mPseudoTag;
nsICSSPseudoComparator* mComparator;
};
struct StateRuleProcessorData : public RuleProcessorData {
StateRuleProcessorData(nsIPresContext* aPresContext,
nsIContent* aContent)
: RuleProcessorData(aPresContext, aContent, nsnull)
{
NS_PRECONDITION(aContent, "null pointer");
}
};
// IID for the nsIStyleRuleProcessor interface {015575fe-7b6c-11d3-ba05-001083023c2b}
#define NS_ISTYLE_RULE_PROCESSOR_IID \
{0x015575fe, 0x7b6c, 0x11d3, {0xba, 0x05, 0x00, 0x10, 0x83, 0x02, 0x3c, 0x2b}}
@ -69,24 +153,15 @@ public:
// populate rule node tree with nsIStyleRule*
// rules are ordered, those with higher precedence are farthest from the root of the tree
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD RulesMatching(ElementRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
NS_IMETHOD RulesMatching(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD RulesMatching(PseudoRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
// Test if style is dependent on content state
NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent) = 0;
NS_IMETHOD HasStateDependentStyle(StateRuleProcessorData* aData,
nsIAtom* aMedium) = 0;
#ifdef DEBUG
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;

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

@ -3,6 +3,7 @@
#include "nsISupports.h"
#include "nsISupportsArray.h"
#include "nsIStyleRuleProcessor.h"
// {2D77A45B-4F3A-4203-A7D2-F4B84D0C1EE4}
#define NS_ISTYLERULESUPPLIER_IID \
@ -17,11 +18,12 @@ class nsIStyleRuleSupplier : public nsISupports {
NS_IMETHOD UseDocumentRules(nsIContent* aContent, PRBool* aResult)=0;
NS_IMETHOD WalkRules(nsIStyleSet* aStyleSet,
nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent)=0;
NS_IMETHOD MatchesScopedRoot(nsIContent* aContent, PRBool* aResult)=0;
nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData)=0;
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc, void* aData, nsIContent* aContent,
NS_IMETHOD AttributeAffectsStyle(nsISupportsArrayEnumFunc aFunc,
void* aData,
nsIContent* aContent,
PRBool* aAffects)=0;
};

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

@ -255,9 +255,6 @@ public:
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
PRBool &aAffects);
void WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent);
private:
static nsrefcnt gInstances;
static nsIURI *gQuirkURI;
@ -282,7 +279,16 @@ protected:
nsresult GatherRuleProcessors(void);
void AddImportantRules(nsRuleNode* aCurrLevelNode, nsRuleNode* aLastPrevLevelNode);
void FileRules(nsISupportsArrayEnumFunc aCollectorFunc, void* aData, nsIContent* aContent);
// Enumerate the rules in a way that cares about the order of the
// rules.
void FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
RuleProcessorData* aData);
// Enumerate all the rules in a way that doesn't care about the order
// of the rules and break out if the enumeration is halted.
void WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData);
nsIStyleContext* GetContext(nsIPresContext* aPresContext,
nsIStyleContext* aParentContext,
@ -424,8 +430,8 @@ StyleSetImpl::ClearOverrideRuleProcessors(void)
RecycleArray(mOverrideRuleProcessors);
}
struct RuleProcessorData {
RuleProcessorData(nsISupportsArray* aRuleProcessors)
struct RuleProcessorEnumData {
RuleProcessorEnumData(nsISupportsArray* aRuleProcessors)
: mRuleProcessors(aRuleProcessors),
mPrevProcessor(nsnull)
{}
@ -438,7 +444,7 @@ static PRBool
EnumRuleProcessor(nsISupports* aSheet, void* aData)
{
nsIStyleSheet* sheet = (nsIStyleSheet*)aSheet;
RuleProcessorData* data = (RuleProcessorData*)aData;
RuleProcessorEnumData* data = (RuleProcessorEnumData*)aData;
nsIStyleRuleProcessor* processor = nsnull;
nsresult result = sheet->GetStyleRuleProcessor(processor, data->mPrevProcessor);
@ -458,7 +464,7 @@ StyleSetImpl::GatherRuleProcessors(void)
nsresult result = NS_ERROR_OUT_OF_MEMORY;
if (mAgentSheets && !mAgentRuleProcessors) {
if (EnsureArray(mAgentRuleProcessors)) {
RuleProcessorData data(mAgentRuleProcessors);
RuleProcessorEnumData data(mAgentRuleProcessors);
mAgentSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mAgentRuleProcessors->Count(&count);
@ -470,7 +476,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mUserSheets && !mUserRuleProcessors) {
if (EnsureArray(mUserRuleProcessors)) {
RuleProcessorData data(mUserRuleProcessors);
RuleProcessorEnumData data(mUserRuleProcessors);
mUserSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mUserRuleProcessors->Count(&count);
@ -482,7 +488,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mDocSheets && !mDocRuleProcessors) {
if (EnsureArray(mDocRuleProcessors)) {
RuleProcessorData data(mDocRuleProcessors);
RuleProcessorEnumData data(mDocRuleProcessors);
mDocSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mDocRuleProcessors->Count(&count);
@ -494,7 +500,7 @@ StyleSetImpl::GatherRuleProcessors(void)
if (mOverrideSheets && !mOverrideRuleProcessors) {
if (EnsureArray(mOverrideRuleProcessors)) {
RuleProcessorData data(mOverrideRuleProcessors);
RuleProcessorEnumData data(mOverrideRuleProcessors);
mOverrideSheets->EnumerateBackwards(EnumRuleProcessor, &data);
PRUint32 count;
mOverrideRuleProcessors->Count(&count);
@ -840,24 +846,16 @@ StyleSetImpl::NotifyStyleSheetStateChanged(PRBool aDisabled)
}
struct RulesMatchingData {
struct RulesMatchingData : public ElementRuleProcessorData {
RulesMatchingData(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aContent,
nsIStyleContext* aParentContext,
nsRuleWalker* aRuleWalker)
: mPresContext(aPresContext),
mMedium(aMedium),
mContent(aContent),
mParentContext(aParentContext),
mRuleWalker(aRuleWalker)
: ElementRuleProcessorData(aPresContext, aContent, aRuleWalker),
mMedium(aMedium)
{
}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mContent;
nsIStyleContext* mParentContext;
nsRuleWalker* mRuleWalker;
};
static PRBool
@ -866,8 +864,7 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData)
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
RulesMatchingData* data = (RulesMatchingData*)aData;
processor->RulesMatching(data->mPresContext, data->mMedium, data->mContent,
data->mParentContext, data->mRuleWalker);
processor->RulesMatching(data, data->mMedium);
return PR_TRUE;
}
@ -921,10 +918,10 @@ StyleSetImpl::AddImportantRules(nsRuleNode* aCurrLevelNode,
}
}
// Enumerate the rules in a way that cares about the order of the rules.
void
StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
void* aData,
nsIContent* aContent)
RuleProcessorData* aData)
{
// Cascading order:
@ -955,8 +952,8 @@ StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData, aContent);
mStyleRuleSupplier->UseDocumentRules(aContent, &useRuleProcessors);
mStyleRuleSupplier->WalkRules(this, aCollectorFunc, aData);
mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors);
}
if (mDocRuleProcessors) {
mDocRuleProcessors->EnumerateForwards(aCollectorFunc, aData);
@ -976,6 +973,40 @@ StyleSetImpl::FileRules(nsISupportsArrayEnumFunc aCollectorFunc,
}
// Enumerate all the rules in a way that doesn't care about the order
// of the rules and break out if the enumeration is halted.
void
StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc,
RuleProcessorData* aData)
{
// Walk the agent rules first.
if (mAgentRuleProcessors)
if (!mAgentRuleProcessors->EnumerateForwards(aFunc, aData))
return;
// Walk the user rules next.
if (mUserRuleProcessors)
if (!mUserRuleProcessors->EnumerateForwards(aFunc, aData))
return;
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
// XXX We ignore whether the enumerator wants to halt here!
mStyleRuleSupplier->WalkRules(this, aFunc, aData);
mStyleRuleSupplier->UseDocumentRules(aData->mContent, &useRuleProcessors);
}
// Now walk the doc rules.
if (mDocRuleProcessors && useRuleProcessors)
if (!mDocRuleProcessors->EnumerateForwards(aFunc, aData))
return;
// Walk the override rules last.
if (mOverrideRuleProcessors)
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}
#ifdef NS_DEBUG
#define NS_ASSERT_REFCOUNT(ptr,cnt,msg) { \
nsrefcnt count = ptr->AddRef(); \
@ -1019,8 +1050,8 @@ nsIStyleContext* StyleSetImpl::ResolveStyleFor(nsIPresContext* aPresContext,
EnsureRuleWalker(aPresContext);
nsCOMPtr<nsIAtom> medium;
aPresContext->GetMedium(getter_AddRefs(medium));
RulesMatchingData data(aPresContext, medium, aContent, aParentContext, mRuleWalker);
FileRules(EnumRulesMatching, &data, aContent);
RulesMatchingData data(aPresContext, medium, aContent, mRuleWalker);
FileRules(EnumRulesMatching, &data);
result = GetContext(aPresContext, aParentContext, nsnull, aForceUnique);
// Now reset the walker back to the root of the tree.
@ -1063,30 +1094,19 @@ nsIStyleContext* StyleSetImpl::ResolveStyleForNonElement(
}
struct PseudoRulesMatchingData {
struct PseudoRulesMatchingData : public PseudoRuleProcessorData {
PseudoRulesMatchingData(nsIPresContext* aPresContext,
nsIAtom* aMedium,
nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
nsICSSPseudoComparator* aComparator,
nsRuleWalker* aWalker)
: mPresContext(aPresContext),
mMedium(aMedium),
mParentContent(aParentContent),
mPseudoTag(aPseudoTag),
mParentContext(aParentContext),
mComparator(aComparator),
mRuleWalker(aWalker)
nsRuleWalker* aRuleWalker)
: PseudoRuleProcessorData(aPresContext, aParentContent, aPseudoTag, aComparator,
aRuleWalker),
mMedium(aMedium)
{
}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mParentContent;
nsIAtom* mPseudoTag;
nsIStyleContext* mParentContext;
nsICSSPseudoComparator* mComparator;
nsRuleWalker* mRuleWalker;
};
static PRBool
@ -1095,9 +1115,7 @@ EnumPseudoRulesMatching(nsISupports* aProcessor, void* aData)
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
PseudoRulesMatchingData* data = (PseudoRulesMatchingData*)aData;
processor->RulesMatching(data->mPresContext, data->mMedium,
data->mParentContent, data->mPseudoTag,
data->mParentContext, data->mComparator, data->mRuleWalker);
processor->RulesMatching(data, data->mMedium);
return PR_TRUE;
}
@ -1129,8 +1147,8 @@ nsIStyleContext* StyleSetImpl::ResolvePseudoStyleFor(nsIPresContext* aPresContex
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aParentContext, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data, aParentContent);
aPseudoTag, aComparator, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
@ -1171,8 +1189,8 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
aPresContext->GetMedium(getter_AddRefs(medium));
EnsureRuleWalker(aPresContext);
PseudoRulesMatchingData data(aPresContext, medium, aParentContent,
aPseudoTag, aParentContext, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data, aParentContent);
aPseudoTag, nsnull, mRuleWalker);
FileRules(EnumPseudoRulesMatching, &data);
if (!mRuleWalker->AtRoot())
result = GetContext(aPresContext, aParentContext, aPseudoTag, aForceUnique);
@ -1325,16 +1343,13 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
return result;
}
struct StatefulData {
struct StatefulData : public StateRuleProcessorData {
StatefulData(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent)
: mPresContext(aPresContext),
: StateRuleProcessorData(aPresContext, aContent),
mMedium(aMedium),
mContent(aContent),
mStateful(PR_FALSE)
{}
nsIPresContext* mPresContext;
nsIAtom* mMedium;
nsIContent* mContent;
PRBool mStateful;
};
@ -1342,8 +1357,7 @@ static PRBool SheetHasStatefulStyle(nsISupports* aProcessor, void *aData)
{
nsIStyleRuleProcessor* processor = (nsIStyleRuleProcessor*)aProcessor;
StatefulData* data = (StatefulData*)aData;
if (NS_OK == processor->HasStateDependentStyle(data->mPresContext, data->mMedium,
data->mContent)) {
if (NS_OK == processor->HasStateDependentStyle(data, data->mMedium)) {
data->mStateful = PR_TRUE;
return PR_FALSE; // stop iteration
}
@ -1365,7 +1379,7 @@ StyleSetImpl::HasStateDependentStyle(nsIPresContext* aPresContext,
nsIAtom* medium = nsnull;
aPresContext->GetMedium(&medium);
StatefulData data(aPresContext, medium, aContent);
WalkRuleProcessors(SheetHasStatefulStyle, &data, aContent);
WalkRuleProcessors(SheetHasStatefulStyle, &data);
NS_IF_RELEASE(medium);
return ((data.mStateful) ? NS_OK : NS_COMFALSE);
}
@ -1739,8 +1753,9 @@ EnumAffectsStyle(nsISupports *aElement, void *aData)
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
AttributeContentPair *pair = (AttributeContentPair *)aData;
PRBool affects;
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
affects)) || affects)
nsresult res =
sheet->AttributeAffectsStyle(pair->attribute, pair->content, affects);
if (NS_FAILED(res) || affects)
return PR_FALSE; // stop checking
return PR_TRUE;
@ -1965,31 +1980,3 @@ void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
// - none
}
#endif
void
StyleSetImpl::WalkRuleProcessors(nsISupportsArrayEnumFunc aFunc, void* aData,
nsIContent* aContent)
{
// Walk the agent rules first.
if (mAgentRuleProcessors)
mAgentRuleProcessors->EnumerateForwards(aFunc, aData);
// Walk the user rules next.
if (mUserRuleProcessors)
mUserRuleProcessors->EnumerateForwards(aFunc, aData);
PRBool useRuleProcessors = PR_TRUE;
if (mStyleRuleSupplier) {
// We can supply additional document-level sheets that should be walked.
mStyleRuleSupplier->WalkRules(this, aFunc, aData, aContent);
mStyleRuleSupplier->UseDocumentRules(aContent, &useRuleProcessors);
}
// Now walk the doc rules.
if (mDocRuleProcessors && useRuleProcessors)
mDocRuleProcessors->EnumerateForwards(aFunc, aData);
// Walk the override rules last.
if (mOverrideRuleProcessors)
mOverrideRuleProcessors->EnumerateForwards(aFunc, aData);
}