Bug 525952 part 3. Introduce an enum for pseudo-clases. r=dbaron

This commit is contained in:
Boris Zbarsky 2009-12-11 02:37:41 -05:00
parent b61f378670
commit 9d4c216817
5 changed files with 75 additions and 27 deletions

View File

@ -365,10 +365,12 @@ protected:
PRBool aIsNegated);
nsSelectorParsingStatus ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo);
nsIAtom* aPseudo,
nsCSSPseudoClasses::Type aType);
nsSelectorParsingStatus ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo);
nsIAtom* aPseudo,
nsCSSPseudoClasses::Type aType);
nsSelectorParsingStatus ParseNegatedSimpleSelector(PRInt32& aDataMask,
nsCSSSelector& aSelector);
@ -3068,7 +3070,10 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
PRBool isAnonBox = isTreePseudo ||
(pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox &&
mUnsafeRulesEnabled);
PRBool isPseudoClass = nsCSSPseudoClasses::IsPseudoClass(pseudo);
nsCSSPseudoClasses::Type pseudoClassType =
nsCSSPseudoClasses::GetPseudoType(pseudo);
PRBool isPseudoClass =
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass);
NS_ASSERTION(!isPseudoClass ||
pseudoElementType == nsCSSPseudoElements::ePseudo_NotPseudoElement,
@ -3125,20 +3130,20 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
aDataMask |= SEL_MASK_PCLASS;
if (nsCSSPseudoClasses::HasStringArg(pseudo)) {
nsSelectorParsingStatus parsingStatus =
ParsePseudoClassWithIdentArg(aSelector, pseudo);
ParsePseudoClassWithIdentArg(aSelector, pseudo, pseudoClassType);
if (eSelectorParsingStatus_Continue != parsingStatus) {
return parsingStatus;
}
}
else if (nsCSSPseudoClasses::HasNthPairArg(pseudo)) {
nsSelectorParsingStatus parsingStatus =
ParsePseudoClassWithNthPairArg(aSelector, pseudo);
ParsePseudoClassWithNthPairArg(aSelector, pseudo, pseudoClassType);
if (eSelectorParsingStatus_Continue != parsingStatus) {
return parsingStatus;
}
}
else {
aSelector.AddPseudoClass(pseudo);
aSelector.AddPseudoClass(pseudo, pseudoClassType);
}
}
else if (isPseudoElement || isAnonBox) {
@ -3291,7 +3296,8 @@ CSSParserImpl::ParseNegatedSimpleSelector(PRInt32& aDataMask,
//
CSSParserImpl::nsSelectorParsingStatus
CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo)
nsIAtom* aPseudo,
nsCSSPseudoClasses::Type aType)
{
// Check if we have the first parenthesis
if (!ExpectSymbol('(', PR_FALSE)) {
@ -3320,7 +3326,7 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
}
// Add the pseudo with the language parameter
aSelector.AddPseudoClass(aPseudo, mToken.mIdent.get());
aSelector.AddPseudoClass(aPseudo, aType, mToken.mIdent.get());
// close the parenthesis
if (!ExpectSymbol(')', PR_TRUE)) {
@ -3334,7 +3340,8 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector,
CSSParserImpl::nsSelectorParsingStatus
CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
nsIAtom* aPseudo)
nsIAtom* aPseudo,
nsCSSPseudoClasses::Type aType)
{
PRInt32 numbers[2] = { 0, 0 };
PRBool lookForB = PR_TRUE;
@ -3457,7 +3464,7 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector,
// XXX Call SkipUntil to the next ")"?
return eSelectorParsingStatus_Error;
}
aSelector.AddPseudoClass(aPseudo, numbers);
aSelector.AddPseudoClass(aPseudo, aType, numbers);
return eSelectorParsingStatus_Continue;
}
@ -3906,7 +3913,8 @@ CSSParserImpl::ParseTreePseudoElement(nsPseudoClassList **aPseudoElementArgs)
}
if (eCSSToken_Ident == mToken.mType) {
nsCOMPtr<nsIAtom> pseudo = do_GetAtom(mToken.mIdent);
fakeSelector.AddPseudoClass(pseudo);
fakeSelector.AddPseudoClass(pseudo,
nsCSSPseudoClasses::ePseudoClass_NotPseudoClass);
}
else if (!mToken.IsSymbol(',')) {
SkipUntil(')');

View File

@ -85,3 +85,15 @@ nsCSSPseudoClasses::HasNthPairArg(nsIAtom* aAtom)
aAtom == nsCSSPseudoClasses::nthOfType ||
aAtom == nsCSSPseudoClasses::nthLastOfType;
}
nsCSSPseudoClasses::Type
nsCSSPseudoClasses::GetPseudoType(nsIAtom* aAtom)
{
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(CSSPseudoClasses_info); ++i) {
if (*CSSPseudoClasses_info[i].mAtom == aAtom) {
return Type(i);
}
}
return nsCSSPseudoClasses::ePseudoClass_NotPseudoClass;
}

View File

@ -59,6 +59,17 @@ public:
#define CSS_PSEUDO_CLASS(_name, _value) static nsICSSPseudoClass* _name;
#include "nsCSSPseudoClassList.h"
#undef CSS_PSEUDO_CLASS
enum Type {
#define CSS_PSEUDO_CLASS(_name, _value) \
ePseudoClass_##_name,
#include "nsCSSPseudoClassList.h"
#undef CSS_PSEUDO_CLASS
ePseudoClass_Count,
ePseudoClass_NotPseudoClass
};
static Type GetPseudoType(nsIAtom* aAtom);
};
#endif /* nsCSSPseudoClasses_h___ */

View File

@ -136,8 +136,10 @@ nsAtomList::~nsAtomList(void)
NS_CSS_DELETE_LIST_MEMBER(nsAtomList, this, mNext);
}
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom)
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom,
nsCSSPseudoClasses::Type aType)
: mAtom(aAtom),
mType(aType),
mNext(nsnull)
{
NS_ASSERTION(!nsCSSPseudoClasses::HasStringArg(aAtom) &&
@ -147,8 +149,11 @@ nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom)
u.mMemory = nsnull;
}
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom, const PRUnichar* aString)
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom,
nsCSSPseudoClasses::Type aType,
const PRUnichar* aString)
: mAtom(aAtom),
mType(aType),
mNext(nsnull)
{
NS_ASSERTION(nsCSSPseudoClasses::HasStringArg(aAtom),
@ -158,8 +163,11 @@ nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom, const PRUnichar* aString)
u.mString = NS_strdup(aString);
}
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom, const PRInt32* aIntPair)
nsPseudoClassList::nsPseudoClassList(nsIAtom* aAtom,
nsCSSPseudoClasses::Type aType,
const PRInt32* aIntPair)
: mAtom(aAtom),
mType(aType),
mNext(nsnull)
{
NS_ASSERTION(nsCSSPseudoClasses::HasNthPairArg(aAtom),
@ -175,13 +183,13 @@ nsPseudoClassList::Clone(PRBool aDeep) const
{
nsPseudoClassList *result;
if (!u.mMemory) {
result = new nsPseudoClassList(mAtom);
result = new nsPseudoClassList(mAtom, mType);
} else if (nsCSSPseudoClasses::HasStringArg(mAtom)) {
result = new nsPseudoClassList(mAtom, u.mString);
result = new nsPseudoClassList(mAtom, mType, u.mString);
} else {
NS_ASSERTION(nsCSSPseudoClasses::HasNthPairArg(mAtom),
"unexpected pseudo-class");
result = new nsPseudoClassList(mAtom, u.mNumbers);
result = new nsPseudoClassList(mAtom, mType, u.mNumbers);
}
if (aDeep)
@ -392,21 +400,24 @@ void nsCSSSelector::AddClass(const nsString& aClass)
}
}
void nsCSSSelector::AddPseudoClass(nsIAtom* aPseudoClass)
void nsCSSSelector::AddPseudoClass(nsIAtom* aPseudoClass,
nsCSSPseudoClasses::Type aType)
{
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass));
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass, aType));
}
void nsCSSSelector::AddPseudoClass(nsIAtom* aPseudoClass,
nsCSSPseudoClasses::Type aType,
const PRUnichar* aString)
{
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass, aString));
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass, aType, aString));
}
void nsCSSSelector::AddPseudoClass(nsIAtom* aPseudoClass,
nsCSSPseudoClasses::Type aType,
const PRInt32* aIntPair)
{
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass, aIntPair));
AddPseudoClassInternal(new nsPseudoClassList(aPseudoClass, aType, aIntPair));
}
void nsCSSSelector::AddPseudoClassInternal(nsPseudoClassList *aPseudoClass)

View File

@ -53,6 +53,7 @@
#include "nsCSSValue.h"
#include "nsIAtom.h"
#include "nsCSSPseudoElements.h"
#include "nsCSSPseudoClasses.h"
class nsIAtom;
class nsCSSDeclaration;
@ -79,9 +80,11 @@ private:
struct nsPseudoClassList {
public:
nsPseudoClassList(nsIAtom* aAtom);
nsPseudoClassList(nsIAtom* aAtom, const PRUnichar *aString);
nsPseudoClassList(nsIAtom* aAtom, const PRInt32 *aIntPair);
nsPseudoClassList(nsIAtom* aAtom, nsCSSPseudoClasses::Type aType);
nsPseudoClassList(nsIAtom* aAtom, nsCSSPseudoClasses::Type aType,
const PRUnichar *aString);
nsPseudoClassList(nsIAtom* aAtom, nsCSSPseudoClasses::Type aType,
const PRInt32 *aIntPair);
~nsPseudoClassList(void);
/** Do a deep clone. Should be used only on the first in the linked list. */
@ -100,6 +103,7 @@ public:
PRUnichar* mString;
PRInt32* mNumbers;
} u;
nsCSSPseudoClasses::Type mType;
nsPseudoClassList* mNext;
private:
nsPseudoClassList* Clone(PRBool aDeep) const;
@ -159,9 +163,11 @@ public:
void SetTag(const nsString& aTag);
void AddID(const nsString& aID);
void AddClass(const nsString& aClass);
void AddPseudoClass(nsIAtom* aPseudoClass);
void AddPseudoClass(nsIAtom* aPseudoClass, const PRUnichar* aString);
void AddPseudoClass(nsIAtom* aPseudoClass, const PRInt32* aIntPair);
void AddPseudoClass(nsIAtom* aPseudoClass, nsCSSPseudoClasses::Type aType);
void AddPseudoClass(nsIAtom* aPseudoClass, nsCSSPseudoClasses::Type aType,
const PRUnichar* aString);
void AddPseudoClass(nsIAtom* aPseudoClass, nsCSSPseudoClasses::Type aType,
const PRInt32* aIntPair);
void AddAttribute(PRInt32 aNameSpace, const nsString& aAttr);
void AddAttribute(PRInt32 aNameSpace, const nsString& aAttr, PRUint8 aFunc,
const nsString& aValue, PRBool aCaseSensitive);