From 09a726c20da4db8f3d83f76ebbb24a80597bf5cc Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Wed, 3 May 2000 21:42:00 +0000 Subject: [PATCH] WIP for supporting setting the cssText property on css declarations through the CSS DOM, approved and partly reviewed by Pierre. git-svn-id: svn://10.0.0.236/trunk@68135 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/content/src/nsGenericHTMLElement.cpp | 62 +++++++++++++++++-- .../content/html/style/public/nsICSSParser.h | 5 ++ .../content/html/style/src/nsCSSParser.cpp | 24 ++++--- .../content/html/style/src/nsCSSStyleRule.cpp | 49 +++++++++++++-- .../html/style/src/nsDOMCSSDeclaration.cpp | 2 +- .../html/style/src/nsDOMCSSDeclaration.h | 6 +- .../html/content/src/nsGenericHTMLElement.cpp | 62 +++++++++++++++++-- .../layout/html/style/public/nsICSSParser.h | 5 ++ mozilla/layout/html/style/src/nsCSSParser.cpp | 24 ++++--- .../layout/html/style/src/nsCSSStyleRule.cpp | 49 +++++++++++++-- .../html/style/src/nsDOMCSSDeclaration.cpp | 2 +- .../html/style/src/nsDOMCSSDeclaration.h | 6 +- mozilla/layout/style/nsCSSParser.cpp | 24 ++++--- mozilla/layout/style/nsCSSStyleRule.cpp | 49 +++++++++++++-- mozilla/layout/style/nsDOMCSSDeclaration.cpp | 2 +- mozilla/layout/style/nsDOMCSSDeclaration.h | 6 +- mozilla/layout/style/nsICSSParser.h | 5 ++ 17 files changed, 335 insertions(+), 47 deletions(-) diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 4c3619bfcac..3f1726d4ed1 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -114,7 +114,10 @@ public: virtual void DropReference(); virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate); - virtual nsresult ParseDeclaration(const nsString& aDecl); + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl); + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl); virtual nsresult GetParent(nsISupports **aParent); protected: @@ -229,8 +232,34 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(nsICSSDeclaration **aDecl, return result; } +nsresult +nsDOMCSSAttributeDeclaration::SetCSSDeclaration(nsICSSDeclaration *aDecl) +{ + nsHTMLValue val; + nsIStyleRule* rule; + nsICSSStyleRule* cssRule; + nsresult result = NS_OK; + + if (nsnull != mContent) { + mContent->GetHTMLAttribute(nsHTMLAtoms::style, val); + if (eHTMLUnit_ISupports == val.GetUnit()) { + rule = (nsIStyleRule*) val.GetISupportsValue(); + result = rule->QueryInterface(kICSSStyleRuleIID, (void**)&cssRule); + if (NS_OK == result) { + cssRule->SetDeclaration(aDecl); + NS_RELEASE(cssRule); + } + NS_RELEASE(rule); + } + } + + return result; +} + nsresult -nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl) +nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) { nsICSSDeclaration *decl; nsresult result = GetCSSDeclaration(&decl, PR_TRUE); @@ -265,9 +294,34 @@ nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl) if (doc) { doc->BeginUpdate(); } - result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, &hint); + nsCOMPtr declClone; + decl->Clone(*getter_AddRefs(declClone)); + + if (aClearOldDecl) { + // This should be done with decl->Clear() once such a method exists. + nsAutoString propName; + PRUint32 count, i; + + decl->Count(&count); + + for (i = 0; i < count; i++) { + decl->GetNthProperty(0, propName); + + nsCSSProperty prop = nsCSSProps::LookupProperty(propName); + nsCSSValue val; + + decl->RemoveProperty(prop, val); + } + } + + result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, + aParseOnlyOneDecl, &hint); + if (result == NS_CSS_PARSER_DROP_DECLARATION) { + SetCSSDeclaration(declClone); + result = NS_OK; + } if (doc) { - if (NS_SUCCEEDED(result)) { + if (NS_SUCCEEDED(result) && result != NS_CSS_PARSER_DROP_DECLARATION) { doc->AttributeChanged(mContent, kNameSpaceID_None, nsHTMLAtoms::style, hint); } doc->EndUpdate(); diff --git a/mozilla/content/html/style/public/nsICSSParser.h b/mozilla/content/html/style/public/nsICSSParser.h index 3b0241e18fc..349cb71529b 100644 --- a/mozilla/content/html/style/public/nsICSSParser.h +++ b/mozilla/content/html/style/public/nsICSSParser.h @@ -72,6 +72,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) = 0; // Charset management method: @@ -92,6 +93,10 @@ public: #define NS_CSS_GETINFO_CSS2 ((PRUint32) 0x00000004L) #define NS_CSS_GETINFO_CSS_FROSTING ((PRUint32) 0x00000008L) +// Success code that can be returned from ParseAndAppendDeclaration() +#define NS_CSS_PARSER_DROP_DECLARATION \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) + extern NS_HTML nsresult NS_NewCSSParser(nsICSSParser** aInstancePtrResult); diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index a95e6183363..04ce62c183a 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -55,9 +55,6 @@ static NS_DEFINE_IID(kICSSParserIID, NS_ICSS_PARSER_IID); static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); -#define NS_CSS_PARSER_DROP_DECLARATION \ - NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) - MOZ_DECL_CTOR_COUNTER(SelectorList); @@ -149,6 +146,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint); NS_IMETHOD GetCharset(/*out*/nsString &aCharsetDest) const; @@ -555,6 +553,7 @@ NS_IMETHODIMP CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) { // NS_ASSERTION(nsnull != aBaseURL, "need base URL"); @@ -581,15 +580,26 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, PRInt32 hint = NS_STYLE_HINT_NONE; - if (! ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { - hint = NS_STYLE_HINT_NONE; - } if (nsnull != aHint) { *aHint = hint; } + do { + if (ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { + if (aHint && hint > *aHint) { + *aHint = hint; + } + } else { + if (errorCode != -1) { // -1 means EOF so we ignore that + rv = errorCode; + } + + break; + } + } while (!aParseOnlyOneDecl); + ReleaseScanner(); - return NS_OK; + return rv; } //---------------------------------------------------------------------- diff --git a/mozilla/content/html/style/src/nsCSSStyleRule.cpp b/mozilla/content/html/style/src/nsCSSStyleRule.cpp index 15d31bcd17e..e6f76eb14e0 100644 --- a/mozilla/content/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleRule.cpp @@ -793,7 +793,10 @@ public: virtual void DropReference(void); virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate); - virtual nsresult ParseDeclaration(const nsString& aDecl); + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl); + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl); virtual nsresult GetParent(nsISupports **aParent); protected: @@ -865,8 +868,20 @@ DOMCSSDeclarationImpl::GetCSSDeclaration(nsICSSDeclaration **aDecl, return NS_OK; } +nsresult +DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl) +{ + if (nsnull != mRule) { + mRule->SetDeclaration(aDecl); + } + + return NS_OK; +} + nsresult -DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) +DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) { nsICSSDeclaration *decl; nsresult result = GetCSSDeclaration(&decl, PR_TRUE); @@ -904,9 +919,35 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) } if (NS_SUCCEEDED(result)) { + nsCOMPtr declClone; + decl->Clone(*getter_AddRefs(declClone)); + NS_ENSURE_TRUE(declClone, NS_ERROR_OUT_OF_MEMORY); + + if (aClearOldDecl) { + // This should be done with decl->Clear() once such a method exists. + nsAutoString propName; + PRUint32 count, i; + + decl->Count(&count); + + for (i = 0; i < count; i++) { + decl->GetNthProperty(0, propName); + + nsCSSProperty prop = nsCSSProps::LookupProperty(propName); + nsCSSValue val; + + decl->RemoveProperty(prop, val); + } + } + PRInt32 hint; - result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, &hint); - if (NS_SUCCEEDED(result)) { + result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, + aParseOnlyOneDecl, &hint); + + if (result == NS_CSS_PARSER_DROP_DECLARATION) { + SetCSSDeclaration(declClone); + result = NS_OK; + } else if (NS_SUCCEEDED(result)) { if (cssSheet) { cssSheet->SetModified(PR_TRUE); } diff --git a/mozilla/content/html/style/src/nsDOMCSSDeclaration.cpp b/mozilla/content/html/style/src/nsDOMCSSDeclaration.cpp index 091a24a46ca..28131a08784 100644 --- a/mozilla/content/html/style/src/nsDOMCSSDeclaration.cpp +++ b/mozilla/content/html/style/src/nsDOMCSSDeclaration.cpp @@ -247,7 +247,7 @@ nsDOMCSSDeclaration::SetProperty(const nsString& aPropertyName, declString.Append(aValue); declString.Append(aPriority); - return ParseDeclaration(declString); + return ParseDeclaration(declString, PR_TRUE, PR_FALSE); } NS_IMETHODIMP diff --git a/mozilla/content/html/style/src/nsDOMCSSDeclaration.h b/mozilla/content/html/style/src/nsDOMCSSDeclaration.h index 167242c1c39..7f51d0bbe0b 100644 --- a/mozilla/content/html/style/src/nsDOMCSSDeclaration.h +++ b/mozilla/content/html/style/src/nsDOMCSSDeclaration.h @@ -64,8 +64,12 @@ public: virtual void DropReference() = 0; virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate) = 0; + // Note! This will only set the declaration if a style rule already exists + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl) = 0; - virtual nsresult ParseDeclaration(const nsString& aDecl) = 0; + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) = 0; virtual nsresult GetParent(nsISupports **aParent) = 0; protected: diff --git a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp index 4c3619bfcac..3f1726d4ed1 100644 --- a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp @@ -114,7 +114,10 @@ public: virtual void DropReference(); virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate); - virtual nsresult ParseDeclaration(const nsString& aDecl); + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl); + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl); virtual nsresult GetParent(nsISupports **aParent); protected: @@ -229,8 +232,34 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(nsICSSDeclaration **aDecl, return result; } +nsresult +nsDOMCSSAttributeDeclaration::SetCSSDeclaration(nsICSSDeclaration *aDecl) +{ + nsHTMLValue val; + nsIStyleRule* rule; + nsICSSStyleRule* cssRule; + nsresult result = NS_OK; + + if (nsnull != mContent) { + mContent->GetHTMLAttribute(nsHTMLAtoms::style, val); + if (eHTMLUnit_ISupports == val.GetUnit()) { + rule = (nsIStyleRule*) val.GetISupportsValue(); + result = rule->QueryInterface(kICSSStyleRuleIID, (void**)&cssRule); + if (NS_OK == result) { + cssRule->SetDeclaration(aDecl); + NS_RELEASE(cssRule); + } + NS_RELEASE(rule); + } + } + + return result; +} + nsresult -nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl) +nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) { nsICSSDeclaration *decl; nsresult result = GetCSSDeclaration(&decl, PR_TRUE); @@ -265,9 +294,34 @@ nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsString& aDecl) if (doc) { doc->BeginUpdate(); } - result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, &hint); + nsCOMPtr declClone; + decl->Clone(*getter_AddRefs(declClone)); + + if (aClearOldDecl) { + // This should be done with decl->Clear() once such a method exists. + nsAutoString propName; + PRUint32 count, i; + + decl->Count(&count); + + for (i = 0; i < count; i++) { + decl->GetNthProperty(0, propName); + + nsCSSProperty prop = nsCSSProps::LookupProperty(propName); + nsCSSValue val; + + decl->RemoveProperty(prop, val); + } + } + + result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, + aParseOnlyOneDecl, &hint); + if (result == NS_CSS_PARSER_DROP_DECLARATION) { + SetCSSDeclaration(declClone); + result = NS_OK; + } if (doc) { - if (NS_SUCCEEDED(result)) { + if (NS_SUCCEEDED(result) && result != NS_CSS_PARSER_DROP_DECLARATION) { doc->AttributeChanged(mContent, kNameSpaceID_None, nsHTMLAtoms::style, hint); } doc->EndUpdate(); diff --git a/mozilla/layout/html/style/public/nsICSSParser.h b/mozilla/layout/html/style/public/nsICSSParser.h index 3b0241e18fc..349cb71529b 100644 --- a/mozilla/layout/html/style/public/nsICSSParser.h +++ b/mozilla/layout/html/style/public/nsICSSParser.h @@ -72,6 +72,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) = 0; // Charset management method: @@ -92,6 +93,10 @@ public: #define NS_CSS_GETINFO_CSS2 ((PRUint32) 0x00000004L) #define NS_CSS_GETINFO_CSS_FROSTING ((PRUint32) 0x00000008L) +// Success code that can be returned from ParseAndAppendDeclaration() +#define NS_CSS_PARSER_DROP_DECLARATION \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) + extern NS_HTML nsresult NS_NewCSSParser(nsICSSParser** aInstancePtrResult); diff --git a/mozilla/layout/html/style/src/nsCSSParser.cpp b/mozilla/layout/html/style/src/nsCSSParser.cpp index a95e6183363..04ce62c183a 100644 --- a/mozilla/layout/html/style/src/nsCSSParser.cpp +++ b/mozilla/layout/html/style/src/nsCSSParser.cpp @@ -55,9 +55,6 @@ static NS_DEFINE_IID(kICSSParserIID, NS_ICSS_PARSER_IID); static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); -#define NS_CSS_PARSER_DROP_DECLARATION \ - NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) - MOZ_DECL_CTOR_COUNTER(SelectorList); @@ -149,6 +146,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint); NS_IMETHOD GetCharset(/*out*/nsString &aCharsetDest) const; @@ -555,6 +553,7 @@ NS_IMETHODIMP CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) { // NS_ASSERTION(nsnull != aBaseURL, "need base URL"); @@ -581,15 +580,26 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, PRInt32 hint = NS_STYLE_HINT_NONE; - if (! ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { - hint = NS_STYLE_HINT_NONE; - } if (nsnull != aHint) { *aHint = hint; } + do { + if (ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { + if (aHint && hint > *aHint) { + *aHint = hint; + } + } else { + if (errorCode != -1) { // -1 means EOF so we ignore that + rv = errorCode; + } + + break; + } + } while (!aParseOnlyOneDecl); + ReleaseScanner(); - return NS_OK; + return rv; } //---------------------------------------------------------------------- diff --git a/mozilla/layout/html/style/src/nsCSSStyleRule.cpp b/mozilla/layout/html/style/src/nsCSSStyleRule.cpp index 15d31bcd17e..e6f76eb14e0 100644 --- a/mozilla/layout/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/layout/html/style/src/nsCSSStyleRule.cpp @@ -793,7 +793,10 @@ public: virtual void DropReference(void); virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate); - virtual nsresult ParseDeclaration(const nsString& aDecl); + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl); + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl); virtual nsresult GetParent(nsISupports **aParent); protected: @@ -865,8 +868,20 @@ DOMCSSDeclarationImpl::GetCSSDeclaration(nsICSSDeclaration **aDecl, return NS_OK; } +nsresult +DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl) +{ + if (nsnull != mRule) { + mRule->SetDeclaration(aDecl); + } + + return NS_OK; +} + nsresult -DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) +DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) { nsICSSDeclaration *decl; nsresult result = GetCSSDeclaration(&decl, PR_TRUE); @@ -904,9 +919,35 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) } if (NS_SUCCEEDED(result)) { + nsCOMPtr declClone; + decl->Clone(*getter_AddRefs(declClone)); + NS_ENSURE_TRUE(declClone, NS_ERROR_OUT_OF_MEMORY); + + if (aClearOldDecl) { + // This should be done with decl->Clear() once such a method exists. + nsAutoString propName; + PRUint32 count, i; + + decl->Count(&count); + + for (i = 0; i < count; i++) { + decl->GetNthProperty(0, propName); + + nsCSSProperty prop = nsCSSProps::LookupProperty(propName); + nsCSSValue val; + + decl->RemoveProperty(prop, val); + } + } + PRInt32 hint; - result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, &hint); - if (NS_SUCCEEDED(result)) { + result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, + aParseOnlyOneDecl, &hint); + + if (result == NS_CSS_PARSER_DROP_DECLARATION) { + SetCSSDeclaration(declClone); + result = NS_OK; + } else if (NS_SUCCEEDED(result)) { if (cssSheet) { cssSheet->SetModified(PR_TRUE); } diff --git a/mozilla/layout/html/style/src/nsDOMCSSDeclaration.cpp b/mozilla/layout/html/style/src/nsDOMCSSDeclaration.cpp index 091a24a46ca..28131a08784 100644 --- a/mozilla/layout/html/style/src/nsDOMCSSDeclaration.cpp +++ b/mozilla/layout/html/style/src/nsDOMCSSDeclaration.cpp @@ -247,7 +247,7 @@ nsDOMCSSDeclaration::SetProperty(const nsString& aPropertyName, declString.Append(aValue); declString.Append(aPriority); - return ParseDeclaration(declString); + return ParseDeclaration(declString, PR_TRUE, PR_FALSE); } NS_IMETHODIMP diff --git a/mozilla/layout/html/style/src/nsDOMCSSDeclaration.h b/mozilla/layout/html/style/src/nsDOMCSSDeclaration.h index 167242c1c39..7f51d0bbe0b 100644 --- a/mozilla/layout/html/style/src/nsDOMCSSDeclaration.h +++ b/mozilla/layout/html/style/src/nsDOMCSSDeclaration.h @@ -64,8 +64,12 @@ public: virtual void DropReference() = 0; virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate) = 0; + // Note! This will only set the declaration if a style rule already exists + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl) = 0; - virtual nsresult ParseDeclaration(const nsString& aDecl) = 0; + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) = 0; virtual nsresult GetParent(nsISupports **aParent) = 0; protected: diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index a95e6183363..04ce62c183a 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -55,9 +55,6 @@ static NS_DEFINE_IID(kICSSParserIID, NS_ICSS_PARSER_IID); static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); -#define NS_CSS_PARSER_DROP_DECLARATION \ - NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) - MOZ_DECL_CTOR_COUNTER(SelectorList); @@ -149,6 +146,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint); NS_IMETHOD GetCharset(/*out*/nsString &aCharsetDest) const; @@ -555,6 +553,7 @@ NS_IMETHODIMP CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) { // NS_ASSERTION(nsnull != aBaseURL, "need base URL"); @@ -581,15 +580,26 @@ CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, PRInt32 hint = NS_STYLE_HINT_NONE; - if (! ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { - hint = NS_STYLE_HINT_NONE; - } if (nsnull != aHint) { *aHint = hint; } + do { + if (ParseDeclaration(errorCode, aDeclaration, PR_FALSE, hint)) { + if (aHint && hint > *aHint) { + *aHint = hint; + } + } else { + if (errorCode != -1) { // -1 means EOF so we ignore that + rv = errorCode; + } + + break; + } + } while (!aParseOnlyOneDecl); + ReleaseScanner(); - return NS_OK; + return rv; } //---------------------------------------------------------------------- diff --git a/mozilla/layout/style/nsCSSStyleRule.cpp b/mozilla/layout/style/nsCSSStyleRule.cpp index 15d31bcd17e..e6f76eb14e0 100644 --- a/mozilla/layout/style/nsCSSStyleRule.cpp +++ b/mozilla/layout/style/nsCSSStyleRule.cpp @@ -793,7 +793,10 @@ public: virtual void DropReference(void); virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate); - virtual nsresult ParseDeclaration(const nsString& aDecl); + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl); + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl); virtual nsresult GetParent(nsISupports **aParent); protected: @@ -865,8 +868,20 @@ DOMCSSDeclarationImpl::GetCSSDeclaration(nsICSSDeclaration **aDecl, return NS_OK; } +nsresult +DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl) +{ + if (nsnull != mRule) { + mRule->SetDeclaration(aDecl); + } + + return NS_OK; +} + nsresult -DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) +DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) { nsICSSDeclaration *decl; nsresult result = GetCSSDeclaration(&decl, PR_TRUE); @@ -904,9 +919,35 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsString& aDecl) } if (NS_SUCCEEDED(result)) { + nsCOMPtr declClone; + decl->Clone(*getter_AddRefs(declClone)); + NS_ENSURE_TRUE(declClone, NS_ERROR_OUT_OF_MEMORY); + + if (aClearOldDecl) { + // This should be done with decl->Clear() once such a method exists. + nsAutoString propName; + PRUint32 count, i; + + decl->Count(&count); + + for (i = 0; i < count; i++) { + decl->GetNthProperty(0, propName); + + nsCSSProperty prop = nsCSSProps::LookupProperty(propName); + nsCSSValue val; + + decl->RemoveProperty(prop, val); + } + } + PRInt32 hint; - result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, &hint); - if (NS_SUCCEEDED(result)) { + result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl, + aParseOnlyOneDecl, &hint); + + if (result == NS_CSS_PARSER_DROP_DECLARATION) { + SetCSSDeclaration(declClone); + result = NS_OK; + } else if (NS_SUCCEEDED(result)) { if (cssSheet) { cssSheet->SetModified(PR_TRUE); } diff --git a/mozilla/layout/style/nsDOMCSSDeclaration.cpp b/mozilla/layout/style/nsDOMCSSDeclaration.cpp index 091a24a46ca..28131a08784 100644 --- a/mozilla/layout/style/nsDOMCSSDeclaration.cpp +++ b/mozilla/layout/style/nsDOMCSSDeclaration.cpp @@ -247,7 +247,7 @@ nsDOMCSSDeclaration::SetProperty(const nsString& aPropertyName, declString.Append(aValue); declString.Append(aPriority); - return ParseDeclaration(declString); + return ParseDeclaration(declString, PR_TRUE, PR_FALSE); } NS_IMETHODIMP diff --git a/mozilla/layout/style/nsDOMCSSDeclaration.h b/mozilla/layout/style/nsDOMCSSDeclaration.h index 167242c1c39..7f51d0bbe0b 100644 --- a/mozilla/layout/style/nsDOMCSSDeclaration.h +++ b/mozilla/layout/style/nsDOMCSSDeclaration.h @@ -64,8 +64,12 @@ public: virtual void DropReference() = 0; virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl, PRBool aAllocate) = 0; + // Note! This will only set the declaration if a style rule already exists + virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl) = 0; - virtual nsresult ParseDeclaration(const nsString& aDecl) = 0; + virtual nsresult ParseDeclaration(const nsString& aDecl, + PRBool aParseOnlyOneDecl, + PRBool aClearOldDecl) = 0; virtual nsresult GetParent(nsISupports **aParent) = 0; protected: diff --git a/mozilla/layout/style/nsICSSParser.h b/mozilla/layout/style/nsICSSParser.h index 3b0241e18fc..349cb71529b 100644 --- a/mozilla/layout/style/nsICSSParser.h +++ b/mozilla/layout/style/nsICSSParser.h @@ -72,6 +72,7 @@ public: NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, nsIURI* aBaseURL, nsICSSDeclaration* aDeclaration, + PRBool aParseOnlyOneDecl, PRInt32* aHint) = 0; // Charset management method: @@ -92,6 +93,10 @@ public: #define NS_CSS_GETINFO_CSS2 ((PRUint32) 0x00000004L) #define NS_CSS_GETINFO_CSS_FROSTING ((PRUint32) 0x00000008L) +// Success code that can be returned from ParseAndAppendDeclaration() +#define NS_CSS_PARSER_DROP_DECLARATION \ + NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_LAYOUT,1) + extern NS_HTML nsresult NS_NewCSSParser(nsICSSParser** aInstancePtrResult);