mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Speed up matching class rules by caching the class attribute, rather than looking it up for each rule. Remove HasClass now that it's no longer needed. Bug 310236, r+sr=dbaron.
This commit is contained in:
parent
d1b0778bd9
commit
48082c9284
@ -47,10 +47,10 @@ class nsRuleWalker;
|
||||
class nsAttrValue;
|
||||
|
||||
// IID for the nsIStyledContent class
|
||||
// c59f05f5-6e39-4e98-a1ea-6c555cb7813c
|
||||
// b3edce42-2a58-4b05-a679-eae3ddbd1edd
|
||||
#define NS_ISTYLEDCONTENT_IID \
|
||||
{ 0xc59f05f5, 0x6e39, 0x4e98, \
|
||||
{ 0xa1, 0xea, 0x6c, 0x55, 0x5c, 0xb7, 0x81, 0x3c } }
|
||||
{ 0xb3edc342, 0x2a58, 0x4b05, \
|
||||
{ 0xa6, 0x79, 0xea, 0xe3, 0xdd, 0xbd, 0x1e, 0xdd } }
|
||||
|
||||
// Abstract interface for all styled content (that supports ID, CLASS, STYLE, and
|
||||
// the ability to specify style hints on an attribute change).
|
||||
@ -69,7 +69,6 @@ public:
|
||||
// incorrect, then new methods need to be added here.
|
||||
virtual nsIAtom* GetID() const = 0;
|
||||
virtual const nsAttrValue* GetClasses() const = 0;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const = 0;
|
||||
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
|
||||
|
||||
|
@ -673,6 +673,48 @@ nsAttrValue::Equals(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const
|
||||
return aValue->Equals(val);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAttrValue::Contains(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
switch (BaseType()) {
|
||||
case eAtomBase:
|
||||
{
|
||||
nsIAtom* atom = GetAtomValue();
|
||||
|
||||
if (aCaseSensitive == eCaseMatters) {
|
||||
return aValue == atom;
|
||||
}
|
||||
|
||||
const char *val1, *val2;
|
||||
aValue->GetUTF8String(&val1);
|
||||
atom->GetUTF8String(&val2);
|
||||
|
||||
return nsCRT::strcasecmp(val1, val2) == 0;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (Type() == eAtomArray) {
|
||||
nsCOMArray<nsIAtom>* array = GetAtomArrayValue();
|
||||
if (aCaseSensitive == eCaseMatters) {
|
||||
return array->IndexOf(aValue) >= 0;
|
||||
}
|
||||
|
||||
const char *val1, *val2;
|
||||
aValue->GetUTF8String(&val1);
|
||||
|
||||
for (PRInt32 i = 0, count = array->Count(); i < count; ++i) {
|
||||
array->ObjectAt(i)->GetUTF8String(&val2);
|
||||
if (nsCRT::strcasecmp(val1, val2) == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::ParseAtom(const nsAString& aValue)
|
||||
{
|
||||
|
@ -159,6 +159,12 @@ public:
|
||||
PRBool Equals(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const;
|
||||
PRBool Equals(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const;
|
||||
|
||||
/**
|
||||
* Returns true if this AttrValue is equal to the given atom, or is an
|
||||
* array which contains the given atom.
|
||||
*/
|
||||
PRBool Contains(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const;
|
||||
|
||||
void ParseAtom(const nsAString& aValue);
|
||||
void ParseAtomArray(const nsAString& aValue);
|
||||
void ParseStringOrAtom(const nsAString& aValue);
|
||||
|
@ -2295,12 +2295,6 @@ nsGenericElement::GetClasses() const
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsGenericElement::HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||
{
|
||||
|
@ -449,7 +449,6 @@ public:
|
||||
// nsIStyledContent interface methods
|
||||
virtual nsIAtom* GetID() const;
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||
virtual nsICSSStyleRule* GetInlineStyleRule();
|
||||
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
|
||||
|
@ -1915,44 +1915,6 @@ nsGenericHTMLElement::GetClassAttributeName() const
|
||||
return nsHTMLAtoms::kClass;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsGenericHTMLElement::HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const
|
||||
{
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(nsHTMLAtoms::kClass);
|
||||
if (val) {
|
||||
if (val->Type() == nsAttrValue::eAtom) {
|
||||
if (aCaseSensitive) {
|
||||
return aClass == val->GetAtomValue();
|
||||
}
|
||||
|
||||
const char *class1, *class2;
|
||||
aClass->GetUTF8String(&class1);
|
||||
val->GetAtomValue()->GetUTF8String(&class2);
|
||||
|
||||
return nsCRT::strcasecmp(class1, class2) == 0;
|
||||
}
|
||||
if (val->Type() == nsAttrValue::eAtomArray) {
|
||||
nsCOMArray<nsIAtom>* array = val->GetAtomArrayValue();
|
||||
if (aCaseSensitive) {
|
||||
return array->IndexOf(aClass) >= 0;
|
||||
}
|
||||
|
||||
const char *class1, *class2;
|
||||
aClass->GetUTF8String(&class1);
|
||||
|
||||
PRInt32 i, count = array->Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
array->ObjectAt(i)->GetUTF8String(&class2);
|
||||
if (nsCRT::strcasecmp(class1, class2) == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||
{
|
||||
|
@ -251,7 +251,6 @@ public:
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
virtual nsIAtom *GetClassAttributeName() const;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||
virtual nsICSSStyleRule* GetInlineStyleRule();
|
||||
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
|
||||
|
@ -92,22 +92,6 @@ nsSVGStylableElement::GetClasses() const
|
||||
return mClassName->GetAttrValue();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsSVGStylableElement::HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const
|
||||
{
|
||||
NS_ASSERTION(aCaseSensitive, "svg should always be casesensitive");
|
||||
|
||||
const nsAttrValue* val = mClassName->GetAttrValue();
|
||||
if (val->Type() == nsAttrValue::eAtom) {
|
||||
return aClass == val->GetAtomValue();
|
||||
}
|
||||
if (val->Type() == nsAttrValue::eAtomArray) {
|
||||
return val->GetAtomArrayValue()->IndexOf(aClass) >= 0;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGStylable methods
|
||||
|
||||
|
@ -61,7 +61,6 @@ public:
|
||||
|
||||
// nsIStyledContent
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
|
||||
|
||||
protected:
|
||||
nsRefPtr<nsSVGClassValue> mClassName;
|
||||
|
@ -44,10 +44,10 @@
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
// ded21e95-2484-4735-a29a-af778335ecfe
|
||||
// 37eff125-80a9-49ce-a0f7-1617a21ce745
|
||||
#define NS_IXMLCONTENT_IID \
|
||||
{ 0xded21e95, 0x2484, 0x4735, \
|
||||
{ 0xa2, 0x9a, 0xaf, 0x77, 0x83, 0x35, 0xec, 0xfe } }
|
||||
{ 0x37eff125, 0x80a9, 0x49ce, \
|
||||
{ 0xa0, 0xf7, 0x16, 0x17, 0xa2, 0x1c, 0xe7, 0x45 } }
|
||||
|
||||
/**
|
||||
* XML content extensions to nsIContent
|
||||
|
@ -810,22 +810,6 @@ nsXTFStyledElementWrapper::GetClasses() const
|
||||
return val;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXTFStyledElementWrapper::HasClass(nsIAtom* aClass, PRBool /*aCaseSensitive*/) const
|
||||
{
|
||||
const nsAttrValue* val = GetClasses();
|
||||
if (val) {
|
||||
if (val->Type() == nsAttrValue::eAtom) {
|
||||
return aClass == val->GetAtomValue();
|
||||
}
|
||||
|
||||
if (val->Type() == nsAttrValue::eAtomArray) {
|
||||
return val->GetAtomArrayValue()->IndexOf(aClass) >= 0;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXTFStyledElementWrapper::SetClassAttributeName(nsIAtom* aName)
|
||||
{
|
||||
|
@ -159,7 +159,6 @@ public:
|
||||
// for nsIStyledContent
|
||||
virtual nsIAtom *GetClassAttributeName() const;
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
|
||||
|
||||
nsresult SetClassAttributeName(nsIAtom* aName);
|
||||
protected:
|
||||
|
@ -2282,22 +2282,6 @@ nsXULElement::GetClasses() const
|
||||
return FindLocalOrProtoAttr(kNameSpaceID_None, nsXULAtoms::clazz);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsXULElement::HasClass(nsIAtom* aClass, PRBool /*aCaseSensitive*/) const
|
||||
{
|
||||
const nsAttrValue* val = FindLocalOrProtoAttr(kNameSpaceID_None, nsXULAtoms::clazz);
|
||||
if (val) {
|
||||
if (val->Type() == nsAttrValue::eAtom) {
|
||||
return aClass == val->GetAtomValue();
|
||||
}
|
||||
if (val->Type() == nsAttrValue::eAtomArray) {
|
||||
return val->GetAtomArrayValue()->IndexOf(aClass) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
||||
{
|
||||
|
@ -531,7 +531,6 @@ public:
|
||||
// nsIStyledContent
|
||||
virtual nsIAtom* GetID() const;
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
NS_IMETHOD_(PRBool) HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
|
||||
|
||||
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
|
||||
virtual nsICSSStyleRule* GetInlineStyleRule();
|
||||
|
@ -2663,6 +2663,7 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext,
|
||||
mPreviousSiblingData = nsnull;
|
||||
mParentData = nsnull;
|
||||
mLanguage = nsnull;
|
||||
mClasses = nsnull;
|
||||
|
||||
// get the compat. mode (unless it is provided)
|
||||
if(!aCompat) {
|
||||
@ -2687,6 +2688,7 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext,
|
||||
if (aContent->IsContentOfType(nsIContent::eELEMENT)) {
|
||||
mStyledContent = NS_STATIC_CAST(nsIStyledContent*, aContent);
|
||||
mContentID = mStyledContent->GetID();
|
||||
mClasses = mStyledContent->GetClasses();
|
||||
}
|
||||
|
||||
NS_ASSERTION(nsCOMPtr<nsIStyledContent>(do_QueryInterface(aContent)) == mStyledContent,
|
||||
@ -3291,9 +3293,8 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
||||
do {
|
||||
const char* id2Str;
|
||||
IDList->mAtom->GetUTF8String(&id2Str);
|
||||
nsDependentCString id2(id2Str);
|
||||
if (localTrue !=
|
||||
id1.Equals(id2, nsCaseInsensitiveCStringComparator())) {
|
||||
id1.Equals(id2Str, nsCaseInsensitiveCStringComparator())) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
@ -3305,8 +3306,9 @@ static PRBool SelectorMatches(RuleProcessorData &data,
|
||||
if (result &&
|
||||
(!aAttribute || aAttribute != data.mStyledContent->GetClassAttributeName())) {
|
||||
nsAtomList* classList = aSelector->mClassList;
|
||||
const nsAttrValue *elementClasses = data.mClasses;
|
||||
while (nsnull != classList) {
|
||||
if (localTrue == (!data.mStyledContent->HasClass(classList->mAtom, isCaseSensitive))) {
|
||||
if (localTrue == (!(elementClasses && elementClasses->Contains(classList->mAtom, isCaseSensitive ? eCaseMatters : eIgnoreCase)))) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
@ -3448,15 +3450,10 @@ nsCSSRuleProcessor::RulesMatching(ElementRuleProcessorData *aData)
|
||||
RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext);
|
||||
|
||||
if (cascade) {
|
||||
nsIStyledContent* styledContent = aData->mStyledContent;
|
||||
const nsAttrValue* classes = nsnull;
|
||||
if (styledContent)
|
||||
classes = styledContent->GetClasses();
|
||||
|
||||
cascade->mRuleHash.EnumerateAllRules(aData->mNameSpaceID,
|
||||
aData->mContentTag,
|
||||
aData->mContentID,
|
||||
classes,
|
||||
aData->mClasses,
|
||||
ContentEnumFunc,
|
||||
aData);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ class nsISupportsArray;
|
||||
class nsIAtom;
|
||||
class nsICSSPseudoComparator;
|
||||
class nsRuleWalker;
|
||||
class nsAttrValue;
|
||||
|
||||
// The implementation of the constructor and destructor are currently in
|
||||
// nsCSSStyleSheet.cpp.
|
||||
@ -93,6 +94,7 @@ struct RuleProcessorData {
|
||||
nsLinkState mLinkState; // if a link, this is the state, otherwise unknown
|
||||
PRInt32 mEventState; // if content, eventStateMgr->GetContentState()
|
||||
PRInt32 mNameSpaceID; // if content, content->GetNameSapce()
|
||||
const nsAttrValue* mClasses; // if styled content, styledcontent->GetClasses()
|
||||
RuleProcessorData* mPreviousSiblingData;
|
||||
RuleProcessorData* mParentData;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user