From bafa24e23afe448863b8252996dc753de7f08a66 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Thu, 6 Sep 2001 13:14:35 +0000 Subject: [PATCH] Re-fix bug 93977 and fix bug 98358 (lack of underlining on links). The CSS parser parses "foo, bar { decls }" into two separate rules -- one for foo and one for bar. So ParseRule() has to return an array of rules, not just a rule. r=dbaron, sr=jst git-svn-id: svn://10.0.0.236/trunk@102406 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/html/style/public/nsICSSParser.h | 7 +- .../content/html/style/src/nsCSSParser.cpp | 160 +++++++------- mozilla/content/html/style/src/nsCSSRules.cpp | 35 ++- .../html/style/src/nsCSSStyleSheet.cpp | 208 ++++++++++-------- .../content/html/style/src/nsICSSGroupRule.h | 4 +- mozilla/layout/base/nsPresShell.cpp | 35 ++- mozilla/layout/html/base/src/nsPresShell.cpp | 35 ++- mozilla/layout/style/nsCSSParser.cpp | 160 +++++++------- mozilla/layout/style/nsCSSRules.cpp | 35 ++- mozilla/layout/style/nsCSSStyleSheet.cpp | 208 ++++++++++-------- mozilla/layout/style/nsICSSGroupRule.h | 4 +- mozilla/layout/style/nsICSSParser.h | 7 +- 12 files changed, 482 insertions(+), 416 deletions(-) diff --git a/mozilla/content/html/style/public/nsICSSParser.h b/mozilla/content/html/style/public/nsICSSParser.h index 6839164714a..12bea9204a4 100644 --- a/mozilla/content/html/style/public/nsICSSParser.h +++ b/mozilla/content/html/style/public/nsICSSParser.h @@ -31,11 +31,16 @@ class nsIUnicharInputStream; class nsIURI; class nsICSSDeclaration; class nsICSSLoader; +class nsICSSRule; +class nsISupportsArray; #define NS_ICSS_PARSER_IID \ { 0xcc9c0610, 0x968c, 0x11d1, \ {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } +// Rule processing function +typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData); + // Interface to the css parser. class nsICSSParser : public nsISupports { public: @@ -77,7 +82,7 @@ public: NS_IMETHOD ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult) = 0; + nsISupportsArray** aResult) = 0; // Charset management method: // Set the charset before calling any of the Parse emthods if you want the diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index d66334a548e..9d16c208920 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -156,13 +156,14 @@ public: NS_IMETHOD ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult); + nsISupportsArray** aResult); NS_IMETHOD GetCharset(/*out*/nsAWritableString &aCharsetDest) const; // sets the out-param to the current charset, as set by SetCharset NS_IMETHOD SetCharset(/*in*/ const nsAReadableString &aCharsetSrc); // NOTE: SetCharset expects the charset to be the preferred charset // and it just records the string exactly as passed in (no alias resolution) + void AppendRule(nsICSSRule* aRule); protected: nsresult InitScanner(nsIUnicharInputStream* aInput, nsIURI* aURI); @@ -182,20 +183,20 @@ protected: PRBool PushGroup(nsICSSGroupRule* aRule); void PopGroup(void); - void AppendRule(nsICSSRule* aRule); - PRBool ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult = nsnull); - PRBool ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult = nsnull); - PRBool ParseCharsetRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + PRBool ParseRuleSet(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseAtRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseCharsetRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseImportRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool GatherMedia(PRInt32& aErrorCode, nsString& aMedia, nsISupportsArray* aMediaAtoms); - PRBool ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, nsIStyleRule** aResult); - PRBool ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + PRBool ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseMediaRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseNameSpaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPrefix, - const nsString& aURLSpec, nsIStyleRule** aResult); - PRBool ParseFontFaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParsePageRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + const nsString& aURLSpec, RuleAppendFunc aAppendFunc, + void* aProcessData); + PRBool ParseFontFaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParsePageRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); void ParseIDSelector(PRInt32& aDataMask, nsCSSSelector& aSelector, PRInt32& aParsingStatus, PRInt32& aErrorCode); @@ -330,6 +331,18 @@ protected: PRBool IsParsingCompoundProperty(void) {return mParsingCompoundProperty;}; }; +PR_STATIC_CALLBACK(void) AppendRuleToArray(nsICSSRule* aRule, void* aArray) +{ + nsISupportsArray* arr = (nsISupportsArray*) aArray; + arr->AppendElement(aRule); +} + +PR_STATIC_CALLBACK(void) AppendRuleToSheet(nsICSSRule* aRule, void* aParser) +{ + CSSParserImpl* parser = (CSSParserImpl*) aParser; + parser->AppendRule(aRule); +} + NS_HTML nsresult NS_NewCSSParser(nsICSSParser** aInstancePtrResult) { @@ -566,11 +579,11 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, continue; // legal here only } if (eCSSToken_AtKeyword == tk->mType) { - ParseAtRule(errorCode); + ParseAtRule(errorCode, AppendRuleToSheet, this); continue; } UngetToken(); - if (ParseRuleSet(errorCode)) { + if (ParseRuleSet(errorCode, AppendRuleToSheet, this)) { mSection = eCSSSection_General; } } @@ -684,42 +697,49 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAReadableString& aBuffer, NS_IMETHODIMP CSSParserImpl::ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult) + nsISupportsArray** aResult) { NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - + nsString* str = new nsString(aRule); if (nsnull == str) { return NS_ERROR_OUT_OF_MEMORY; } nsCOMPtr input = nsnull; nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); - if (NS_OK != rv) { + if (NS_FAILED(rv)) { delete str; return rv; } rv = InitScanner(input, aBaseURL); - if (! NS_SUCCEEDED(rv)) { + if (NS_FAILED(rv)) { return rv; } - mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules. Maybe pass in the previous rule to this method? + rv = NS_NewISupportsArray(aResult); + if (NS_FAILED(rv)) { + return rv; + } + + mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules. PRInt32 errorCode = NS_OK; nsCSSToken* tk = &mToken; // Get first non-whitespace token if (!GetToken(errorCode, PR_TRUE)) { + REPORT_UNEXPECTED( + NS_LITERAL_STRING("Whitespace-only string given to be parsed as rule.")); OUTPUT_ERROR(); } else if (eCSSToken_AtKeyword == tk->mType) { - ParseAtRule(errorCode, aResult); + ParseAtRule(errorCode, AppendRuleToArray, *aResult); } else { UngetToken(); - ParseRuleSet(errorCode, aResult); + ParseRuleSet(errorCode, AppendRuleToArray, *aResult); } + OUTPUT_ERROR(); ReleaseScanner(); return NS_OK; } @@ -837,43 +857,44 @@ PRBool CSSParserImpl::SkipAtRule(PRInt32& aErrorCode) return PR_TRUE; } -PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { if ((mSection <= eCSSSection_Charset) && (mToken.mIdent.EqualsIgnoreCase("charset"))) { - if (ParseCharsetRule(aErrorCode, aResult)) { + if (ParseCharsetRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_Import; // only one charset allowed return PR_TRUE; } } if ((mSection <= eCSSSection_Import) && mToken.mIdent.EqualsIgnoreCase("import")) { - if (ParseImportRule(aErrorCode, aResult)) { + if (ParseImportRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_Import; return PR_TRUE; } } if ((mSection <= eCSSSection_NameSpace) && mToken.mIdent.EqualsIgnoreCase("namespace")) { - if (ParseNameSpaceRule(aErrorCode, aResult)) { + if (ParseNameSpaceRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_NameSpace; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("media")) { - if (ParseMediaRule(aErrorCode, aResult)) { + if (ParseMediaRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("font-face")) { - if (ParseFontFaceRule(aErrorCode, aResult)) { + if (ParseFontFaceRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("page")) { - if (ParsePageRule(aErrorCode, aResult)) { + if (ParsePageRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } @@ -886,7 +907,8 @@ PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult) return SkipAtRule(aErrorCode); } -PRBool CSSParserImpl::ParseCharsetRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseCharsetRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { // XXX not yet implemented return PR_FALSE; @@ -961,7 +983,7 @@ PRBool CSSParserImpl::GatherMedia(PRInt32& aErrorCode, nsString& aMedia, } // Parse a CSS2 import rule: "@import STRING | URL [medium [, mdeium]]" -PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { if (!GetToken(aErrorCode, PR_TRUE)) { REPORT_UNEXPECTED_EOF(); @@ -974,7 +996,7 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul url = mToken.mIdent; if (GatherMedia(aErrorCode, media, nsnull)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessImport(aErrorCode, url, media, aResult); + ProcessImport(aErrorCode, url, media, aAppendFunc, aData); return PR_TRUE; } } @@ -988,7 +1010,7 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (GatherMedia(aErrorCode, media, nsnull)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessImport(aErrorCode, url, media, aResult); + ProcessImport(aErrorCode, url, media, aAppendFunc, aData); return PR_TRUE; } } @@ -1004,19 +1026,14 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul } -PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, nsIStyleRule** aResult) +PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, RuleAppendFunc aAppendFunc, void* aData) { nsCOMPtr rule; - NS_NewCSSImportRule(getter_AddRefs(rule), aURLSpec, aMedia); - if (rule) { - if (aResult) { // someone wants this rule - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - } + aErrorCode = NS_NewCSSImportRule(getter_AddRefs(rule), aURLSpec, aMedia); + if (NS_FAILED(aErrorCode)) { + return PR_FALSE; } + (*aAppendFunc)(rule, aData); if (mChildLoader) { // XXX probably need a way to encode unicode junk for the part of @@ -1042,7 +1059,8 @@ PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpe } // Parse a CSS2 media rule: "@media medium [, medium] { ... }" -PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { nsAutoString mediaStr; nsCOMPtr media; @@ -1075,22 +1093,15 @@ PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult continue; } UngetToken(); - ParseRuleSet(aErrorCode); + ParseRuleSet(aErrorCode, AppendRuleToSheet, this); } PopGroup(); if (ExpectSymbol(aErrorCode, '}', PR_TRUE)) { - if (aResult) { // someone wants this rule - rule->SetMedia(media); - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - // Append first, so when we do SetMedia() the rule - // knows what its stylesheet is. - AppendRule(rule); - rule->SetMedia(media); - } + // Append first, so when we do SetMedia() the rule + // knows what its stylesheet is. + (*aAppendFunc)(rule, aData); + rule->SetMedia(media); return PR_TRUE; } mSection = holdSection; @@ -1107,7 +1118,9 @@ PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult } // Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;" -PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, + RuleAppendFunc aAppendFunc, + void* aData) { if (!GetToken(aErrorCode, PR_TRUE)) { REPORT_UNEXPECTED_EOF(); @@ -1129,7 +1142,7 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe if (eCSSToken_String == mToken.mType) { url = mToken.mIdent; if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessNameSpace(aErrorCode, prefix, url, aResult); + ProcessNameSpace(aErrorCode, prefix, url, aAppendFunc, aData); return PR_TRUE; } } @@ -1141,7 +1154,7 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe url = mToken.mIdent; if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessNameSpace(aErrorCode, prefix, url, aResult); + ProcessNameSpace(aErrorCode, prefix, url, aAppendFunc, aData); return PR_TRUE; } } @@ -1156,7 +1169,8 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe } PRBool CSSParserImpl::ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPrefix, - const nsString& aURLSpec, nsIStyleRule** aResult) + const nsString& aURLSpec, RuleAppendFunc aAppendFunc, + void* aData) { PRBool result = PR_FALSE; @@ -1169,27 +1183,21 @@ PRBool CSSParserImpl::ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPre NS_NewCSSNameSpaceRule(getter_AddRefs(rule), prefix, aURLSpec); if (rule) { - if (aResult) { // someone wants this rule - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - NS_IF_RELEASE(mNameSpace); - mSheet->GetNameSpace(mNameSpace); - } + (*aAppendFunc)(rule, aData); + NS_IF_RELEASE(mNameSpace); + mSheet->GetNameSpace(mNameSpace); } return result; } -PRBool CSSParserImpl::ParseFontFaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseFontFaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // XXX not yet implemented return PR_FALSE; } -PRBool CSSParserImpl::ParsePageRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParsePageRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // XXX not yet implemented return PR_FALSE; @@ -1313,7 +1321,7 @@ void CSSParserImpl::AppendRule(nsICSSRule* aRule) } } -PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // First get the list of selectors for the rule SelectorList* slist = nsnull; @@ -1361,13 +1369,7 @@ PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult) rule->SetDeclaration(declaration); rule->SetWeight(list->mWeight); // rule->List(); - if (aResult) { // someone wants this rule back; don't append it - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - } + (*aAppendFunc)(rule, aData); NS_RELEASE(rule); } diff --git a/mozilla/content/html/style/src/nsCSSRules.cpp b/mozilla/content/html/style/src/nsCSSRules.cpp index 637cadf6ffd..150b47f4734 100644 --- a/mozilla/content/html/style/src/nsCSSRules.cpp +++ b/mozilla/content/html/style/src/nsCSSRules.cpp @@ -711,7 +711,7 @@ public: NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const; NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const; NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex); - NS_IMETHOD InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule); + NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules); // nsIDOMCSSRule interface NS_DECL_NSIDOMCSSRULE @@ -836,8 +836,7 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const PRUint32 count; mMedia->Count(&count); while (index < count) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); medium->ToString(buffer); fputs(buffer, out); if (index < count) { @@ -852,8 +851,7 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const PRUint32 count; mRules->Count(&count); while (index < count) { - nsCOMPtr rule; - mRules->QueryElementAt(index++, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++)); rule->List(out, aIndent + 1); } } @@ -898,8 +896,7 @@ void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 count; mMedia->Count(&count); while (index < count) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); if(medium && uniqueItems->AddItem(medium)){ medium->SizeOf(aSizeOfHandler, &localSize); aSize += localSize; @@ -915,8 +912,7 @@ void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 count; mRules->Count(&count); while (index < count) { - nsCOMPtr rule; - mRules->QueryElementAt(index++, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++)); rule->SizeOf(aSizeOfHandler, localSize); } } @@ -1016,7 +1012,7 @@ CSSMediaRuleImpl::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * } /* - * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) + * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt) * should never be called unless you have first called WillDirty() on * the parents tylesheet. After they are called, DidDirty() needs to * be called on the sheet @@ -1026,23 +1022,23 @@ CSSMediaRuleImpl::DeleteStyleRuleAt(PRUint32 aIndex) { NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE); - nsCOMPtr rule; - nsresult rv = mRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); - NS_ENSURE_SUCCESS(rv, rv); - rule->SetStyleSheet(nsnull); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex)); + if (rule) { + rule->SetStyleSheet(nsnull); + } return mRules->DeleteElementAt(aIndex); } NS_IMETHODIMP -CSSMediaRuleImpl::InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule) +CSSMediaRuleImpl::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) { NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE); - // There is no xpcom-compatible version of InsertElementAt.... :( - if (! mRules->InsertElementAt(aRule, aIndex)) { + aRules->EnumerateForwards(SetStyleSheetReference, mSheet); + // There is no xpcom-compatible version of InsertElementsAt.... :( + if (! mRules->InsertElementsAt(aRules, aIndex)) { return NS_ERROR_FAILURE; } - aRule->SetStyleSheet(mSheet); return NS_OK; } @@ -1081,8 +1077,7 @@ CSSMediaRuleImpl::GetCssText(nsAWritableString& aCssText) if (mMedia) { mMedia->Count(&count); for (index = 0; index < count; index++) { - nsCOMPtr medium; - mMedia->QueryElementAt(index, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index)); if (medium) { nsAutoString tempString; if (index > 0) diff --git a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp index 6d7bafee8e8..44bbdd00ace 100644 --- a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp @@ -1515,8 +1515,7 @@ CSSStyleSheetInner::RebuildNameSpaces(void) } } if (mOrderedRules) { - nsINameSpace* nameSpace = mNameSpace; - mOrderedRules->EnumerateForwards(CreateNameSpace, &nameSpace); + mOrderedRules->EnumerateForwards(CreateNameSpace, address_of(mNameSpace)); } } } @@ -2353,8 +2352,7 @@ ListRules(nsISupportsArray* aRules, FILE* aOut, PRInt32 aIndent) if (aRules) { aRules->Count(&count); for (index = 0; index < count; index++) { - nsCOMPtr rule; - aRules->QueryElementAt(index, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)aRules->ElementAt(index)); rule->List(aOut, aIndent); } } @@ -2417,8 +2415,7 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const mMedia->Count(&count); nsAutoString buffer; while (index < PRInt32(count)) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); medium->ToString(buffer); fputs(buffer, out); if (index < PRInt32(count)) { @@ -2680,6 +2677,10 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, { NS_ENSURE_TRUE(mInner, NS_ERROR_FAILURE); nsresult result; + result = WillDirty(); + if (NS_FAILED(result)) + return result; + if (! mInner->mOrderedRules) { result = NS_NewISupportsArray(&(mInner->mOrderedRules)); } @@ -2691,10 +2692,6 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, if (aIndex > count) return NS_ERROR_DOM_INDEX_SIZE_ERR; - result = WillDirty(); - if (NS_FAILED(result)) - return result; - nsCOMPtr loader; nsCOMPtr css; nsCOMPtr htmlContainer(do_QueryInterface(mDocument)); @@ -2717,95 +2714,126 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, return result; } - nsCOMPtr rule; - result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rule)); + nsCOMPtr rules; + result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rules)); if (NS_FAILED(result)) return result; - if (! rule) // parsed successfully, but no rule resulted - return NS_ERROR_DOM_SYNTAX_ERR; - nsCOMPtr cssRule(do_QueryInterface(rule, &result)); - NS_ENSURE_SUCCESS(result, result); + PRUint32 rulecount = 0; + rules->Count(&rulecount); + if (rulecount == 0 && !aRule.IsEmpty()) { + return NS_ERROR_DOM_SYNTAX_ERR; + } + + // Hierarchy checking. Just check the first and last rule in the list. + + // check that we're not inserting before a charset rule + nsCOMPtr nextRule; + PRInt32 nextType = nsICSSRule::UNKNOWN_RULE; + nextRule = dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex)); + if (nextRule) { + nextRule->GetType(nextType); + if (nextType == nsICSSRule::CHARSET_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } - PRInt32 type = nsICSSRule::UNKNOWN_RULE; - cssRule->GetType(type); + // check last rule in list + nsCOMPtr lastRule = dont_AddRef((nsICSSRule*)rules->ElementAt(rulecount-1)); + PRInt32 lastType = nsICSSRule::UNKNOWN_RULE; + lastRule->GetType(lastType); + + if (nextType == nsICSSRule::IMPORT_RULE && + lastType != nsICSSRule::CHARSET_RULE && + lastType != nsICSSRule::IMPORT_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + + if (nextType == nsICSSRule::NAMESPACE_RULE && + lastType != nsICSSRule::CHARSET_RULE && + lastType != nsICSSRule::IMPORT_RULE && + lastType != nsICSSRule::NAMESPACE_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + } + + // check first rule in list + nsCOMPtr firstRule = dont_AddRef((nsICSSRule*)rules->ElementAt(0)); + PRInt32 firstType = nsICSSRule::UNKNOWN_RULE; + firstRule->GetType(firstType); if (aIndex != 0) { - if (type == nsICSSRule::CHARSET_RULE) { // no inserting charset at nonzero position + if (firstType == nsICSSRule::CHARSET_RULE) { // no inserting charset at nonzero position return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } - nsCOMPtr prevRule; - result = mInner->mOrderedRules->QueryElementAt(aIndex-1, NS_GET_IID(nsICSSRule), getter_AddRefs(prevRule)); - NS_ENSURE_SUCCESS(result, result); + nsCOMPtr prevRule = dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex-1)); PRInt32 prevType = nsICSSRule::UNKNOWN_RULE; prevRule->GetType(prevType); - if (type == nsICSSRule::IMPORT_RULE && + if (firstType == nsICSSRule::IMPORT_RULE && prevType != nsICSSRule::CHARSET_RULE && prevType != nsICSSRule::IMPORT_RULE) { return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } - if (type == nsICSSRule::NAMESPACE_RULE && + if (firstType == nsICSSRule::NAMESPACE_RULE && prevType != nsICSSRule::CHARSET_RULE && prevType != nsICSSRule::IMPORT_RULE && prevType != nsICSSRule::NAMESPACE_RULE) { return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } } - - if (type == nsICSSRule::CHARSET_RULE) { - // check that we're not inserting before another chatset rule - nsCOMPtr nextRule; - mInner->mOrderedRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), getter_AddRefs(nextRule)); - if (nextRule) { - PRInt32 nextType = nsICSSRule::UNKNOWN_RULE; - nextRule->GetType(nextType); - if (nextType == nsICSSRule::CHARSET_RULE) { - return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + + result = mInner->mOrderedRules->InsertElementsAt(rules, aIndex); + NS_ENSURE_SUCCESS(result, result); + nsCOMPtr cssRule; + PRUint32 counter; + for (counter = 0; counter < rulecount; counter++) { + cssRule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + cssRule->SetStyleSheet(this); + + PRInt32 type = nsICSSRule::UNKNOWN_RULE; + cssRule->GetType(type); + if (type == nsICSSRule::NAMESPACE_RULE) { + if (! mInner->mNameSpace) { + nsCOMPtr nameSpaceMgr; + result = NS_NewNameSpaceManager(getter_AddRefs(nameSpaceMgr)); + if (NS_FAILED(result)) + return result; + nameSpaceMgr->CreateRootNameSpace(*getter_AddRefs(mInner->mNameSpace)); } + + NS_ENSURE_TRUE(mInner->mNameSpace, NS_ERROR_FAILURE); + + nsCOMPtr nameSpaceRule(do_QueryInterface(cssRule)); + nsCOMPtr newNameSpace; + + nsCOMPtr prefix; + nsAutoString urlSpec; + nameSpaceRule->GetPrefix(*getter_AddRefs(prefix)); + nameSpaceRule->GetURLSpec(urlSpec); + mInner->mNameSpace->CreateChildNameSpace(prefix, urlSpec, + *getter_AddRefs(newNameSpace)); + if (newNameSpace) { + mInner->mNameSpace = newNameSpace; + } + } + else { + CheckRuleForAttributes(cssRule); + } + + if (mDocument) { + result = mDocument->StyleRuleAdded(this, cssRule); + NS_ENSURE_SUCCESS(result, result); } } - result = mInner->mOrderedRules->InsertElementAt(cssRule, aIndex); - NS_ENSURE_SUCCESS(result, result); - cssRule->SetStyleSheet(this); DidDirty(); - if (type == nsICSSRule::NAMESPACE_RULE) { - if (! mInner->mNameSpace) { - nsCOMPtr nameSpaceMgr; - result = NS_NewNameSpaceManager(getter_AddRefs(nameSpaceMgr)); - if (NS_FAILED(result)) - return result; - nameSpaceMgr->CreateRootNameSpace(*getter_AddRefs(mInner->mNameSpace)); - } - - NS_ENSURE_TRUE(mInner->mNameSpace, NS_ERROR_FAILURE); - - nsCOMPtr nameSpaceRule(do_QueryInterface(cssRule)); - nsCOMPtr newNameSpace; - nsCOMPtr prefix; - nsAutoString urlSpec; - nameSpaceRule->GetPrefix(*getter_AddRefs(prefix)); - nameSpaceRule->GetURLSpec(urlSpec); - mInner->mNameSpace->CreateChildNameSpace(prefix, urlSpec, - *getter_AddRefs(newNameSpace)); - if (newNameSpace) { - mInner->mNameSpace = newNameSpace; - } - } - else { - CheckRuleForAttributes(cssRule); - } if (mDocument) { - result = mDocument->StyleRuleAdded(this, cssRule); - NS_ENSURE_SUCCESS(result, result); - result = mDocument->EndUpdate(); NS_ENSURE_SUCCESS(result, result); } - + *aReturn = aIndex; return NS_OK; } @@ -2830,9 +2858,8 @@ CSSStyleSheetImpl::DeleteRule(PRUint32 aIndex) if (aIndex >= count) return NS_ERROR_DOM_INDEX_SIZE_ERR; - nsCOMPtr rule; - mInner->mOrderedRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), - getter_AddRefs(rule)); + nsCOMPtr rule = + dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex)); if (rule) { mInner->mOrderedRules->RemoveElementAt(aIndex); rule->SetStyleSheet(nsnull); @@ -2935,31 +2962,38 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul result = WillDirty(); NS_ENSURE_SUCCESS(result, result); - nsCOMPtr rule; - result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rule)); + nsCOMPtr rules; + result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rules)); NS_ENSURE_SUCCESS(result, result); - if (! rule) { + PRUint32 rulecount = 0; + rules->Count(&rulecount); + if (rulecount == 0 && !aRule.IsEmpty()) { return NS_ERROR_DOM_SYNTAX_ERR; } - nsCOMPtr cssRule(do_QueryInterface(rule, &result)); - NS_ENSURE_SUCCESS(result, result); - - // Only rulesets are allowed in a group as of CSS2 - PRInt32 type = nsICSSRule::UNKNOWN_RULE; - cssRule->GetType(type); - if (type != nsICSSRule::STYLE_RULE) { - return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + PRUint32 counter; + nsCOMPtr rule; + for (counter = 0; counter < rulecount; counter++) { + // Only rulesets are allowed in a group as of CSS2 + PRInt32 type = nsICSSRule::UNKNOWN_RULE; + rule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + rule->GetType(type); + if (type != nsICSSRule::STYLE_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } } - result = aGroup->InsertStyleRuleAt(aIndex, cssRule); + result = aGroup->InsertStyleRulesAt(aIndex, rules); NS_ENSURE_SUCCESS(result, result); DidDirty(); - CheckRuleForAttributes(cssRule); + for (counter = 0; counter < rulecount; counter++) { + rule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + CheckRuleForAttributes(rule); - result = mDocument->StyleRuleAdded(this, cssRule); - NS_ENSURE_SUCCESS(result, result); + result = mDocument->StyleRuleAdded(this, rule); + NS_ENSURE_SUCCESS(result, result); + } result = mDocument->EndUpdate(); NS_ENSURE_SUCCESS(result, result); @@ -4093,8 +4127,8 @@ void CSSRuleProcessor::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 sheetCount, curSheet, localSize2; mSheets->Count(&sheetCount); for(curSheet=0; curSheet < sheetCount; curSheet++){ - nsCOMPtr pSheet; - mSheets->QueryElementAt(curSheet, NS_GET_IID(nsICSSStyleSheet), getter_AddRefs(pSheet)); + nsCOMPtr pSheet = + dont_AddRef((nsICSSStyleSheet*)mSheets->ElementAt(curSheet)); if(pSheet && uniqueItems->AddItem((void*)pSheet)){ pSheet->SizeOf(aSizeOfHandler, localSize2); // XXX aSize += localSize2; diff --git a/mozilla/content/html/style/src/nsICSSGroupRule.h b/mozilla/content/html/style/src/nsICSSGroupRule.h index b6d27c53cbb..512f385fa53 100644 --- a/mozilla/content/html/style/src/nsICSSGroupRule.h +++ b/mozilla/content/html/style/src/nsICSSGroupRule.h @@ -44,13 +44,13 @@ public: NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const = 0; /* - * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) + * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt) * should never be called unless you have first called WillDirty() * on the parent stylesheet. After they are called, DidDirty() * needs to be called on the sheet */ NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex) = 0; - NS_IMETHOD InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule) = 0; + NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) = 0; }; diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 05e859ea64a..374db2a7e98 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -2233,7 +2233,7 @@ nsresult PresShell::SetPrefLinkRules(void) if (NS_SUCCEEDED(result)) { // insert a rule to make links the preferred color PRUint32 index = 0; - nsAutoString strRule, strColor; + nsAutoString strColor; PRBool useDocColors = PR_TRUE; // see if we need to create the rules first @@ -2242,27 +2242,24 @@ nsresult PresShell::SetPrefLinkRules(void) /////////////////////////////////////////////////////////////// // - links: '*:link, *:link:active {color: #RRGGBB [!important];}' ColorToString(linkColor,strColor); - strRule.Append(NS_LITERAL_STRING("*:link, *:link:active {color:")); - strRule.Append(strColor); - if (!useDocColors) { - strRule.Append(NS_LITERAL_STRING(" !important;} ")); - } else { - strRule.Append(NS_LITERAL_STRING(";} ")); - } - + result = sheet->InsertRule(NS_LITERAL_STRING("*:link, *:link:active {color:") + + strColor + + ( useDocColors ? + NS_LITERAL_STRING(";} ") : + NS_LITERAL_STRING(" !important;} ") ), + 0,&index); + NS_ENSURE_SUCCESS(result, result); + /////////////////////////////////////////////////////////////// // - visited links '*:visited, *:visited:active {color: #RRGGBB [!important];}' ColorToString(visitedColor,strColor); - strRule.Append(NS_LITERAL_STRING("*:visited, *:visited:active {color:")); - strRule.Append(strColor); - if (!useDocColors) { - strRule.Append(NS_LITERAL_STRING(" !important;} ")); - } else { - strRule.Append(NS_LITERAL_STRING(";} ")); - } - - // insert the rules - result = sheet->InsertRule(strRule,0,&index); + // insert the rule + result = sheet->InsertRule(NS_LITERAL_STRING("*:visited, *:visited:active {color:") + + strColor + + ( useDocColors ? + NS_LITERAL_STRING(";} ") : + NS_LITERAL_STRING(" !important;} ") ), + 0,&index); } if (NS_SUCCEEDED(result)) { diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 05e859ea64a..374db2a7e98 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -2233,7 +2233,7 @@ nsresult PresShell::SetPrefLinkRules(void) if (NS_SUCCEEDED(result)) { // insert a rule to make links the preferred color PRUint32 index = 0; - nsAutoString strRule, strColor; + nsAutoString strColor; PRBool useDocColors = PR_TRUE; // see if we need to create the rules first @@ -2242,27 +2242,24 @@ nsresult PresShell::SetPrefLinkRules(void) /////////////////////////////////////////////////////////////// // - links: '*:link, *:link:active {color: #RRGGBB [!important];}' ColorToString(linkColor,strColor); - strRule.Append(NS_LITERAL_STRING("*:link, *:link:active {color:")); - strRule.Append(strColor); - if (!useDocColors) { - strRule.Append(NS_LITERAL_STRING(" !important;} ")); - } else { - strRule.Append(NS_LITERAL_STRING(";} ")); - } - + result = sheet->InsertRule(NS_LITERAL_STRING("*:link, *:link:active {color:") + + strColor + + ( useDocColors ? + NS_LITERAL_STRING(";} ") : + NS_LITERAL_STRING(" !important;} ") ), + 0,&index); + NS_ENSURE_SUCCESS(result, result); + /////////////////////////////////////////////////////////////// // - visited links '*:visited, *:visited:active {color: #RRGGBB [!important];}' ColorToString(visitedColor,strColor); - strRule.Append(NS_LITERAL_STRING("*:visited, *:visited:active {color:")); - strRule.Append(strColor); - if (!useDocColors) { - strRule.Append(NS_LITERAL_STRING(" !important;} ")); - } else { - strRule.Append(NS_LITERAL_STRING(";} ")); - } - - // insert the rules - result = sheet->InsertRule(strRule,0,&index); + // insert the rule + result = sheet->InsertRule(NS_LITERAL_STRING("*:visited, *:visited:active {color:") + + strColor + + ( useDocColors ? + NS_LITERAL_STRING(";} ") : + NS_LITERAL_STRING(" !important;} ") ), + 0,&index); } if (NS_SUCCEEDED(result)) { diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index d66334a548e..9d16c208920 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -156,13 +156,14 @@ public: NS_IMETHOD ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult); + nsISupportsArray** aResult); NS_IMETHOD GetCharset(/*out*/nsAWritableString &aCharsetDest) const; // sets the out-param to the current charset, as set by SetCharset NS_IMETHOD SetCharset(/*in*/ const nsAReadableString &aCharsetSrc); // NOTE: SetCharset expects the charset to be the preferred charset // and it just records the string exactly as passed in (no alias resolution) + void AppendRule(nsICSSRule* aRule); protected: nsresult InitScanner(nsIUnicharInputStream* aInput, nsIURI* aURI); @@ -182,20 +183,20 @@ protected: PRBool PushGroup(nsICSSGroupRule* aRule); void PopGroup(void); - void AppendRule(nsICSSRule* aRule); - PRBool ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult = nsnull); - PRBool ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult = nsnull); - PRBool ParseCharsetRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + PRBool ParseRuleSet(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseAtRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseCharsetRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseImportRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool GatherMedia(PRInt32& aErrorCode, nsString& aMedia, nsISupportsArray* aMediaAtoms); - PRBool ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, nsIStyleRule** aResult); - PRBool ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + PRBool ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseMediaRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParseNameSpaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); PRBool ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPrefix, - const nsString& aURLSpec, nsIStyleRule** aResult); - PRBool ParseFontFaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult); - PRBool ParsePageRule(PRInt32& aErrorCode, nsIStyleRule** aResult); + const nsString& aURLSpec, RuleAppendFunc aAppendFunc, + void* aProcessData); + PRBool ParseFontFaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); + PRBool ParsePageRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aProcessData); void ParseIDSelector(PRInt32& aDataMask, nsCSSSelector& aSelector, PRInt32& aParsingStatus, PRInt32& aErrorCode); @@ -330,6 +331,18 @@ protected: PRBool IsParsingCompoundProperty(void) {return mParsingCompoundProperty;}; }; +PR_STATIC_CALLBACK(void) AppendRuleToArray(nsICSSRule* aRule, void* aArray) +{ + nsISupportsArray* arr = (nsISupportsArray*) aArray; + arr->AppendElement(aRule); +} + +PR_STATIC_CALLBACK(void) AppendRuleToSheet(nsICSSRule* aRule, void* aParser) +{ + CSSParserImpl* parser = (CSSParserImpl*) aParser; + parser->AppendRule(aRule); +} + NS_HTML nsresult NS_NewCSSParser(nsICSSParser** aInstancePtrResult) { @@ -566,11 +579,11 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, continue; // legal here only } if (eCSSToken_AtKeyword == tk->mType) { - ParseAtRule(errorCode); + ParseAtRule(errorCode, AppendRuleToSheet, this); continue; } UngetToken(); - if (ParseRuleSet(errorCode)) { + if (ParseRuleSet(errorCode, AppendRuleToSheet, this)) { mSection = eCSSSection_General; } } @@ -684,42 +697,49 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsAReadableString& aBuffer, NS_IMETHODIMP CSSParserImpl::ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult) + nsISupportsArray** aResult) { NS_ASSERTION(nsnull != aBaseURL, "need base URL"); NS_ENSURE_ARG_POINTER(aResult); - *aResult = nsnull; - + nsString* str = new nsString(aRule); if (nsnull == str) { return NS_ERROR_OUT_OF_MEMORY; } nsCOMPtr input = nsnull; nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str); - if (NS_OK != rv) { + if (NS_FAILED(rv)) { delete str; return rv; } rv = InitScanner(input, aBaseURL); - if (! NS_SUCCEEDED(rv)) { + if (NS_FAILED(rv)) { return rv; } - mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules. Maybe pass in the previous rule to this method? + rv = NS_NewISupportsArray(aResult); + if (NS_FAILED(rv)) { + return rv; + } + + mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules. PRInt32 errorCode = NS_OK; nsCSSToken* tk = &mToken; // Get first non-whitespace token if (!GetToken(errorCode, PR_TRUE)) { + REPORT_UNEXPECTED( + NS_LITERAL_STRING("Whitespace-only string given to be parsed as rule.")); OUTPUT_ERROR(); } else if (eCSSToken_AtKeyword == tk->mType) { - ParseAtRule(errorCode, aResult); + ParseAtRule(errorCode, AppendRuleToArray, *aResult); } else { UngetToken(); - ParseRuleSet(errorCode, aResult); + ParseRuleSet(errorCode, AppendRuleToArray, *aResult); } + OUTPUT_ERROR(); ReleaseScanner(); return NS_OK; } @@ -837,43 +857,44 @@ PRBool CSSParserImpl::SkipAtRule(PRInt32& aErrorCode) return PR_TRUE; } -PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { if ((mSection <= eCSSSection_Charset) && (mToken.mIdent.EqualsIgnoreCase("charset"))) { - if (ParseCharsetRule(aErrorCode, aResult)) { + if (ParseCharsetRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_Import; // only one charset allowed return PR_TRUE; } } if ((mSection <= eCSSSection_Import) && mToken.mIdent.EqualsIgnoreCase("import")) { - if (ParseImportRule(aErrorCode, aResult)) { + if (ParseImportRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_Import; return PR_TRUE; } } if ((mSection <= eCSSSection_NameSpace) && mToken.mIdent.EqualsIgnoreCase("namespace")) { - if (ParseNameSpaceRule(aErrorCode, aResult)) { + if (ParseNameSpaceRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_NameSpace; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("media")) { - if (ParseMediaRule(aErrorCode, aResult)) { + if (ParseMediaRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("font-face")) { - if (ParseFontFaceRule(aErrorCode, aResult)) { + if (ParseFontFaceRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } } if (mToken.mIdent.EqualsIgnoreCase("page")) { - if (ParsePageRule(aErrorCode, aResult)) { + if (ParsePageRule(aErrorCode, aAppendFunc, aData)) { mSection = eCSSSection_General; return PR_TRUE; } @@ -886,7 +907,8 @@ PRBool CSSParserImpl::ParseAtRule(PRInt32& aErrorCode, nsIStyleRule** aResult) return SkipAtRule(aErrorCode); } -PRBool CSSParserImpl::ParseCharsetRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseCharsetRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { // XXX not yet implemented return PR_FALSE; @@ -961,7 +983,7 @@ PRBool CSSParserImpl::GatherMedia(PRInt32& aErrorCode, nsString& aMedia, } // Parse a CSS2 import rule: "@import STRING | URL [medium [, mdeium]]" -PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { if (!GetToken(aErrorCode, PR_TRUE)) { REPORT_UNEXPECTED_EOF(); @@ -974,7 +996,7 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul url = mToken.mIdent; if (GatherMedia(aErrorCode, media, nsnull)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessImport(aErrorCode, url, media, aResult); + ProcessImport(aErrorCode, url, media, aAppendFunc, aData); return PR_TRUE; } } @@ -988,7 +1010,7 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (GatherMedia(aErrorCode, media, nsnull)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessImport(aErrorCode, url, media, aResult); + ProcessImport(aErrorCode, url, media, aAppendFunc, aData); return PR_TRUE; } } @@ -1004,19 +1026,14 @@ PRBool CSSParserImpl::ParseImportRule(PRInt32& aErrorCode, nsIStyleRule** aResul } -PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, nsIStyleRule** aResult) +PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpec, const nsString& aMedia, RuleAppendFunc aAppendFunc, void* aData) { nsCOMPtr rule; - NS_NewCSSImportRule(getter_AddRefs(rule), aURLSpec, aMedia); - if (rule) { - if (aResult) { // someone wants this rule - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - } + aErrorCode = NS_NewCSSImportRule(getter_AddRefs(rule), aURLSpec, aMedia); + if (NS_FAILED(aErrorCode)) { + return PR_FALSE; } + (*aAppendFunc)(rule, aData); if (mChildLoader) { // XXX probably need a way to encode unicode junk for the part of @@ -1042,7 +1059,8 @@ PRBool CSSParserImpl::ProcessImport(PRInt32& aErrorCode, const nsString& aURLSpe } // Parse a CSS2 media rule: "@media medium [, medium] { ... }" -PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, + void* aData) { nsAutoString mediaStr; nsCOMPtr media; @@ -1075,22 +1093,15 @@ PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult continue; } UngetToken(); - ParseRuleSet(aErrorCode); + ParseRuleSet(aErrorCode, AppendRuleToSheet, this); } PopGroup(); if (ExpectSymbol(aErrorCode, '}', PR_TRUE)) { - if (aResult) { // someone wants this rule - rule->SetMedia(media); - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - // Append first, so when we do SetMedia() the rule - // knows what its stylesheet is. - AppendRule(rule); - rule->SetMedia(media); - } + // Append first, so when we do SetMedia() the rule + // knows what its stylesheet is. + (*aAppendFunc)(rule, aData); + rule->SetMedia(media); return PR_TRUE; } mSection = holdSection; @@ -1107,7 +1118,9 @@ PRBool CSSParserImpl::ParseMediaRule(PRInt32& aErrorCode, nsIStyleRule** aResult } // Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;" -PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, + RuleAppendFunc aAppendFunc, + void* aData) { if (!GetToken(aErrorCode, PR_TRUE)) { REPORT_UNEXPECTED_EOF(); @@ -1129,7 +1142,7 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe if (eCSSToken_String == mToken.mType) { url = mToken.mIdent; if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessNameSpace(aErrorCode, prefix, url, aResult); + ProcessNameSpace(aErrorCode, prefix, url, aAppendFunc, aData); return PR_TRUE; } } @@ -1141,7 +1154,7 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe url = mToken.mIdent; if (ExpectSymbol(aErrorCode, ')', PR_TRUE)) { if (ExpectSymbol(aErrorCode, ';', PR_TRUE)) { - ProcessNameSpace(aErrorCode, prefix, url, aResult); + ProcessNameSpace(aErrorCode, prefix, url, aAppendFunc, aData); return PR_TRUE; } } @@ -1156,7 +1169,8 @@ PRBool CSSParserImpl::ParseNameSpaceRule(PRInt32& aErrorCode, nsIStyleRule** aRe } PRBool CSSParserImpl::ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPrefix, - const nsString& aURLSpec, nsIStyleRule** aResult) + const nsString& aURLSpec, RuleAppendFunc aAppendFunc, + void* aData) { PRBool result = PR_FALSE; @@ -1169,27 +1183,21 @@ PRBool CSSParserImpl::ProcessNameSpace(PRInt32& aErrorCode, const nsString& aPre NS_NewCSSNameSpaceRule(getter_AddRefs(rule), prefix, aURLSpec); if (rule) { - if (aResult) { // someone wants this rule - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - NS_IF_RELEASE(mNameSpace); - mSheet->GetNameSpace(mNameSpace); - } + (*aAppendFunc)(rule, aData); + NS_IF_RELEASE(mNameSpace); + mSheet->GetNameSpace(mNameSpace); } return result; } -PRBool CSSParserImpl::ParseFontFaceRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseFontFaceRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // XXX not yet implemented return PR_FALSE; } -PRBool CSSParserImpl::ParsePageRule(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParsePageRule(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // XXX not yet implemented return PR_FALSE; @@ -1313,7 +1321,7 @@ void CSSParserImpl::AppendRule(nsICSSRule* aRule) } } -PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult) +PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, RuleAppendFunc aAppendFunc, void* aData) { // First get the list of selectors for the rule SelectorList* slist = nsnull; @@ -1361,13 +1369,7 @@ PRBool CSSParserImpl::ParseRuleSet(PRInt32& aErrorCode, nsIStyleRule** aResult) rule->SetDeclaration(declaration); rule->SetWeight(list->mWeight); // rule->List(); - if (aResult) { // someone wants this rule back; don't append it - *aResult = rule; - NS_ADDREF(*aResult); - } - else { - AppendRule(rule); - } + (*aAppendFunc)(rule, aData); NS_RELEASE(rule); } diff --git a/mozilla/layout/style/nsCSSRules.cpp b/mozilla/layout/style/nsCSSRules.cpp index 637cadf6ffd..150b47f4734 100644 --- a/mozilla/layout/style/nsCSSRules.cpp +++ b/mozilla/layout/style/nsCSSRules.cpp @@ -711,7 +711,7 @@ public: NS_IMETHOD GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const; NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const; NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex); - NS_IMETHOD InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule); + NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules); // nsIDOMCSSRule interface NS_DECL_NSIDOMCSSRULE @@ -836,8 +836,7 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const PRUint32 count; mMedia->Count(&count); while (index < count) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); medium->ToString(buffer); fputs(buffer, out); if (index < count) { @@ -852,8 +851,7 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const PRUint32 count; mRules->Count(&count); while (index < count) { - nsCOMPtr rule; - mRules->QueryElementAt(index++, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++)); rule->List(out, aIndent + 1); } } @@ -898,8 +896,7 @@ void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 count; mMedia->Count(&count); while (index < count) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); if(medium && uniqueItems->AddItem(medium)){ medium->SizeOf(aSizeOfHandler, &localSize); aSize += localSize; @@ -915,8 +912,7 @@ void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 count; mRules->Count(&count); while (index < count) { - nsCOMPtr rule; - mRules->QueryElementAt(index++, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(index++)); rule->SizeOf(aSizeOfHandler, localSize); } } @@ -1016,7 +1012,7 @@ CSSMediaRuleImpl::EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * } /* - * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) + * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt) * should never be called unless you have first called WillDirty() on * the parents tylesheet. After they are called, DidDirty() needs to * be called on the sheet @@ -1026,23 +1022,23 @@ CSSMediaRuleImpl::DeleteStyleRuleAt(PRUint32 aIndex) { NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE); - nsCOMPtr rule; - nsresult rv = mRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); - NS_ENSURE_SUCCESS(rv, rv); - rule->SetStyleSheet(nsnull); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)mRules->ElementAt(aIndex)); + if (rule) { + rule->SetStyleSheet(nsnull); + } return mRules->DeleteElementAt(aIndex); } NS_IMETHODIMP -CSSMediaRuleImpl::InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule) +CSSMediaRuleImpl::InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) { NS_ENSURE_TRUE(mRules, NS_ERROR_FAILURE); - // There is no xpcom-compatible version of InsertElementAt.... :( - if (! mRules->InsertElementAt(aRule, aIndex)) { + aRules->EnumerateForwards(SetStyleSheetReference, mSheet); + // There is no xpcom-compatible version of InsertElementsAt.... :( + if (! mRules->InsertElementsAt(aRules, aIndex)) { return NS_ERROR_FAILURE; } - aRule->SetStyleSheet(mSheet); return NS_OK; } @@ -1081,8 +1077,7 @@ CSSMediaRuleImpl::GetCssText(nsAWritableString& aCssText) if (mMedia) { mMedia->Count(&count); for (index = 0; index < count; index++) { - nsCOMPtr medium; - mMedia->QueryElementAt(index, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index)); if (medium) { nsAutoString tempString; if (index > 0) diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index 6d7bafee8e8..44bbdd00ace 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -1515,8 +1515,7 @@ CSSStyleSheetInner::RebuildNameSpaces(void) } } if (mOrderedRules) { - nsINameSpace* nameSpace = mNameSpace; - mOrderedRules->EnumerateForwards(CreateNameSpace, &nameSpace); + mOrderedRules->EnumerateForwards(CreateNameSpace, address_of(mNameSpace)); } } } @@ -2353,8 +2352,7 @@ ListRules(nsISupportsArray* aRules, FILE* aOut, PRInt32 aIndent) if (aRules) { aRules->Count(&count); for (index = 0; index < count; index++) { - nsCOMPtr rule; - aRules->QueryElementAt(index, NS_GET_IID(nsICSSRule), getter_AddRefs(rule)); + nsCOMPtr rule = dont_AddRef((nsICSSRule*)aRules->ElementAt(index)); rule->List(aOut, aIndent); } } @@ -2417,8 +2415,7 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const mMedia->Count(&count); nsAutoString buffer; while (index < PRInt32(count)) { - nsCOMPtr medium; - mMedia->QueryElementAt(index++, NS_GET_IID(nsIAtom), getter_AddRefs(medium)); + nsCOMPtr medium = dont_AddRef((nsIAtom*)mMedia->ElementAt(index++)); medium->ToString(buffer); fputs(buffer, out); if (index < PRInt32(count)) { @@ -2680,6 +2677,10 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, { NS_ENSURE_TRUE(mInner, NS_ERROR_FAILURE); nsresult result; + result = WillDirty(); + if (NS_FAILED(result)) + return result; + if (! mInner->mOrderedRules) { result = NS_NewISupportsArray(&(mInner->mOrderedRules)); } @@ -2691,10 +2692,6 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, if (aIndex > count) return NS_ERROR_DOM_INDEX_SIZE_ERR; - result = WillDirty(); - if (NS_FAILED(result)) - return result; - nsCOMPtr loader; nsCOMPtr css; nsCOMPtr htmlContainer(do_QueryInterface(mDocument)); @@ -2717,95 +2714,126 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule, return result; } - nsCOMPtr rule; - result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rule)); + nsCOMPtr rules; + result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rules)); if (NS_FAILED(result)) return result; - if (! rule) // parsed successfully, but no rule resulted - return NS_ERROR_DOM_SYNTAX_ERR; - nsCOMPtr cssRule(do_QueryInterface(rule, &result)); - NS_ENSURE_SUCCESS(result, result); + PRUint32 rulecount = 0; + rules->Count(&rulecount); + if (rulecount == 0 && !aRule.IsEmpty()) { + return NS_ERROR_DOM_SYNTAX_ERR; + } + + // Hierarchy checking. Just check the first and last rule in the list. + + // check that we're not inserting before a charset rule + nsCOMPtr nextRule; + PRInt32 nextType = nsICSSRule::UNKNOWN_RULE; + nextRule = dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex)); + if (nextRule) { + nextRule->GetType(nextType); + if (nextType == nsICSSRule::CHARSET_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } - PRInt32 type = nsICSSRule::UNKNOWN_RULE; - cssRule->GetType(type); + // check last rule in list + nsCOMPtr lastRule = dont_AddRef((nsICSSRule*)rules->ElementAt(rulecount-1)); + PRInt32 lastType = nsICSSRule::UNKNOWN_RULE; + lastRule->GetType(lastType); + + if (nextType == nsICSSRule::IMPORT_RULE && + lastType != nsICSSRule::CHARSET_RULE && + lastType != nsICSSRule::IMPORT_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + + if (nextType == nsICSSRule::NAMESPACE_RULE && + lastType != nsICSSRule::CHARSET_RULE && + lastType != nsICSSRule::IMPORT_RULE && + lastType != nsICSSRule::NAMESPACE_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } + } + + // check first rule in list + nsCOMPtr firstRule = dont_AddRef((nsICSSRule*)rules->ElementAt(0)); + PRInt32 firstType = nsICSSRule::UNKNOWN_RULE; + firstRule->GetType(firstType); if (aIndex != 0) { - if (type == nsICSSRule::CHARSET_RULE) { // no inserting charset at nonzero position + if (firstType == nsICSSRule::CHARSET_RULE) { // no inserting charset at nonzero position return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } - nsCOMPtr prevRule; - result = mInner->mOrderedRules->QueryElementAt(aIndex-1, NS_GET_IID(nsICSSRule), getter_AddRefs(prevRule)); - NS_ENSURE_SUCCESS(result, result); + nsCOMPtr prevRule = dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex-1)); PRInt32 prevType = nsICSSRule::UNKNOWN_RULE; prevRule->GetType(prevType); - if (type == nsICSSRule::IMPORT_RULE && + if (firstType == nsICSSRule::IMPORT_RULE && prevType != nsICSSRule::CHARSET_RULE && prevType != nsICSSRule::IMPORT_RULE) { return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } - if (type == nsICSSRule::NAMESPACE_RULE && + if (firstType == nsICSSRule::NAMESPACE_RULE && prevType != nsICSSRule::CHARSET_RULE && prevType != nsICSSRule::IMPORT_RULE && prevType != nsICSSRule::NAMESPACE_RULE) { return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; } } - - if (type == nsICSSRule::CHARSET_RULE) { - // check that we're not inserting before another chatset rule - nsCOMPtr nextRule; - mInner->mOrderedRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), getter_AddRefs(nextRule)); - if (nextRule) { - PRInt32 nextType = nsICSSRule::UNKNOWN_RULE; - nextRule->GetType(nextType); - if (nextType == nsICSSRule::CHARSET_RULE) { - return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + + result = mInner->mOrderedRules->InsertElementsAt(rules, aIndex); + NS_ENSURE_SUCCESS(result, result); + nsCOMPtr cssRule; + PRUint32 counter; + for (counter = 0; counter < rulecount; counter++) { + cssRule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + cssRule->SetStyleSheet(this); + + PRInt32 type = nsICSSRule::UNKNOWN_RULE; + cssRule->GetType(type); + if (type == nsICSSRule::NAMESPACE_RULE) { + if (! mInner->mNameSpace) { + nsCOMPtr nameSpaceMgr; + result = NS_NewNameSpaceManager(getter_AddRefs(nameSpaceMgr)); + if (NS_FAILED(result)) + return result; + nameSpaceMgr->CreateRootNameSpace(*getter_AddRefs(mInner->mNameSpace)); } + + NS_ENSURE_TRUE(mInner->mNameSpace, NS_ERROR_FAILURE); + + nsCOMPtr nameSpaceRule(do_QueryInterface(cssRule)); + nsCOMPtr newNameSpace; + + nsCOMPtr prefix; + nsAutoString urlSpec; + nameSpaceRule->GetPrefix(*getter_AddRefs(prefix)); + nameSpaceRule->GetURLSpec(urlSpec); + mInner->mNameSpace->CreateChildNameSpace(prefix, urlSpec, + *getter_AddRefs(newNameSpace)); + if (newNameSpace) { + mInner->mNameSpace = newNameSpace; + } + } + else { + CheckRuleForAttributes(cssRule); + } + + if (mDocument) { + result = mDocument->StyleRuleAdded(this, cssRule); + NS_ENSURE_SUCCESS(result, result); } } - result = mInner->mOrderedRules->InsertElementAt(cssRule, aIndex); - NS_ENSURE_SUCCESS(result, result); - cssRule->SetStyleSheet(this); DidDirty(); - if (type == nsICSSRule::NAMESPACE_RULE) { - if (! mInner->mNameSpace) { - nsCOMPtr nameSpaceMgr; - result = NS_NewNameSpaceManager(getter_AddRefs(nameSpaceMgr)); - if (NS_FAILED(result)) - return result; - nameSpaceMgr->CreateRootNameSpace(*getter_AddRefs(mInner->mNameSpace)); - } - - NS_ENSURE_TRUE(mInner->mNameSpace, NS_ERROR_FAILURE); - - nsCOMPtr nameSpaceRule(do_QueryInterface(cssRule)); - nsCOMPtr newNameSpace; - nsCOMPtr prefix; - nsAutoString urlSpec; - nameSpaceRule->GetPrefix(*getter_AddRefs(prefix)); - nameSpaceRule->GetURLSpec(urlSpec); - mInner->mNameSpace->CreateChildNameSpace(prefix, urlSpec, - *getter_AddRefs(newNameSpace)); - if (newNameSpace) { - mInner->mNameSpace = newNameSpace; - } - } - else { - CheckRuleForAttributes(cssRule); - } if (mDocument) { - result = mDocument->StyleRuleAdded(this, cssRule); - NS_ENSURE_SUCCESS(result, result); - result = mDocument->EndUpdate(); NS_ENSURE_SUCCESS(result, result); } - + *aReturn = aIndex; return NS_OK; } @@ -2830,9 +2858,8 @@ CSSStyleSheetImpl::DeleteRule(PRUint32 aIndex) if (aIndex >= count) return NS_ERROR_DOM_INDEX_SIZE_ERR; - nsCOMPtr rule; - mInner->mOrderedRules->QueryElementAt(aIndex, NS_GET_IID(nsICSSRule), - getter_AddRefs(rule)); + nsCOMPtr rule = + dont_AddRef((nsICSSRule*)mInner->mOrderedRules->ElementAt(aIndex)); if (rule) { mInner->mOrderedRules->RemoveElementAt(aIndex); rule->SetStyleSheet(nsnull); @@ -2935,31 +2962,38 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul result = WillDirty(); NS_ENSURE_SUCCESS(result, result); - nsCOMPtr rule; - result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rule)); + nsCOMPtr rules; + result = css->ParseRule(aRule, mInner->mURL, getter_AddRefs(rules)); NS_ENSURE_SUCCESS(result, result); - if (! rule) { + PRUint32 rulecount = 0; + rules->Count(&rulecount); + if (rulecount == 0 && !aRule.IsEmpty()) { return NS_ERROR_DOM_SYNTAX_ERR; } - nsCOMPtr cssRule(do_QueryInterface(rule, &result)); - NS_ENSURE_SUCCESS(result, result); - - // Only rulesets are allowed in a group as of CSS2 - PRInt32 type = nsICSSRule::UNKNOWN_RULE; - cssRule->GetType(type); - if (type != nsICSSRule::STYLE_RULE) { - return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + PRUint32 counter; + nsCOMPtr rule; + for (counter = 0; counter < rulecount; counter++) { + // Only rulesets are allowed in a group as of CSS2 + PRInt32 type = nsICSSRule::UNKNOWN_RULE; + rule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + rule->GetType(type); + if (type != nsICSSRule::STYLE_RULE) { + return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; + } } - result = aGroup->InsertStyleRuleAt(aIndex, cssRule); + result = aGroup->InsertStyleRulesAt(aIndex, rules); NS_ENSURE_SUCCESS(result, result); DidDirty(); - CheckRuleForAttributes(cssRule); + for (counter = 0; counter < rulecount; counter++) { + rule = dont_AddRef((nsICSSRule*)rules->ElementAt(counter)); + CheckRuleForAttributes(rule); - result = mDocument->StyleRuleAdded(this, cssRule); - NS_ENSURE_SUCCESS(result, result); + result = mDocument->StyleRuleAdded(this, rule); + NS_ENSURE_SUCCESS(result, result); + } result = mDocument->EndUpdate(); NS_ENSURE_SUCCESS(result, result); @@ -4093,8 +4127,8 @@ void CSSRuleProcessor::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) PRUint32 sheetCount, curSheet, localSize2; mSheets->Count(&sheetCount); for(curSheet=0; curSheet < sheetCount; curSheet++){ - nsCOMPtr pSheet; - mSheets->QueryElementAt(curSheet, NS_GET_IID(nsICSSStyleSheet), getter_AddRefs(pSheet)); + nsCOMPtr pSheet = + dont_AddRef((nsICSSStyleSheet*)mSheets->ElementAt(curSheet)); if(pSheet && uniqueItems->AddItem((void*)pSheet)){ pSheet->SizeOf(aSizeOfHandler, localSize2); // XXX aSize += localSize2; diff --git a/mozilla/layout/style/nsICSSGroupRule.h b/mozilla/layout/style/nsICSSGroupRule.h index b6d27c53cbb..512f385fa53 100644 --- a/mozilla/layout/style/nsICSSGroupRule.h +++ b/mozilla/layout/style/nsICSSGroupRule.h @@ -44,13 +44,13 @@ public: NS_IMETHOD EnumerateRulesForwards(nsISupportsArrayEnumFunc aFunc, void * aData) const = 0; /* - * The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt) + * The next two methods (DeleteStyleRuleAt and InsertStyleRulesAt) * should never be called unless you have first called WillDirty() * on the parent stylesheet. After they are called, DidDirty() * needs to be called on the sheet */ NS_IMETHOD DeleteStyleRuleAt(PRUint32 aIndex) = 0; - NS_IMETHOD InsertStyleRuleAt(PRUint32 aIndex, nsICSSRule* aRule) = 0; + NS_IMETHOD InsertStyleRulesAt(PRUint32 aIndex, nsISupportsArray* aRules) = 0; }; diff --git a/mozilla/layout/style/nsICSSParser.h b/mozilla/layout/style/nsICSSParser.h index 6839164714a..12bea9204a4 100644 --- a/mozilla/layout/style/nsICSSParser.h +++ b/mozilla/layout/style/nsICSSParser.h @@ -31,11 +31,16 @@ class nsIUnicharInputStream; class nsIURI; class nsICSSDeclaration; class nsICSSLoader; +class nsICSSRule; +class nsISupportsArray; #define NS_ICSS_PARSER_IID \ { 0xcc9c0610, 0x968c, 0x11d1, \ {0x93, 0x23, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} } +// Rule processing function +typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData); + // Interface to the css parser. class nsICSSParser : public nsISupports { public: @@ -77,7 +82,7 @@ public: NS_IMETHOD ParseRule(nsAReadableString& aRule, nsIURI* aBaseURL, - nsIStyleRule** aResult) = 0; + nsISupportsArray** aResult) = 0; // Charset management method: // Set the charset before calling any of the Parse emthods if you want the