diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index e12a8375eed9..1a11c81a803e 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -143,15 +143,16 @@ nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType) } nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType, - const PRUnichar* aString) + nsIAtom* aAtom) : mType(aType), mNext(nsnull) { NS_ASSERTION(nsCSSPseudoClasses::HasStringArg(aType), "unexpected pseudo-class"); - NS_ASSERTION(aString, "string expected"); + NS_ASSERTION(aAtom, "atom expected"); MOZ_COUNT_CTOR(nsPseudoClassList); - u.mString = NS_strdup(aString); + NS_ADDREF(aAtom); + u.mAtom = aAtom; } nsPseudoClassList::nsPseudoClassList(nsCSSPseudoClasses::Type aType, @@ -187,7 +188,7 @@ nsPseudoClassList::Clone(bool aDeep) const if (!u.mMemory) { result = new nsPseudoClassList(mType); } else if (nsCSSPseudoClasses::HasStringArg(mType)) { - result = new nsPseudoClassList(mType, u.mString); + result = new nsPseudoClassList(mType, u.mAtom); } else if (nsCSSPseudoClasses::HasNthPairArg(mType)) { result = new nsPseudoClassList(mType, u.mNumbers); } else { @@ -210,7 +211,11 @@ nsPseudoClassList::~nsPseudoClassList(void) if (nsCSSPseudoClasses::HasSelectorListArg(mType)) { delete u.mSelectors; } else if (u.mMemory) { - NS_Free(u.mMemory); + if (nsCSSPseudoClasses::HasStringArg(mType)) { + NS_RELEASE(u.mAtom); + } else { + NS_Free(u.mMemory); + } } NS_CSS_DELETE_LIST_MEMBER(nsPseudoClassList, this, mNext); } @@ -414,9 +419,9 @@ void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType) } void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType, - const PRUnichar* aString) + nsIAtom* aAtom) { - AddPseudoClassInternal(new nsPseudoClassList(aType, aString)); + AddPseudoClassInternal(new nsPseudoClassList(aType, aAtom)); } void nsCSSSelector::AddPseudoClass(nsCSSPseudoClasses::Type aType, @@ -772,7 +777,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations aString.Append(PRUnichar('(')); if (nsCSSPseudoClasses::HasStringArg(list->mType)) { nsStyleUtil::AppendEscapedCSSIdent( - nsDependentString(list->u.mString), aString); + nsDependentAtomString(list->u.mAtom), aString); } else if (nsCSSPseudoClasses::HasNthPairArg(list->mType)) { PRInt32 a = list->u.mNumbers[0], b = list->u.mNumbers[1]; diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index ab9ca5b4609c..8355c156e951 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -80,7 +80,7 @@ private: struct nsPseudoClassList { public: nsPseudoClassList(nsCSSPseudoClasses::Type aType); - nsPseudoClassList(nsCSSPseudoClasses::Type aType, const PRUnichar *aString); + nsPseudoClassList(nsCSSPseudoClasses::Type aType, nsIAtom *aAtom); nsPseudoClassList(nsCSSPseudoClasses::Type aType, const PRInt32 *aIntPair); nsPseudoClassList(nsCSSPseudoClasses::Type aType, nsCSSSelectorList *aSelectorList /* takes ownership */); @@ -99,8 +99,8 @@ public: // (if nsCSSPseudoClasses::HasNthPairArg(mType)) // d. a selector list, which means mSelectors is non-null // (if nsCSSPseudoClasses::HasSelectorListArg(mType)) - void* mMemory; // mString and mNumbers use NS_Alloc/NS_Free - PRUnichar* mString; + void* mMemory; // mNumbers uses NS_Alloc/NS_Free + nsIAtom* mAtom; // STRONG REF PRInt32* mNumbers; nsCSSSelectorList* mSelectors; } u; @@ -165,7 +165,7 @@ public: void AddID(const nsString& aID); void AddClass(const nsString& aClass); void AddPseudoClass(nsCSSPseudoClasses::Type aType); - void AddPseudoClass(nsCSSPseudoClasses::Type aType, const PRUnichar* aString); + void AddPseudoClass(nsCSSPseudoClasses::Type aType, nsIAtom* aAtom); void AddPseudoClass(nsCSSPseudoClasses::Type aType, const PRInt32* aIntPair); // takes ownership of aSelectorList void AddPseudoClass(nsCSSPseudoClasses::Type aType, diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index ae1a474b2c51..9b694e0a0931 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -3371,16 +3371,16 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector, return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } + nsCOMPtr atom = do_GetAtom(mToken.mIdent); // -moz-locale-dir can only have values of 'ltr' or 'rtl'. if (aType == nsCSSPseudoClasses::ePseudoClass_mozLocaleDir) { - if (!mToken.mIdent.EqualsLiteral("ltr") && - !mToken.mIdent.EqualsLiteral("rtl")) { + if (atom != nsGkAtoms::ltr && atom != nsGkAtoms::rtl) { return eSelectorParsingStatus_Error; // our caller calls SkipUntil(')') } } // Add the pseudo with the language parameter - aSelector.AddPseudoClass(aType, mToken.mIdent.get()); + aSelector.AddPseudoClass(aType, atom); // close the parenthesis if (!ExpectSymbol(')', true)) { diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 57bc75a7ca4e..a684cecaf8d7 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1686,7 +1686,7 @@ static bool SelectorMatches(const Element* aElement, case nsCSSPseudoClasses::ePseudoClass_mozEmptyExceptChildrenWithLocalname: { - NS_ASSERTION(pseudoClass->u.mString, "Must have string!"); + NS_ASSERTION(pseudoClass->u.mAtom, "Must have atom!"); const nsIContent *child = nsnull; PRInt32 index = -1; @@ -1702,7 +1702,7 @@ static bool SelectorMatches(const Element* aElement, } while (child && (!IsSignificantChild(child, true, false) || (child->GetNameSpaceID() == aElement->GetNameSpaceID() && - child->Tag()->Equals(nsDependentString(pseudoClass->u.mString))))); + child->Tag() == pseudoClass->u.mAtom))); if (child != nsnull) { return false; } @@ -1711,10 +1711,7 @@ static bool SelectorMatches(const Element* aElement, case nsCSSPseudoClasses::ePseudoClass_lang: { - NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter"); - if (!pseudoClass->u.mString || !*pseudoClass->u.mString) { - return false; - } + NS_ASSERTION(pseudoClass->u.mAtom, "Must have atom!"); // We have to determine the language of the current element. Since // this is currently no property and since the language is inherited @@ -1722,9 +1719,10 @@ static bool SelectorMatches(const Element* aElement, // nodes. The language itself is encoded in the LANG attribute. nsAutoString language; aElement->GetLang(language); + nsDependentAtomString langString(pseudoClass->u.mAtom); if (!language.IsEmpty()) { if (!nsStyleUtil::DashMatchCompare(language, - nsDependentString(pseudoClass->u.mString), + langString, nsASCIICaseInsensitiveStringComparator())) { return false; } @@ -1740,7 +1738,6 @@ static bool SelectorMatches(const Element* aElement, // language codes. doc->GetContentLanguage(language); - nsDependentString langString(pseudoClass->u.mString); language.StripWhitespace(); PRInt32 begin = 0; PRInt32 len = language.Length(); @@ -1933,8 +1930,7 @@ static bool SelectorMatches(const Element* aElement, case nsCSSPseudoClasses::ePseudoClass_mozSystemMetric: { - nsCOMPtr metric = do_GetAtom(pseudoClass->u.mString); - if (!nsCSSRuleProcessor::HasSystemMetric(metric)) { + if (!nsCSSRuleProcessor::HasSystemMetric(pseudoClass->u.mAtom)) { return false; } } @@ -1945,12 +1941,11 @@ static bool SelectorMatches(const Element* aElement, bool docIsRTL = aTreeMatchContext.mDocStates.HasState(NS_DOCUMENT_STATE_RTL_LOCALE); - nsDependentString dirString(pseudoClass->u.mString); - NS_ASSERTION(dirString.EqualsLiteral("ltr") || - dirString.EqualsLiteral("rtl"), + NS_ASSERTION(pseudoClass->u.mAtom == nsGkAtoms::ltr || + pseudoClass->u.mAtom == nsGkAtoms::rtl, "invalid value for -moz-locale-dir"); - if (dirString.EqualsLiteral("rtl") != docIsRTL) { + if ((pseudoClass->u.mAtom == nsGkAtoms::rtl) != docIsRTL) { return false; } }