From ae2d56cabcc2519547363a4d43882d79ebd30bec Mon Sep 17 00:00:00 2001 From: "vidur%netscape.com" Date: Fri, 25 Sep 1998 00:51:45 +0000 Subject: [PATCH] Added new style interfaces. Implemented getStyle() on HTMLElement. Moved DOM fields into side struct for nsGenericHTMLElement. Implemented style declaration interface on proxy. Added new entry point to CSSParser and new methods to style declaration. git-svn-id: svn://10.0.0.236/trunk@11002 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/html/content/src/makefile.win | 2 + .../html/content/src/nsGenericHTMLElement.cpp | 174 +- .../html/content/src/nsGenericHTMLElement.h | 34 +- .../html/document/src/nsHTMLDocument.cpp | 18 +- .../content/html/style/public/nsICSSParser.h | 6 + .../html/style/src/nsCSSDeclaration.cpp | 264 ++- .../content/html/style/src/nsCSSParser.cpp | 38 + .../content/html/style/src/nsCSSStruct.cpp | 264 ++- .../html/style/src/nsICSSDeclaration.h | 8 + .../layout/generic/nsHTMLContainerFrame.cpp | 15 + mozilla/layout/generic/nsHTMLContainerFrame.h | 5 + mozilla/layout/generic/nsInlineFrame.cpp | 7 + .../html/base/src/nsHTMLContainerFrame.cpp | 15 + .../html/base/src/nsHTMLContainerFrame.h | 5 + .../layout/html/base/src/nsHTMLTagContent.cpp | 1791 +++++++++++++++++ .../layout/html/base/src/nsInlineFrame.cpp | 7 + mozilla/layout/html/content/src/Makefile | 1 + mozilla/layout/html/content/src/makefile.win | 2 + .../content/src/nsDOMStyleDeclaration.cpp | 1741 ++++++++++++++++ .../html/content/src/nsDOMStyleDeclaration.h | 53 + .../html/content/src/nsGenericHTMLElement.cpp | 174 +- .../html/content/src/nsGenericHTMLElement.h | 34 +- .../html/document/src/nsHTMLDocument.cpp | 18 +- .../layout/html/style/public/nsICSSParser.h | 6 + .../html/style/src/nsCSSDeclaration.cpp | 264 ++- mozilla/layout/html/style/src/nsCSSParser.cpp | 38 + .../layout/html/style/src/nsICSSDeclaration.h | 8 + mozilla/layout/style/nsCSSDeclaration.cpp | 264 ++- mozilla/layout/style/nsCSSParser.cpp | 38 + mozilla/layout/style/nsCSSStruct.cpp | 264 ++- mozilla/layout/style/nsICSSParser.h | 6 + 31 files changed, 4919 insertions(+), 645 deletions(-) create mode 100644 mozilla/layout/html/base/src/nsHTMLTagContent.cpp create mode 100644 mozilla/layout/html/content/src/nsDOMStyleDeclaration.cpp create mode 100644 mozilla/layout/html/content/src/nsDOMStyleDeclaration.h diff --git a/mozilla/content/html/content/src/makefile.win b/mozilla/content/html/content/src/makefile.win index 47ab2f2c65a..a72823fcf12 100644 --- a/mozilla/content/html/content/src/makefile.win +++ b/mozilla/content/html/content/src/makefile.win @@ -24,6 +24,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsCommentNode.cpp \ + nsDOMStyleDeclaration.cpp \ nsGenericDOMDataNode.cpp \ nsGenericHTMLElement.cpp \ nsHTMLAnchorElement.cpp \ @@ -90,6 +91,7 @@ CPPSRCS= \ CPP_OBJS= \ .\$(OBJDIR)\nsCommentNode.obj \ + .\$(OBJDIR)\nsDOMStyleDeclaration.obj \ .\$(OBJDIR)\nsGenericDOMDataNode.obj \ .\$(OBJDIR)\nsGenericHTMLElement.obj \ .\$(OBJDIR)\nsHTMLAnchorElement.obj \ diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index e9e99b00ed6..b8c125b256c 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -59,7 +59,10 @@ #include "nsDOMCID.h" #include "nsIServiceManager.h" #include "nsIDOMScriptObjectFactory.h" +#include "nsIDOMCSSStyleDeclaration.h" +#include "nsDOMStyleDeclaration.h" #include "prprf.h" +#include "prmem.h" // XXX todo: add in missing out-of-memory checks @@ -80,6 +83,7 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); +static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); // Attribute helper class used to wrap up an attribute with a dom // object that implements nsIDOMAttribute and nsIDOMNode and @@ -160,7 +164,7 @@ class nsChildContentList : public nsIDOMNodeList, public nsIScriptObjectOwner { public: - nsChildContentList(); + nsChildContentList(nsGenericHTMLContainerElement *aContent); virtual ~nsChildContentList() {} NS_DECL_ISUPPORTS @@ -171,24 +175,10 @@ public: // nsIDOMNodeList interface NS_DECL_IDOMNODELIST - // Methods stolen from nsVoidArray - PRInt32 Count() { return mArray.Count(); } - nsIContent* ElementAt(PRInt32 aIndex) const - { return (nsIContent*)mArray.ElementAt(aIndex); } - PRBool InsertElementAt(nsIContent* aElement, PRInt32 aIndex) - { return mArray.InsertElementAt(aElement, aIndex); } - PRBool ReplaceElementAt(nsIContent* aElement, PRInt32 aIndex) - { return mArray.ReplaceElementAt(aElement, aIndex); } - PRBool AppendElement(nsIContent* aElement) - { return mArray.AppendElement(aElement); } - PRBool RemoveElementAt(PRInt32 aIndex) - { return mArray.RemoveElementAt(aIndex); } - PRInt32 IndexOf(nsIContent* aPossibleElement) const - { return mArray.IndexOf(aPossibleElement); } - void Compact() { mArray.Compact(); } + void DropContent(); private: - nsVoidArray mArray; + nsGenericHTMLContainerElement *mContent; void *mScriptObject; }; @@ -638,7 +628,7 @@ nsGenericHTMLElement::nsGenericHTMLElement() mAttributes = nsnull; mTag = nsnull; mContent = nsnull; - mScriptObject = nsnull; + mDOMSlots = nsnull; mListenerManager = nsnull; } @@ -649,7 +639,31 @@ nsGenericHTMLElement::~nsGenericHTMLElement() } NS_IF_RELEASE(mTag); NS_IF_RELEASE(mListenerManager); - // XXX what about mScriptObject? it's now safe to GC it... + if (nsnull != mDOMSlots) { + if (nsnull != mDOMSlots->mChildNodes) { + mDOMSlots->mChildNodes->DropContent(); + NS_RELEASE(mDOMSlots->mChildNodes); + } + if (nsnull != mDOMSlots->mStyle) { + mDOMSlots->mStyle->DropContent(); + NS_RELEASE(mDOMSlots->mStyle); + } + // XXX Should really be arena managed + PR_DELETE(mDOMSlots); + } +} + +nsDOMSlots * +nsGenericHTMLElement::GetDOMSlots() +{ + if (nsnull == mDOMSlots) { + mDOMSlots = PR_NEW(nsDOMSlots); + mDOMSlots->mScriptObject = nsnull; + mDOMSlots->mChildNodes = nsnull; + mDOMSlots->mStyle = nsnull; + } + + return mDOMSlots; } void @@ -933,6 +947,26 @@ nsGenericHTMLElement::SetClassName(const nsString& aClassName) return NS_OK; } +nsresult +nsGenericHTMLElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) +{ + nsresult res = NS_OK; + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mStyle) { + slots->mStyle = new nsDOMStyleDeclaration(mContent); + if (nsnull == slots->mStyle) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(slots->mStyle); + } + + res = slots->mStyle->QueryInterface(kIDOMCSSStyleDeclarationIID, + (void **)aStyle); + + return res; +} + nsresult nsGenericHTMLElement::GetDocument(nsIDocument*& aResult) const { @@ -1655,7 +1689,9 @@ nsGenericHTMLElement::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject) { nsresult res = NS_OK; - if (nsnull == mScriptObject) { + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mScriptObject) { nsIDOMScriptObjectFactory *factory; res = GetScriptObjectFactory(&factory); @@ -1666,17 +1702,19 @@ nsGenericHTMLElement::GetScriptObject(nsIScriptContext* aContext, nsAutoString tag; mTag->ToString(tag); res = factory->NewScriptElement(tag, aContext, mContent, - mParent, (void**)&mScriptObject); + mParent, (void**)&slots->mScriptObject); NS_RELEASE(factory); } - *aScriptObject = mScriptObject; + *aScriptObject = slots->mScriptObject; return res; } nsresult nsGenericHTMLElement::SetScriptObject(void *aScriptObject) { - mScriptObject = aScriptObject; + nsDOMSlots *slots = GetDOMSlots(); + + slots->mScriptObject = aScriptObject; return NS_OK; } @@ -2680,6 +2718,20 @@ nsGenericHTMLLeafElement::Equals(nsIDOMNode* aNode, PRBool aDeep, return NS_OK; } +nsresult +nsGenericHTMLLeafElement::GetChildNodes(nsIDOMNodeList** aChildNodes) +{ + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mChildNodes) { + slots->mChildNodes = new nsChildContentList(nsnull); + NS_ADDREF(slots->mChildNodes); + } + + return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); +} + + nsresult nsGenericHTMLLeafElement::BeginConvertToXIF(nsXIFConverter& aConverter) const { @@ -2745,9 +2797,12 @@ nsGenericHTMLLeafElement::SizeOf(nsISizeOfHandler* aHandler) const //---------------------------------------------------------------------- -nsChildContentList::nsChildContentList() +nsChildContentList::nsChildContentList(nsGenericHTMLContainerElement *aContent) { NS_INIT_REFCNT(); + // This reference is not reference-counted. The content + // object tells us when its about to go away. + mContent = aContent; mScriptObject = nsnull; } @@ -2787,7 +2842,7 @@ nsChildContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptOb { nsresult res = NS_OK; if (nsnull == mScriptObject) { - res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, nsnull, (void**)&mScriptObject); + res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, mContent, (void**)&mScriptObject); } *aScriptObject = mScriptObject; return res; @@ -2803,7 +2858,14 @@ nsChildContentList::SetScriptObject(void *aScriptObject) NS_IMETHODIMP nsChildContentList::GetLength(PRUint32* aLength) { - *aLength = (PRUint32)mArray.Count(); + if (nsnull != mContent) { + PRInt32 length; + mContent->ChildCount(length); + *aLength = (PRUint32)length; + } + else { + *aLength = 0; + } return NS_OK; } @@ -2813,9 +2875,14 @@ nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) nsIContent *content; nsresult res = NS_OK; - content = (nsIContent *)mArray.ElementAt(aIndex); - if (nsnull != content) { - res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + if (nsnull != mContent) { + mContent->ChildAt(aIndex, content); + if (nsnull != content) { + res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + } + else { + *aReturn = nsnull; + } } else { *aReturn = nsnull; @@ -2824,23 +2891,25 @@ nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) return res; } +void +nsChildContentList::DropContent() +{ + mContent = nsnull; +} //---------------------------------------------------------------------- nsGenericHTMLContainerElement::nsGenericHTMLContainerElement() { - mChildren = new nsChildContentList(); - mChildren->AddRef(); } nsGenericHTMLContainerElement::~nsGenericHTMLContainerElement() { - PRInt32 n = mChildren->Count(); + PRInt32 n = mChildren.Count(); for (PRInt32 i = 0; i < n; i++) { - nsIContent* kid = mChildren->ElementAt(i); + nsIContent* kid = (nsIContent *)mChildren.ElementAt(i); NS_RELEASE(kid); } - mChildren->Release(); } nsresult @@ -2866,13 +2935,20 @@ nsGenericHTMLContainerElement::Equals(nsIDOMNode* aNode, PRBool aDeep, nsresult nsGenericHTMLContainerElement::GetChildNodes(nsIDOMNodeList** aChildNodes) { - return mChildren->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mChildNodes) { + slots->mChildNodes = new nsChildContentList(this); + NS_ADDREF(slots->mChildNodes); + } + + return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); } nsresult nsGenericHTMLContainerElement::GetHasChildNodes(PRBool* aReturn) { - if (0 != mChildren->Count()) { + if (0 != mChildren.Count()) { *aReturn = PR_TRUE; } else { @@ -2884,7 +2960,7 @@ nsGenericHTMLContainerElement::GetHasChildNodes(PRBool* aReturn) nsresult nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) { - nsIContent *child = mChildren->ElementAt(0); + nsIContent *child = (nsIContent *)mChildren.ElementAt(0); if (nsnull != child) { nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node @@ -2897,7 +2973,7 @@ nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) nsresult nsGenericHTMLContainerElement::GetLastChild(nsIDOMNode** aNode) { - nsIContent *child = mChildren->ElementAt(mChildren->Count()-1); + nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); if (nsnull != child) { nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node @@ -3094,7 +3170,7 @@ nsGenericHTMLContainerElement::FinishConvertToXIF(nsXIFConverter& aConverter) co nsresult nsGenericHTMLContainerElement::Compact() { - mChildren->Compact(); + mChildren.Compact(); return NS_OK; } @@ -3108,7 +3184,7 @@ nsGenericHTMLContainerElement::CanContainChildren(PRBool& aResult) const nsresult nsGenericHTMLContainerElement::ChildCount(PRInt32& aCount) const { - aCount = mChildren->Count(); + aCount = mChildren.Count(); return NS_OK; } @@ -3116,7 +3192,7 @@ nsresult nsGenericHTMLContainerElement::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { - nsIContent *child = mChildren->ElementAt(aIndex); + nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex); if (nsnull != child) { NS_ADDREF(child); } @@ -3129,7 +3205,7 @@ nsGenericHTMLContainerElement::IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const { NS_PRECONDITION(nsnull != aPossibleChild, "null ptr"); - aIndex = mChildren->IndexOf(aPossibleChild); + aIndex = mChildren.IndexOf(aPossibleChild); return NS_OK; } @@ -3139,7 +3215,7 @@ nsGenericHTMLContainerElement::InsertChildAt(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION(nsnull != aKid, "null ptr"); - PRBool rv = mChildren->InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/ + PRBool rv = mChildren.InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/ if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3160,8 +3236,8 @@ nsGenericHTMLContainerElement::ReplaceChildAt(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION(nsnull != aKid, "null ptr"); - nsIContent* oldKid = mChildren->ElementAt(aIndex); - PRBool rv = mChildren->ReplaceElementAt(aKid, aIndex); + nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); + PRBool rv = mChildren.ReplaceElementAt(aKid, aIndex); if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3183,7 +3259,7 @@ nsresult nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION((nsnull != aKid) && (aKid != mContent), "null ptr"); - PRBool rv = mChildren->AppendElement(aKid); + PRBool rv = mChildren.AppendElement(aKid); if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3191,7 +3267,7 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) if (nsnull != doc) { aKid->SetDocument(doc); if (aNotify) { - doc->ContentAppended(mContent, mChildren->Count() - 1); + doc->ContentAppended(mContent, mChildren.Count() - 1); } } } @@ -3201,10 +3277,10 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) nsresult nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { - nsIContent* oldKid = mChildren->ElementAt(aIndex); + nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); if (nsnull != oldKid ) { nsIDocument* doc = mDocument; - PRBool rv = mChildren->RemoveElementAt(aIndex); + PRBool rv = mChildren.RemoveElementAt(aIndex); if (aNotify) { if (nsnull != doc) { doc->ContentRemoved(mContent, oldKid, aIndex); diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.h b/mozilla/content/html/content/src/nsGenericHTMLElement.h index 6eaa886f9a2..693510e0771 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.h +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.h @@ -47,6 +47,20 @@ class nsIStyleRule; class nsISupportsArray; class nsIDOMScriptObjectFactory; class nsChildContentList; +class nsDOMStyleDeclaration; + + +// There are a set of DOM- and scripting-specific instance variables +// that may only be instantiated when a content object is accessed +// through the DOM. Rather than burn actual slots in the content +// objects for each of these instance variables, we put them off +// in a side structure that's only allocated when the content is +// accessed through the DOM. +typedef struct { + void *mScriptObject; + nsChildContentList *mChildNodes; + nsDOMStyleDeclaration *mStyle; +} nsDOMSlots; class nsGenericHTMLElement : public nsIJSScriptObject { public: @@ -89,6 +103,7 @@ public: nsresult SetDir(const nsString& aDir); nsresult GetClassName(nsString& aClassName); nsresult SetClassName(const nsString& aClassName); + nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle); // nsIDOMEventReceiver interface nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); @@ -152,7 +167,10 @@ public: virtual void Finalize(JSContext *aContext); // Implementation for nsISupports - NS_DECL_ISUPPORTS + NS_IMETHOD QueryInterface(REFNSIID aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); //---------------------------------------- @@ -289,6 +307,8 @@ public: static nsIDOMScriptObjectFactory *gScriptObjectFactory; + nsDOMSlots *GetDOMSlots(); + // Up pointer to the real content object that we are // supporting. Sometimes there is work that we just can't do // ourselves, so this is needed to ask the real object to do the @@ -299,8 +319,8 @@ public: nsIContent* mParent; nsIHTMLAttributes* mAttributes; nsIAtom* mTag; - void* mScriptObject; nsIEventListenerManager* mListenerManager; + nsDOMSlots *mDOMSlots; }; //---------------------------------------------------------------------- @@ -315,10 +335,7 @@ public: // Remainder of nsIDOMHTMLElement (and nsIDOMNode) nsresult Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn); - nsresult GetChildNodes(nsIDOMNodeList** aChildNodes) { - *aChildNodes = nsnull; - return NS_OK; - } + nsresult GetChildNodes(nsIDOMNodeList** aChildNodes); nsresult GetHasChildNodes(PRBool* aHasChildNodes) { *aHasChildNodes = PR_FALSE; return NS_OK; @@ -422,7 +439,7 @@ public: nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify); nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify); - nsChildContentList *mChildren; + nsVoidArray mChildren; }; //---------------------------------------------------------------------- @@ -562,6 +579,9 @@ public: } \ NS_IMETHOD SetClassName(const nsString& aClassName) { \ return _g.SetClassName(aClassName); \ + } \ + NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) { \ + return _g.GetStyle(aStyle); \ } /** diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index ad359d96e12..11b8948c487 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -518,8 +518,8 @@ nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets) NS_ADDREF(mApplets); } - *aApplets = (nsIDOMHTMLCollection *)mImages; - NS_ADDREF(mImages); + *aApplets = (nsIDOMHTMLCollection *)mApplets; + NS_ADDREF(mApplets); return NS_OK; } @@ -829,8 +829,18 @@ nsHTMLDocument::GetLastModified(nsString& aLastModified) NS_IMETHODIMP nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds) { - //XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; + if (nsnull == mEmbeds) { + mEmbeds = new nsContentList(this, "EMBED"); + if (nsnull == mEmbeds) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mEmbeds); + } + + *aEmbeds = (nsIDOMHTMLCollection *)mEmbeds; + NS_ADDREF(mEmbeds); + + return NS_OK; } NS_IMETHODIMP diff --git a/mozilla/content/html/style/public/nsICSSParser.h b/mozilla/content/html/style/public/nsICSSParser.h index b12e3eff839..1dfd596f1d5 100644 --- a/mozilla/content/html/style/public/nsICSSParser.h +++ b/mozilla/content/html/style/public/nsICSSParser.h @@ -25,6 +25,7 @@ class nsIStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; +class nsICSSDeclaration; #define NS_ICSS_PARSER_IID \ { 0xcc9c0610, 0x968c, 0x11d1, \ @@ -51,6 +52,11 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult) = 0; + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) = 0; + }; // Values or'd in the GetInfoMask; other bits are reserved diff --git a/mozilla/content/html/style/src/nsCSSDeclaration.cpp b/mozilla/content/html/style/src/nsCSSDeclaration.cpp index 4c6bfa05c43..5cfeaef158d 100644 --- a/mozilla/content/html/style/src/nsCSSDeclaration.cpp +++ b/mozilla/content/html/style/src/nsCSSDeclaration.cpp @@ -268,6 +268,118 @@ nsCSSValue::~nsCSSValue(void) Reset(); } +// XXX shouldn't this get moved to color code? +static const char* RGBToCSSString(nscolor aColor) +{ + const char* result = nsnull; + + PRInt32 r = NS_GET_R(aColor); + PRInt32 g = NS_GET_G(aColor); + PRInt32 b = NS_GET_B(aColor); + + PRInt32 index = 0; + PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); + CSSColorEntry* entry = nsnull; + + for (index = 0; index < count; index++) + { + entry = &css_rgb_table[index]; + if (entry->r == r) + { + if (entry->g == g && entry->b == b) + { + result = entry->name; + break; + } + } + else if (entry->r > r) + { + break; + } + } + return result; +} + + +void +nsCSSValue::ValueToString(nsString& aBuffer, const nsCSSValue& aValue, + PRInt32 aPropID) +{ + nsCSSUnit unit = aValue.GetUnit(); + + if (eCSSUnit_Null == unit) { + return; + } + + if (eCSSUnit_String == unit) { + nsAutoString buffer; + aValue.GetStringValue(buffer); + aBuffer.Append(buffer); + } + else if (eCSSUnit_Integer == unit) { + aBuffer.Append(aValue.GetIntValue(), 10); + } + else if (eCSSUnit_Enumerated == unit) { + const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); + if (name != nsnull) { + aBuffer.Append(name); + } + } + else if (eCSSUnit_Color == unit){ + nscolor color = aValue.GetColorValue(); + const char* name = RGBToCSSString(color); + + if (name != nsnull) + aBuffer.Append(name); + else + { + aBuffer.Append("rgb("); + aBuffer.Append(NS_GET_R(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_G(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_B(color), 10); + aBuffer.Append(')'); + } + } + else if (eCSSUnit_Percent == unit) { + aBuffer.Append(aValue.GetPercentValue() * 100.0f); + } + else if (eCSSUnit_Percent < unit) { // length unit + aBuffer.Append(aValue.GetFloatValue()); + } + + switch (unit) { + case eCSSUnit_Null: break; + case eCSSUnit_Auto: aBuffer.Append("auto"); break; + case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; + case eCSSUnit_None: aBuffer.Append("none"); break; + case eCSSUnit_Normal: aBuffer.Append("normal"); break; + case eCSSUnit_String: break; + case eCSSUnit_Integer: break; + case eCSSUnit_Enumerated: break; + case eCSSUnit_Color: break; + case eCSSUnit_Percent: aBuffer.Append("%"); break; + case eCSSUnit_Number: break; + case eCSSUnit_Inch: aBuffer.Append("in"); break; + case eCSSUnit_Foot: aBuffer.Append("ft"); break; + case eCSSUnit_Mile: aBuffer.Append("mi"); break; + case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; + case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; + case eCSSUnit_Meter: aBuffer.Append("m"); break; + case eCSSUnit_Kilometer: aBuffer.Append("km"); break; + case eCSSUnit_Point: aBuffer.Append("pt"); break; + case eCSSUnit_Pica: aBuffer.Append("pc"); break; + case eCSSUnit_Didot: aBuffer.Append("dt"); break; + case eCSSUnit_Cicero: aBuffer.Append("cc"); break; + case eCSSUnit_EM: aBuffer.Append("em"); break; + case eCSSUnit_EN: aBuffer.Append("en"); break; + case eCSSUnit_XHeight: aBuffer.Append("ex"); break; + case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; + case eCSSUnit_Pixel: aBuffer.Append("px"); break; + } +} + nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); @@ -772,7 +884,7 @@ void nsCSSList::List(FILE* out, PRInt32 aIndent) const class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); - + CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); @@ -791,10 +903,14 @@ public: nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); - + nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); + virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsresult Count(PRUint32* aCount); + nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); @@ -2211,115 +2327,25 @@ nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) return NS_OK; } -// XXX shouldn't this get moved to color code? -static const char* RGBToCSSString(nscolor aColor) +nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, + PRBool& aIsImportant) { - const char* result = nsnull; + nsCSSValue val; - PRInt32 r = NS_GET_R(aColor); - PRInt32 g = NS_GET_G(aColor); - PRInt32 b = NS_GET_B(aColor); - - PRInt32 index = 0; - PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); - CSSColorEntry* entry = nsnull; - - for (index = 0; index < count; index++) - { - entry = &css_rgb_table[index]; - if (entry->r == r) - { - if (entry->g == g && entry->b == b) - { - result = entry->name; - break; - } + if (nsnull != mImportant) { + mImportant->GetValue(aProperty, val); + if (eCSSUnit_Null != val.GetUnit()) { + aIsImportant = PR_TRUE; } - else if (entry->r > r) - { - break; + else { + aIsImportant = PR_FALSE; } } - return result; -} - - -static void -ValueToString(const nsCSSValue& aValue, PRInt32 aPropID, nsString& aBuffer) -{ - nsCSSUnit unit = aValue.GetUnit(); - - if (eCSSUnit_Null == unit) { - return; + else { + aIsImportant = PR_FALSE; } - if (eCSSUnit_String == unit) { - nsAutoString buffer; - aValue.GetStringValue(buffer); - aBuffer.Append(buffer); - } - else if (eCSSUnit_Integer == unit) { - aBuffer.Append(aValue.GetIntValue(), 10); - } - else if (eCSSUnit_Enumerated == unit) { - const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); - if (name != nsnull) { - aBuffer.Append(name); - } - } - else if (eCSSUnit_Color == unit){ - nscolor color = aValue.GetColorValue(); - const char* name = RGBToCSSString(color); - - if (name != nsnull) - aBuffer.Append(name); - else - { - aBuffer.Append("rgb("); - aBuffer.Append(NS_GET_R(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_G(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_B(color), 10); - aBuffer.Append(')'); - } - } - else if (eCSSUnit_Percent == unit) { - aBuffer.Append(aValue.GetPercentValue() * 100.0f); - } - else if (eCSSUnit_Percent < unit) { // length unit - aBuffer.Append(aValue.GetFloatValue()); - } - - switch (unit) { - case eCSSUnit_Null: break; - case eCSSUnit_Auto: aBuffer.Append("auto"); break; - case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; - case eCSSUnit_None: aBuffer.Append("none"); break; - case eCSSUnit_Normal: aBuffer.Append("normal"); break; - case eCSSUnit_String: break; - case eCSSUnit_Integer: break; - case eCSSUnit_Enumerated: break; - case eCSSUnit_Color: break; - case eCSSUnit_Percent: aBuffer.Append("%"); break; - case eCSSUnit_Number: break; - case eCSSUnit_Inch: aBuffer.Append("in"); break; - case eCSSUnit_Foot: aBuffer.Append("ft"); break; - case eCSSUnit_Mile: aBuffer.Append("mi"); break; - case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; - case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; - case eCSSUnit_Meter: aBuffer.Append("m"); break; - case eCSSUnit_Kilometer: aBuffer.Append("km"); break; - case eCSSUnit_Point: aBuffer.Append("pt"); break; - case eCSSUnit_Pica: aBuffer.Append("pc"); break; - case eCSSUnit_Didot: aBuffer.Append("dt"); break; - case eCSSUnit_Cicero: aBuffer.Append("cc"); break; - case eCSSUnit_EM: aBuffer.Append("em"); break; - case eCSSUnit_EN: aBuffer.Append("en"); break; - case eCSSUnit_XHeight: aBuffer.Append("ex"); break; - case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; - case eCSSUnit_Pixel: aBuffer.Append("px"); break; - } + return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) @@ -2347,7 +2373,7 @@ nsresult CSSDeclarationImpl::ToString(nsString& aString) } aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); - ValueToString(value, property, aString); + nsCSSValue::ValueToString(aString, value, property); if (PR_TRUE == important) { aString.Append(" ! important"); } @@ -2400,6 +2426,34 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +nsresult +CSSDeclarationImpl::Count(PRUint32* aCount) +{ + if (nsnull != mOrder) { + *aCount = (PRUint32)mOrder->Count(); + } + else { + *aCount = 0; + } + + return NS_OK; +} + +nsresult +CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) +{ + aReturn.SetLength(0); + if (nsnull != mOrder) { + PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); + if (0 <= property) { + aReturn.Append(nsCSSProps::kNameTable[property].name); + } + } + + return NS_OK; +} + + NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index 75f07413ca0..92cc83485a1 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -202,6 +202,10 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult); + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration); protected: PRBool GetToken(PRInt32* aErrorCode, PRBool aSkipWS); @@ -448,6 +452,40 @@ CSSParserImpl::ParseDeclarations(const nsString& aDeclaration, return NS_OK; } +NS_METHOD +CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) +{ + nsString* str = new nsString(aBuffer); + if (nsnull == str) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsIUnicharInputStream* input = nsnull; + nsresult rv = NS_NewStringUnicharInputStream(&input, str); + if (NS_OK != rv) { + return rv; + } + + mScanner = new nsCSSScanner(); + mScanner->Init(input); + NS_RELEASE(input); + + mURL = aBaseURL; + NS_IF_ADDREF(mURL); + + mInHead = PR_FALSE; + PRInt32 errorCode = NS_OK; + + ParseDeclaration(&errorCode, &aDeclaration, PR_FALSE); + + delete mScanner; + mScanner = nsnull; + NS_IF_RELEASE(mURL); + + return NS_OK; +} + //---------------------------------------------------------------------- PRBool CSSParserImpl::GetToken(PRInt32* aErrorCode, PRBool aSkipWS) diff --git a/mozilla/content/html/style/src/nsCSSStruct.cpp b/mozilla/content/html/style/src/nsCSSStruct.cpp index 4c6bfa05c43..5cfeaef158d 100644 --- a/mozilla/content/html/style/src/nsCSSStruct.cpp +++ b/mozilla/content/html/style/src/nsCSSStruct.cpp @@ -268,6 +268,118 @@ nsCSSValue::~nsCSSValue(void) Reset(); } +// XXX shouldn't this get moved to color code? +static const char* RGBToCSSString(nscolor aColor) +{ + const char* result = nsnull; + + PRInt32 r = NS_GET_R(aColor); + PRInt32 g = NS_GET_G(aColor); + PRInt32 b = NS_GET_B(aColor); + + PRInt32 index = 0; + PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); + CSSColorEntry* entry = nsnull; + + for (index = 0; index < count; index++) + { + entry = &css_rgb_table[index]; + if (entry->r == r) + { + if (entry->g == g && entry->b == b) + { + result = entry->name; + break; + } + } + else if (entry->r > r) + { + break; + } + } + return result; +} + + +void +nsCSSValue::ValueToString(nsString& aBuffer, const nsCSSValue& aValue, + PRInt32 aPropID) +{ + nsCSSUnit unit = aValue.GetUnit(); + + if (eCSSUnit_Null == unit) { + return; + } + + if (eCSSUnit_String == unit) { + nsAutoString buffer; + aValue.GetStringValue(buffer); + aBuffer.Append(buffer); + } + else if (eCSSUnit_Integer == unit) { + aBuffer.Append(aValue.GetIntValue(), 10); + } + else if (eCSSUnit_Enumerated == unit) { + const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); + if (name != nsnull) { + aBuffer.Append(name); + } + } + else if (eCSSUnit_Color == unit){ + nscolor color = aValue.GetColorValue(); + const char* name = RGBToCSSString(color); + + if (name != nsnull) + aBuffer.Append(name); + else + { + aBuffer.Append("rgb("); + aBuffer.Append(NS_GET_R(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_G(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_B(color), 10); + aBuffer.Append(')'); + } + } + else if (eCSSUnit_Percent == unit) { + aBuffer.Append(aValue.GetPercentValue() * 100.0f); + } + else if (eCSSUnit_Percent < unit) { // length unit + aBuffer.Append(aValue.GetFloatValue()); + } + + switch (unit) { + case eCSSUnit_Null: break; + case eCSSUnit_Auto: aBuffer.Append("auto"); break; + case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; + case eCSSUnit_None: aBuffer.Append("none"); break; + case eCSSUnit_Normal: aBuffer.Append("normal"); break; + case eCSSUnit_String: break; + case eCSSUnit_Integer: break; + case eCSSUnit_Enumerated: break; + case eCSSUnit_Color: break; + case eCSSUnit_Percent: aBuffer.Append("%"); break; + case eCSSUnit_Number: break; + case eCSSUnit_Inch: aBuffer.Append("in"); break; + case eCSSUnit_Foot: aBuffer.Append("ft"); break; + case eCSSUnit_Mile: aBuffer.Append("mi"); break; + case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; + case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; + case eCSSUnit_Meter: aBuffer.Append("m"); break; + case eCSSUnit_Kilometer: aBuffer.Append("km"); break; + case eCSSUnit_Point: aBuffer.Append("pt"); break; + case eCSSUnit_Pica: aBuffer.Append("pc"); break; + case eCSSUnit_Didot: aBuffer.Append("dt"); break; + case eCSSUnit_Cicero: aBuffer.Append("cc"); break; + case eCSSUnit_EM: aBuffer.Append("em"); break; + case eCSSUnit_EN: aBuffer.Append("en"); break; + case eCSSUnit_XHeight: aBuffer.Append("ex"); break; + case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; + case eCSSUnit_Pixel: aBuffer.Append("px"); break; + } +} + nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); @@ -772,7 +884,7 @@ void nsCSSList::List(FILE* out, PRInt32 aIndent) const class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); - + CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); @@ -791,10 +903,14 @@ public: nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); - + nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); + virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsresult Count(PRUint32* aCount); + nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); @@ -2211,115 +2327,25 @@ nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) return NS_OK; } -// XXX shouldn't this get moved to color code? -static const char* RGBToCSSString(nscolor aColor) +nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, + PRBool& aIsImportant) { - const char* result = nsnull; + nsCSSValue val; - PRInt32 r = NS_GET_R(aColor); - PRInt32 g = NS_GET_G(aColor); - PRInt32 b = NS_GET_B(aColor); - - PRInt32 index = 0; - PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); - CSSColorEntry* entry = nsnull; - - for (index = 0; index < count; index++) - { - entry = &css_rgb_table[index]; - if (entry->r == r) - { - if (entry->g == g && entry->b == b) - { - result = entry->name; - break; - } + if (nsnull != mImportant) { + mImportant->GetValue(aProperty, val); + if (eCSSUnit_Null != val.GetUnit()) { + aIsImportant = PR_TRUE; } - else if (entry->r > r) - { - break; + else { + aIsImportant = PR_FALSE; } } - return result; -} - - -static void -ValueToString(const nsCSSValue& aValue, PRInt32 aPropID, nsString& aBuffer) -{ - nsCSSUnit unit = aValue.GetUnit(); - - if (eCSSUnit_Null == unit) { - return; + else { + aIsImportant = PR_FALSE; } - if (eCSSUnit_String == unit) { - nsAutoString buffer; - aValue.GetStringValue(buffer); - aBuffer.Append(buffer); - } - else if (eCSSUnit_Integer == unit) { - aBuffer.Append(aValue.GetIntValue(), 10); - } - else if (eCSSUnit_Enumerated == unit) { - const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); - if (name != nsnull) { - aBuffer.Append(name); - } - } - else if (eCSSUnit_Color == unit){ - nscolor color = aValue.GetColorValue(); - const char* name = RGBToCSSString(color); - - if (name != nsnull) - aBuffer.Append(name); - else - { - aBuffer.Append("rgb("); - aBuffer.Append(NS_GET_R(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_G(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_B(color), 10); - aBuffer.Append(')'); - } - } - else if (eCSSUnit_Percent == unit) { - aBuffer.Append(aValue.GetPercentValue() * 100.0f); - } - else if (eCSSUnit_Percent < unit) { // length unit - aBuffer.Append(aValue.GetFloatValue()); - } - - switch (unit) { - case eCSSUnit_Null: break; - case eCSSUnit_Auto: aBuffer.Append("auto"); break; - case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; - case eCSSUnit_None: aBuffer.Append("none"); break; - case eCSSUnit_Normal: aBuffer.Append("normal"); break; - case eCSSUnit_String: break; - case eCSSUnit_Integer: break; - case eCSSUnit_Enumerated: break; - case eCSSUnit_Color: break; - case eCSSUnit_Percent: aBuffer.Append("%"); break; - case eCSSUnit_Number: break; - case eCSSUnit_Inch: aBuffer.Append("in"); break; - case eCSSUnit_Foot: aBuffer.Append("ft"); break; - case eCSSUnit_Mile: aBuffer.Append("mi"); break; - case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; - case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; - case eCSSUnit_Meter: aBuffer.Append("m"); break; - case eCSSUnit_Kilometer: aBuffer.Append("km"); break; - case eCSSUnit_Point: aBuffer.Append("pt"); break; - case eCSSUnit_Pica: aBuffer.Append("pc"); break; - case eCSSUnit_Didot: aBuffer.Append("dt"); break; - case eCSSUnit_Cicero: aBuffer.Append("cc"); break; - case eCSSUnit_EM: aBuffer.Append("em"); break; - case eCSSUnit_EN: aBuffer.Append("en"); break; - case eCSSUnit_XHeight: aBuffer.Append("ex"); break; - case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; - case eCSSUnit_Pixel: aBuffer.Append("px"); break; - } + return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) @@ -2347,7 +2373,7 @@ nsresult CSSDeclarationImpl::ToString(nsString& aString) } aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); - ValueToString(value, property, aString); + nsCSSValue::ValueToString(aString, value, property); if (PR_TRUE == important) { aString.Append(" ! important"); } @@ -2400,6 +2426,34 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +nsresult +CSSDeclarationImpl::Count(PRUint32* aCount) +{ + if (nsnull != mOrder) { + *aCount = (PRUint32)mOrder->Count(); + } + else { + *aCount = 0; + } + + return NS_OK; +} + +nsresult +CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) +{ + aReturn.SetLength(0); + if (nsnull != mOrder) { + PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); + if (0 <= property) { + aReturn.Append(nsCSSProps::kNameTable[property].name); + } + } + + return NS_OK; +} + + NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { diff --git a/mozilla/content/html/style/src/nsICSSDeclaration.h b/mozilla/content/html/style/src/nsICSSDeclaration.h index 646563e2fb5..255b79939f5 100644 --- a/mozilla/content/html/style/src/nsICSSDeclaration.h +++ b/mozilla/content/html/style/src/nsICSSDeclaration.h @@ -112,6 +112,10 @@ public: void SetNoneValue(void); void SetNormalValue(void); + static void ValueToString(nsString& aBuffer, + const nsCSSValue& aValue, + PRInt32 aPropID = -1); + // debugging methods void AppendToString(nsString& aBuffer, PRInt32 aPropID = -1) const; void ToString(nsString& aBuffer, PRInt32 aPropID = -1) const; @@ -326,6 +330,10 @@ public: virtual nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue) = 0; virtual nsresult GetImportantValues(nsICSSDeclaration*& aResult) = 0; + virtual nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant) = 0; + + virtual nsresult Count(PRUint32* aCount) = 0; + virtual nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn) = 0; virtual nsresult ToString(nsString& aString) = 0; diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.cpp b/mozilla/layout/generic/nsHTMLContainerFrame.cpp index 5b3922dd9c1..56b16efcf07 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/generic/nsHTMLContainerFrame.cpp @@ -478,6 +478,21 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, return NS_OK; } +NS_IMETHODIMP +nsHTMLContainerFrame::AttributeChanged(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute) +{ + if (nsHTMLAtoms::style == aAttribute) { + ApplyStyleChangeToTree(*aPresContext, this); + ApplyReflowChangeToTree(*aPresContext, this); + ApplyRenderingChangeToTree(*aPresContext, this); + } + + return NS_OK; +} + void nsHTMLContainerFrame::ApplyStyleChangeToTree(nsIPresContext& aPresContext, nsIFrame* aFrame) diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.h b/mozilla/layout/generic/nsHTMLContainerFrame.h index d83a2ef6b11..5ee163d1dfe 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.h +++ b/mozilla/layout/generic/nsHTMLContainerFrame.h @@ -47,6 +47,11 @@ public: nsIContent* aChild, PRInt32 aIndexInParent); + NS_IMETHOD AttributeChanged(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute); + nsresult WrapFrames(nsIPresContext& aPresContext, nsIFrame* aPrevFrame, nsIFrame* aFrame); diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index a20c9f78eb1..25cc288f53f 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -222,6 +222,13 @@ nsInlineFrame::AttributeChanged(nsIPresShell* aShell, nsIContent* aChild, nsIAtom* aAttribute) { + nsresult result = nsHTMLContainerFrame::AttributeChanged(aShell, + aPresContext, + aChild, + aAttribute); + if (NS_OK != result) { + return result; + } if (nsHTMLAtoms::color == aAttribute) { ApplyStyleChangeToTree(*aPresContext, this); ApplyRenderingChangeToTree(*aPresContext, this); diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp index 5b3922dd9c1..56b16efcf07 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -478,6 +478,21 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext& aPresContext, return NS_OK; } +NS_IMETHODIMP +nsHTMLContainerFrame::AttributeChanged(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute) +{ + if (nsHTMLAtoms::style == aAttribute) { + ApplyStyleChangeToTree(*aPresContext, this); + ApplyReflowChangeToTree(*aPresContext, this); + ApplyRenderingChangeToTree(*aPresContext, this); + } + + return NS_OK; +} + void nsHTMLContainerFrame::ApplyStyleChangeToTree(nsIPresContext& aPresContext, nsIFrame* aFrame) diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h index d83a2ef6b11..5ee163d1dfe 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h @@ -47,6 +47,11 @@ public: nsIContent* aChild, PRInt32 aIndexInParent); + NS_IMETHOD AttributeChanged(nsIPresShell* aShell, + nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute); + nsresult WrapFrames(nsIPresContext& aPresContext, nsIFrame* aPrevFrame, nsIFrame* aFrame); diff --git a/mozilla/layout/html/base/src/nsHTMLTagContent.cpp b/mozilla/layout/html/base/src/nsHTMLTagContent.cpp new file mode 100644 index 00000000000..491a474d6ea --- /dev/null +++ b/mozilla/layout/html/base/src/nsHTMLTagContent.cpp @@ -0,0 +1,1791 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#include "nsHTMLTagContent.h" +#include "nsIDocument.h" +#include "nsIHTMLAttributes.h" +#include "nsIHTMLStyleSheet.h" +#include "nsIHTMLDocument.h" +#include "nsIStyleRule.h" +#include "nsIStyleContext.h" +#include "nsIPresContext.h" +#include "nsHTMLAtoms.h" +#include "nsStyleConsts.h" +#include "nsString.h" +#include "prprf.h" +#include "nsDOMAttributes.h" +#include "nsIDOMDocument.h" +#include "nsILinkHandler.h" +#include "nsIPresContext.h" +#include "nsIURL.h" +#include "nsICSSParser.h" +#include "nsISupportsArray.h" +#include "nsXIFConverter.h" +#include "nsISizeOfHandler.h" +#include "nsIEventListenerManager.h" +#include "nsIEventStateManager.h" +#include "nsIScriptEventListener.h" +#include "nsIScriptContextOwner.h" +#include "nsIScriptGlobalObject.h" +#include "nsDOMEvent.h" +#include "nsDOMEventsIIDs.h" +#include "jsapi.h" + +#include "nsXIFConverter.h" + +static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); +static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); +static NS_DEFINE_IID(kIDOMHTMLElementIID, NS_IDOMHTMLELEMENT_IID); +static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID); +static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); +static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); +static NS_DEFINE_IID(kIScriptEventListenerIID, NS_ISCRIPTEVENTLISTENER_IID); +static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID); +static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); + + +/** + * Translate the content object into the (XIF) XML Interchange Format + * XIF is an intermediate form of the content model, the buffer + * will then be parsed into any number of formats including HTML, TXT, etc. + * These methods must be called in the following order: + + BeginConvertToXIF + ConvertContentToXIF + EndConvertToXIF + */ + +NS_IMETHODIMP +nsHTMLTagContent::BeginConvertToXIF(nsXIFConverter& aConverter) const +{ + if (nsnull != mTag) + { + nsAutoString name; + mTag->ToString(name); + + + PRBool isContainer; + CanContainChildren(isContainer); + if (!isContainer) + aConverter.BeginLeaf(name); + else + aConverter.BeginContainer(name); + } + + // Add all attributes to the convert + if (nsnull != mAttributes) + { + nsISupportsArray* attrs; + nsresult rv = NS_NewISupportsArray(&attrs); + if (NS_OK == rv) + { + PRInt32 i, n; + mAttributes->GetAllAttributeNames(attrs, n); + nsAutoString name, value; + for (i = 0; i < n; i++) + { + nsIAtom* atom = (nsIAtom*) attrs->ElementAt(i); + atom->ToString(name); + + value.Truncate(); + GetAttribute(name, value); + + aConverter.AddHTMLAttribute(name,value); + NS_RELEASE(atom); + } + NS_RELEASE(attrs); + } + } + return NS_OK; +} + + +NS_IMETHODIMP +nsHTMLTagContent::FinishConvertToXIF(nsXIFConverter& aConverter) const +{ + if (nsnull != mTag) + { + PRBool isContainer; + CanContainChildren(isContainer); + + nsAutoString name; + mTag->ToString(name); + + if (!isContainer) + aConverter.EndLeaf(name); + else + aConverter.EndContainer(name); + } + return NS_OK; +} + +/** + * Translate the content object into the (XIF) XML Interchange Format + * XIF is an intermediate form of the content model, the buffer + * will then be parsed into any number of formats including HTML, TXT, etc. + */ +NS_IMETHODIMP +nsHTMLTagContent::ConvertContentToXIF(nsXIFConverter& aConverter) const +{ + // Do nothing, all conversion is handled in the StartConvertToXIF and FinishConvertToXIF + return NS_OK; +} + + + +static nsresult EnsureWritableAttributes(nsIHTMLContent* aContent, + nsIHTMLAttributes*& aAttributes, PRBool aCreate) +{ + nsresult result = NS_OK; + + if (nsnull == aAttributes) { + if (PR_TRUE == aCreate) { + nsMapAttributesFunc mapFunc; + result = aContent->GetAttributeMappingFunction(mapFunc); + if (NS_OK == result) { + result = NS_NewHTMLAttributes(&aAttributes, mapFunc); + if (NS_OK == result) { + aAttributes->AddContentRef(); + } + } + } + } + else { + PRInt32 contentRefCount; + aAttributes->GetContentRefCount(contentRefCount); + if (1 < contentRefCount) { + nsIHTMLAttributes* attrs; + result = aAttributes->Clone(&attrs); + if (NS_OK == result) { + aAttributes->ReleaseContentRef(); + NS_RELEASE(aAttributes); + aAttributes = attrs; + aAttributes->AddContentRef(); + } + } + } + return result; +} + +static void ReleaseAttributes(nsIHTMLAttributes*& aAttributes) +{ + aAttributes->ReleaseContentRef(); + NS_RELEASE(aAttributes); +} + + +nsHTMLTagContent::nsHTMLTagContent() +{ +} + +nsHTMLTagContent::nsHTMLTagContent(nsIAtom* aTag) +{ + NS_PRECONDITION(nsnull != aTag, "null ptr"); + mTag = aTag; + NS_IF_ADDREF(mTag); +} + +nsHTMLTagContent::~nsHTMLTagContent() +{ + NS_IF_RELEASE(mTag); + if(nsnull != mAttributes) { + ReleaseAttributes(mAttributes); + } +} + +nsresult nsHTMLTagContent::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + nsresult res = nsHTMLContent::QueryInterface(aIID, aInstancePtr); + if (NS_NOINTERFACE == res) { + if (aIID.Equals(kIDOMElementIID)) { + *aInstancePtr = (void*)(nsIDOMElement*)(nsIDOMHTMLElement*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIDOMHTMLElementIID)) { + *aInstancePtr = (void*)(nsIDOMHTMLElement*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIJSScriptObjectIID)) { + *aInstancePtr = (void*)(nsIJSScriptObject*)this; + AddRef(); + return NS_OK; + } + } + + return res; +} + +nsrefcnt nsHTMLTagContent::AddRef(void) +{ + return nsHTMLContent::AddRef(); +} + +nsrefcnt nsHTMLTagContent::Release(void) +{ + return nsHTMLContent::Release(); +} + +NS_IMETHODIMP nsHTMLTagContent::GetTag(nsIAtom*& aResult) const +{ + NS_IF_ADDREF(mTag); + aResult = mTag; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SizeOf(nsISizeOfHandler* aHandler) const +{ + aHandler->Add(sizeof(*this)); + nsHTMLTagContent::SizeOfWithoutThis(aHandler); + return NS_OK; +} + +void +nsHTMLTagContent::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const +{ + if (!aHandler->HaveSeen(mTag)) { + mTag->SizeOf(aHandler); + } + if (!aHandler->HaveSeen(mAttributes)) { + mAttributes->SizeOf(aHandler); + } +} + +NS_IMETHODIMP +nsHTMLTagContent::ToHTMLString(nsString& aBuf) const +{ + aBuf.Truncate(0); + aBuf.Append('<'); + + nsIAtom* tag; + GetTag(tag); + if (nsnull != tag) { + nsAutoString tmp; + tag->ToString(tmp); + aBuf.Append(tmp); + } else { + aBuf.Append("?NULL"); + } + + if (nsnull != mAttributes) { + nsISupportsArray* attrs; + nsresult rv = NS_NewISupportsArray(&attrs); + if (NS_OK == rv) { + PRInt32 i, n; + mAttributes->GetAllAttributeNames(attrs, n); + nsAutoString name, value, quotedValue; + for (i = 0; i < n; i++) { + nsIAtom* atom = (nsIAtom*) attrs->ElementAt(i); + atom->ToString(name); + aBuf.Append(' '); + aBuf.Append(name); + value.Truncate(); + GetAttribute(name, value); + if (value.Length() > 0) { + aBuf.Append('='); + QuoteForHTML(value, quotedValue); + aBuf.Append(quotedValue); + } + NS_RELEASE(atom); + } + NS_RELEASE(attrs); + } + } + + aBuf.Append('>'); + return NS_OK; +} + +static nsIHTMLStyleSheet* GetAttrStyleSheet(nsIDocument* aDocument) +{ + nsIHTMLStyleSheet* sheet = nsnull; + nsIHTMLDocument* htmlDoc; + + if (nsnull != aDocument) { + if (NS_OK == aDocument->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc)) { + htmlDoc->GetAttributeStyleSheet(&sheet); + NS_RELEASE(htmlDoc); + } + } + NS_ASSERTION(nsnull != sheet, "can't get attribute style sheet"); + return sheet; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetDocument(nsIDocument* aDocument) +{ + nsresult rv = nsHTMLContent::SetDocument(aDocument); + if (NS_OK != rv) { + return rv; + } + + if (nsnull != mAttributes) { + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + sheet->SetAttributesFor(this, mAttributes); // sync attributes with sheet + NS_RELEASE(sheet); + } + } + return rv; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetAttribute(const nsString& aName, + const nsString& aValue, + PRBool aNotify) +{ + nsAutoString upper; + aName.ToUpperCase(upper); + nsIAtom* attr = NS_NewAtom(upper); + nsresult rv = SetAttribute(attr, aValue, aNotify); + NS_RELEASE(attr); + return rv; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttribute(nsIAtom *aAttribute, + nsString &aResult) const +{ + nsHTMLValue value; + nsresult result = GetAttribute(aAttribute, value); + + char cbuf[20]; + nscolor color; + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + // Try subclass conversion routine first + if (NS_CONTENT_ATTR_HAS_VALUE == AttributeToString(aAttribute, value, aResult)) { + return result; + } + + // Provide default conversions for most everything + switch (value.GetUnit()) { + case eHTMLUnit_Empty: + aResult.Truncate(); + break; + + case eHTMLUnit_String: + case eHTMLUnit_Null: + value.GetStringValue(aResult); + break; + + case eHTMLUnit_Integer: + aResult.Truncate(); + aResult.Append(value.GetIntValue(), 10); + break; + + case eHTMLUnit_Pixel: + aResult.Truncate(); + aResult.Append(value.GetPixelValue(), 10); + break; + + case eHTMLUnit_Percent: + aResult.Truncate(0); + aResult.Append(PRInt32(value.GetPercentValue() * 100.0f), 10); + aResult.Append('%'); + break; + + case eHTMLUnit_Color: + color = nscolor(value.GetColorValue()); + PR_snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x", + NS_GET_R(color), NS_GET_G(color), NS_GET_B(color)); + aResult.Truncate(0); + aResult.Append(cbuf); + break; + + default: + case eHTMLUnit_Enumerated: + NS_NOTREACHED("no default enumerated value to string conversion"); + result = NS_CONTENT_ATTR_NOT_THERE; + break; + } + } + + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttribute(const nsString& aName, + nsString& aResult) const +{ + nsAutoString upper; + aName.ToUpperCase(upper); + nsIAtom* attr = NS_NewAtom(upper); + nsresult result = GetAttribute(attr, aResult); + NS_RELEASE(attr); + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::AttributeToString(nsIAtom* aAttribute, + nsHTMLValue& aValue, + nsString& aResult) const +{ + if (nsHTMLAtoms::style == aAttribute) { + if (eHTMLUnit_ISupports == aValue.GetUnit()) { + nsIStyleRule* rule = (nsIStyleRule*) aValue.GetISupportsValue(); + // rule->ToString(str); + aResult = "XXX style rule ToString goes here"; + return NS_CONTENT_ATTR_HAS_VALUE; + } + } + aResult.Truncate(); + return NS_CONTENT_ATTR_NOT_THERE; +} + +// XXX temporary stub until this class is nuked +NS_IMETHODIMP +nsHTMLTagContent::StringToAttribute(nsIAtom* aAttribute, + const nsString& aValue, + nsHTMLValue& aResult) +{ + return NS_CONTENT_ATTR_NOT_THERE; +} + +nsresult +nsHTMLTagContent::AddScriptEventListener(nsIAtom* aAttribute, const nsString& aValue, REFNSIID aIID) +{ + nsresult mRet = NS_OK; + nsIScriptContext* mContext; + nsIScriptContextOwner* mOwner; + + NS_PRECONDITION(nsnull != mDocument, "Element not yet added to doc"); + + if (nsnull != mDocument) { + mOwner = mDocument->GetScriptContextOwner(); + if (NS_OK == mOwner->GetScriptContext(&mContext)) { + if (nsHTMLAtoms::body == mTag || nsHTMLAtoms::frameset == mTag) { + nsIDOMEventReceiver *mReceiver; + nsIScriptGlobalObject *mGlobal = mContext->GetGlobalObject(); + + if (nsnull != mGlobal && NS_OK == mGlobal->QueryInterface(kIDOMEventReceiverIID, (void**)&mReceiver)) { + nsIEventListenerManager *mManager; + if (NS_OK == mReceiver->GetListenerManager(&mManager)) { + nsIScriptObjectOwner *mObjectOwner; + if (NS_OK == mGlobal->QueryInterface(kIScriptObjectOwnerIID, (void**)&mObjectOwner)) { + mRet = mManager->AddScriptEventListener(mContext, mObjectOwner, aAttribute, aValue, aIID); + NS_RELEASE(mObjectOwner); + } + NS_RELEASE(mManager); + } + NS_RELEASE(mReceiver); + } + NS_IF_RELEASE(mGlobal); + } + else { + nsIEventListenerManager *mManager; + if (NS_OK == GetListenerManager(&mManager)) { + mRet = mManager->AddScriptEventListener(mContext, this, aAttribute, aValue, aIID); + NS_RELEASE(mManager); + } + } + NS_RELEASE(mContext); + } + NS_RELEASE(mOwner); + } + return mRet; +} + +// Note: Subclasses should override to parse the value string; in +// addition, when they see an unknown attribute they should call this +// so that global attributes are handled (like CLASS, ID, STYLE, etc.) +NS_IMETHODIMP +nsHTMLTagContent::SetAttribute(nsIAtom* aAttribute, + const nsString& aValue, + PRBool aNotify) +{ + nsresult result = NS_OK; + if (nsHTMLAtoms::style == aAttribute) { + // XXX the style sheet language is a document property that + // should be used to lookup the style sheet parser to parse the + // attribute. + nsICSSParser* css; + result = NS_NewCSSParser(&css); + if (NS_OK != result) { + return result; + } + nsIStyleRule* rule; + result = css->ParseDeclarations(aValue, nsnull, rule); + if ((NS_OK == result) && (nsnull != rule)) { + result = SetAttribute(aAttribute, nsHTMLValue(rule), aNotify); + NS_RELEASE(rule); + } + NS_RELEASE(css); + } + else { + // Check for event handlers + if (nsHTMLAtoms::onclick == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onclick, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::ondblclick == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onclick, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::onmousedown == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onmousedown, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::onmouseup == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onmouseup, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::onmouseover == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onmouseover, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::onmouseout == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onmouseout, aValue, kIDOMMouseListenerIID); + if (nsHTMLAtoms::onkeydown == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onkeydown, aValue, kIDOMKeyListenerIID); + if (nsHTMLAtoms::onkeyup == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onkeyup, aValue, kIDOMKeyListenerIID); + if (nsHTMLAtoms::onkeypress == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onkeypress, aValue, kIDOMKeyListenerIID); + if (nsHTMLAtoms::onmousemove == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onmousemove, aValue, kIDOMMouseMotionListenerIID); + if (nsHTMLAtoms::onload == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onload, aValue, kIDOMLoadListenerIID); + if (nsHTMLAtoms::onunload == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onunload, aValue, kIDOMLoadListenerIID); + if (nsHTMLAtoms::onabort == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onabort, aValue, kIDOMLoadListenerIID); + if (nsHTMLAtoms::onerror == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onerror, aValue, kIDOMLoadListenerIID); + if (nsHTMLAtoms::onfocus == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onfocus, aValue, kIDOMFocusListenerIID); + if (nsHTMLAtoms::onblur == aAttribute) + AddScriptEventListener(nsHTMLAtoms::onblur, aValue, kIDOMFocusListenerIID); + + if (nsnull != mDocument) { // set attr via style sheet + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + result = sheet->SetAttributeFor(aAttribute, aValue, this, mAttributes); + NS_RELEASE(sheet); + } + } + else { // manage this ourselves and re-sync when we connect to doc + result = EnsureWritableAttributes(this, mAttributes, PR_TRUE); + if (nsnull != mAttributes) { + PRInt32 count; + result = mAttributes->SetAttribute(aAttribute, aValue, count); + if (0 == count) { + ReleaseAttributes(mAttributes); + } + } + } + } + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetAttribute(nsIAtom* aAttribute, + const nsHTMLValue& aValue, + PRBool aNotify) +{ + nsresult result = NS_OK; + if (nsnull != mDocument) { // set attr via style sheet + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + result = sheet->SetAttributeFor(aAttribute, aValue, this, mAttributes); + NS_RELEASE(sheet); + } + } + else { // manage this ourselves and re-sync when we connect to doc + result = EnsureWritableAttributes(this, mAttributes, PR_TRUE); + if (nsnull != mAttributes) { + PRInt32 count; + result = mAttributes->SetAttribute(aAttribute, aValue, count); + if (0 == count) { + ReleaseAttributes(mAttributes); + } + } + } + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::UnsetAttribute(nsIAtom* aAttribute) +{ + nsresult result = NS_OK; + if (nsnull != mDocument) { // set attr via style sheet + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + result = sheet->UnsetAttributeFor(aAttribute, this, mAttributes); + NS_RELEASE(sheet); + } + } + else { // manage this ourselves and re-sync when we connect to doc + result = EnsureWritableAttributes(this, mAttributes, PR_FALSE); + if (nsnull != mAttributes) { + PRInt32 count; + result = mAttributes->UnsetAttribute(aAttribute, count); + if (0 == count) { + ReleaseAttributes(mAttributes); + } + } + } + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aValue) const +{ + if (nsnull != mAttributes) { + return mAttributes->GetAttribute(aAttribute, aValue); + } + aValue.Reset(); + return NS_CONTENT_ATTR_NOT_THERE; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAllAttributeNames(nsISupportsArray* aArray, + PRInt32& aCount) const +{ + if (nsnull != mAttributes) { + return mAttributes->GetAllAttributeNames(aArray, aCount); + } + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttributeCount(PRInt32& aCount) const +{ + if (nsnull != mAttributes) { + return mAttributes->Count(aCount); + } + aCount = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetID(nsIAtom* aID) +{ + nsresult result = NS_OK; + if (nsnull != mDocument) { // set attr via style sheet + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + result = sheet->SetIDFor(aID, this, mAttributes); + NS_RELEASE(sheet); + } + } + else { // manage this ourselves and re-sync when we connect to doc + EnsureWritableAttributes(this, mAttributes, PRBool(nsnull != aID)); + if (nsnull != mAttributes) { + PRInt32 count; + result = mAttributes->SetID(aID, count); + if (0 == count) { + ReleaseAttributes(mAttributes); + } + } + } + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetID(nsIAtom*& aResult) const +{ + if (nsnull != mAttributes) { + return mAttributes->GetID(aResult); + } + aResult = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetClass(nsIAtom* aClass) +{ + nsresult result = NS_OK; + if (nsnull != mDocument) { // set attr via style sheet + nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument); + if (nsnull != sheet) { + result = sheet->SetClassFor(aClass, this, mAttributes); + NS_RELEASE(sheet); + } + } + else { // manage this ourselves and re-sync when we connect to doc + EnsureWritableAttributes(this, mAttributes, PRBool(nsnull != aClass)); + if (nsnull != mAttributes) { + PRInt32 count; + result = mAttributes->SetClass(aClass, count); + if (0 == count) { + ReleaseAttributes(mAttributes); + } + } + } + return result; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetClass(nsIAtom*& aResult) const +{ + if (nsnull != mAttributes) { + return mAttributes->GetClass(aResult); + } + aResult = nsnull; + return NS_OK; +} + + +NS_IMETHODIMP +nsHTMLTagContent::GetStyleRule(nsIStyleRule*& aResult) +{ + nsIStyleRule* result = nsnull; + + if (nsnull != mAttributes) { + mAttributes->QueryInterface(kIStyleRuleIID, (void**)&result); + } + aResult = result; + return NS_OK; +} + +// +// Implementation of nsIScriptObjectOwner interface +// +nsresult nsHTMLTagContent::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject) +{ + nsresult res = NS_OK; + if (nsnull == mScriptObject) { + res = NS_NewScriptElement(aContext, (nsISupports *)(nsIDOMHTMLElement *)this, mParent, (void**)&mScriptObject); + } + *aScriptObject = mScriptObject; + return res; +} + +PRBool nsHTMLTagContent::AddProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return PR_TRUE; +} + +PRBool nsHTMLTagContent::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return PR_TRUE; +} + +PRBool nsHTMLTagContent::GetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return PR_TRUE; +} + +PRBool nsHTMLTagContent::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + if (JS_TypeOfValue(aContext, *aVp) == JSTYPE_FUNCTION && JSVAL_IS_STRING(aID)) { + nsAutoString mPropName, mPrefix; + mPropName.SetString(JS_GetStringChars(JS_ValueToString(aContext, aID))); + mPrefix.SetString(mPropName, 2); + if (mPrefix == "on") { + nsIEventListenerManager *mManager = nsnull; + + if (mPropName == "onmousedown" || mPropName == "onmouseup" || mPropName == "onclick" || + mPropName == "onmouseover" || mPropName == "onmouseout") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + else if (mPropName == "onkeydown" || mPropName == "onkeyup" || mPropName == "onkeypress") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMKeyListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + else if (mPropName == "onmousemove") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMMouseMotionListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + else if (mPropName == "onfocus" || mPropName == "onblur") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFocusListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + else if (mPropName == "onsubmit" || mPropName == "onreset") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMFormListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + else if (mPropName == "onload" || mPropName == "onunload" || mPropName == "onabort" || + mPropName == "onerror") { + if (NS_OK == GetListenerManager(&mManager)) { + nsIScriptContext *mScriptCX = (nsIScriptContext *)JS_GetContextPrivate(aContext); + if (NS_OK != mManager->RegisterScriptEventListener(mScriptCX, this, kIDOMLoadListenerIID)) { + NS_RELEASE(mManager); + return PR_FALSE; + } + } + } + NS_IF_RELEASE(mManager); + } + } + return PR_TRUE; +} + +PRBool nsHTMLTagContent::EnumerateProperty(JSContext *aContext) +{ + return PR_TRUE; +} + +PRBool nsHTMLTagContent::Resolve(JSContext *aContext, jsval aID) +{ + return PR_TRUE; +} + +PRBool nsHTMLTagContent::Convert(JSContext *aContext, jsval aID) +{ + return PR_TRUE; +} + +void nsHTMLTagContent::Finalize(JSContext *aContext) +{ +} + +PRBool +nsHTMLTagContent::Construct(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return PR_FALSE; +} + +// +// Implementation of nsIDOMNode interface +// +NS_IMETHODIMP +nsHTMLTagContent::GetNodeName(nsString& aNodeName) +{ + return GetTagName(aNodeName); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetNodeValue(nsString& aNodeValue) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetNodeValue(const nsString& aNodeValue) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetNodeType(PRInt32* aNodeType) +{ + *aNodeType = nsHTMLContent::ELEMENT; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttributes(nsIDOMNamedNodeMap** aAttributes) +{ + NS_PRECONDITION(nsnull != aAttributes, "null pointer argument"); + if (nsnull != mAttributes) { + // XXX Should we create a new one every time or should we + // cache one after we create it? If we find that this is + // something that's called often, we might need to do the + // latter. + *aAttributes = new nsDOMAttributeMap(*this); + } + else { + *aAttributes = nsnull; + } + return NS_OK; +} + +// XXX Currently implemented as a call to document.CreateElement(). +// This requires that the content actually have a document, which +// might not be the case if it isn't yet part of the tree. +NS_IMETHODIMP +nsHTMLTagContent::CloneNode(nsIDOMNode** aReturn) +{ + nsIDOMDocument *doc; + nsresult res = NS_OK; + nsAutoString tag_name; + nsIDOMNamedNodeMap *attr_map; + + if ((nsnull == mDocument) || (nsnull == mTag)) { + return NS_ERROR_FAILURE; + } + + res = mDocument->QueryInterface(kIDOMDocumentIID, (void **)&doc); + if (NS_OK != res) { + return res; + } + + mTag->ToString(tag_name); + // XXX Probably not the most efficient way to pass along attribute + // information. + GetAttributes(&attr_map); + + res = doc->CreateElement(tag_name, attr_map, (nsIDOMElement **)aReturn); + + NS_RELEASE(doc); + + return res; +} + +NS_IMETHODIMP +nsHTMLTagContent::Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn) +{ + // XXX TBI + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetParentNode(nsIDOMNode** aParentNode) +{ + return nsHTMLContent::GetParentNode(aParentNode); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetChildNodes(nsIDOMNodeList** aChildNodes) +{ + return nsHTMLContent::GetChildNodes(aChildNodes); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetHasChildNodes(PRBool* aHasChildNodes) +{ + return nsHTMLContent::GetHasChildNodes(aHasChildNodes); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetFirstChild(nsIDOMNode** aFirstChild) +{ + return nsHTMLContent::GetFirstChild(aFirstChild); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetLastChild(nsIDOMNode** aLastChild) +{ + return nsHTMLContent::GetLastChild(aLastChild); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetPreviousSibling(nsIDOMNode** aPreviousSibling) +{ + return nsHTMLContent::GetPreviousSibling(aPreviousSibling); +} + +NS_IMETHODIMP +nsHTMLTagContent::GetNextSibling(nsIDOMNode** aNextSibling) +{ + return nsHTMLContent::GetNextSibling(aNextSibling); +} + +NS_IMETHODIMP +nsHTMLTagContent::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn) +{ + return nsHTMLContent::InsertBefore(aNewChild, aRefChild, aReturn); +} + +NS_IMETHODIMP +nsHTMLTagContent::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn) +{ + return nsHTMLContent::ReplaceChild(aNewChild, aOldChild, aReturn); +} + +NS_IMETHODIMP +nsHTMLTagContent::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) +{ + return nsHTMLContent::RemoveChild(aOldChild, aReturn); +} + +NS_IMETHODIMP +nsHTMLTagContent::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) +{ + return nsHTMLContent::AppendChild(aNewChild, aReturn); +} + + +// +// Implementation of nsIDOMElement interface +// +NS_IMETHODIMP +nsHTMLTagContent::GetTagName(nsString& aTagName) +{ + if (nsnull != mTag) { + mTag->ToString(aTagName); + } + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetDOMAttribute(const nsString& aName, nsString& aReturn) +{ + GetAttribute(aName, aReturn); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetDOMAttribute(const nsString& aName, const nsString& aValue) +{ + SetAttribute(aName, aValue, PR_TRUE); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::RemoveAttribute(const nsString& aName) +{ + nsAutoString upper; + aName.ToUpperCase(upper); + nsIAtom* attr = NS_NewAtom(upper); + UnsetAttribute(attr); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetAttributeNode(const nsString& aName, nsIDOMAttribute** aReturn) +{ + nsAutoString value; + if(NS_CONTENT_ATTR_NOT_THERE != GetAttribute(aName, value)) { + *aReturn = new nsDOMAttribute(aName, value); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetAttributeNode(nsIDOMAttribute* aAttribute) +{ + NS_PRECONDITION(nsnull != aAttribute, "null attribute"); + + nsresult res = NS_ERROR_FAILURE; + + if (nsnull != aAttribute) { + // XXX Very suspicious code. Why aren't these nsAutoString? + nsString name, value; + res = aAttribute->GetName(name); + if (NS_OK == res) { + res = aAttribute->GetValue(value); + if (NS_OK == res) { + SetAttribute(name, value, PR_TRUE); + } + } + } + + return res; +} + +NS_IMETHODIMP +nsHTMLTagContent::RemoveAttributeNode(nsIDOMAttribute* aAttribute) +{ + NS_PRECONDITION(nsnull != aAttribute, "null attribute"); + + nsresult res = NS_ERROR_FAILURE; + + if (nsnull != aAttribute) { + nsAutoString name; + res = aAttribute->GetName(name); + if (NS_OK == res) { + nsAutoString upper; + name.ToUpperCase(upper); + nsIAtom* attr = NS_NewAtom(upper); + UnsetAttribute(attr); + } + } + + return res; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTMLTagContent::Normalize() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +// +// Implementation of nsIDOMHTMLElement interface +// +NS_IMETHODIMP +nsHTMLTagContent::GetId(nsString& aId) +{ + GetAttribute(nsHTMLAtoms::id, aId); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetId(const nsString& aId) +{ + SetAttribute(nsHTMLAtoms::id, aId, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetTitle(nsString& aTitle) +{ + GetAttribute(nsHTMLAtoms::title, aTitle); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetTitle(const nsString& aTitle) +{ + SetAttribute(nsHTMLAtoms::title, aTitle, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetLang(nsString& aLang) +{ + GetAttribute(nsHTMLAtoms::lang, aLang); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetLang(const nsString& aLang) +{ + SetAttribute(nsHTMLAtoms::lang, aLang, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetDir(nsString& aDir) +{ + GetAttribute(nsHTMLAtoms::dir, aDir); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetDir(const nsString& aDir) +{ + SetAttribute(nsHTMLAtoms::dir, aDir, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetClassName(nsString& aClassName) +{ + GetAttribute(nsHTMLAtoms::kClass, aClassName); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::SetClassName(const nsString& aClassName) +{ + SetAttribute(nsHTMLAtoms::kClass, aClassName, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLTagContent::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) +{ + // XXX NYI + return NS_OK; +} + +void nsHTMLTagContent::TriggerLink(nsIPresContext& aPresContext, + const nsString& aBase, + const nsString& aURLSpec, + const nsString& aTargetSpec, + PRBool aClick) +{ + nsILinkHandler* handler; + if (NS_OK == aPresContext.GetLinkHandler(&handler) && (nsnull != handler)) { + // Resolve url to an absolute url + nsIURL* docURL = nsnull; + nsIDocument* doc; + if (NS_OK == GetDocument(doc)) { + docURL = doc->GetDocumentURL(); + NS_RELEASE(doc); + } + + nsAutoString absURLSpec; + if (aURLSpec.Length() > 0) { + nsresult rv = NS_MakeAbsoluteURL(docURL, aBase, aURLSpec, absURLSpec); + } + else { + absURLSpec = aURLSpec; + } + + if (nsnull != docURL) { + NS_RELEASE(docURL); + } + + // Now pass on absolute url to the click handler + if (aClick) { + handler->OnLinkClick(nsnull, absURLSpec, aTargetSpec); + } + else { + handler->OnOverLink(nsnull, absURLSpec, aTargetSpec); + } + NS_RELEASE(handler); + } +} + +nsresult nsHTMLTagContent::HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) +{ + nsresult ret = NS_OK; + + ret = nsHTMLContent::HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); + + if (NS_OK == ret && nsEventStatus_eIgnore == aEventStatus) { + switch (aEvent->message) { + case NS_MOUSE_LEFT_BUTTON_DOWN: + if (mTag == nsHTMLAtoms::a) { + nsIEventStateManager *mStateManager; + if (NS_OK == aPresContext.GetEventStateManager(&mStateManager)) { + mStateManager->SetActiveLink(this); + NS_RELEASE(mStateManager); + } + aEventStatus = nsEventStatus_eConsumeNoDefault; + } + break; + + case NS_MOUSE_LEFT_BUTTON_UP: + if (mTag == nsHTMLAtoms::a) { + nsIEventStateManager *mStateManager; + nsIContent *mActiveLink; + if (NS_OK == aPresContext.GetEventStateManager(&mStateManager)) { + mStateManager->GetActiveLink(&mActiveLink); + NS_RELEASE(mStateManager); + } + + if (mActiveLink == this) { + nsEventStatus mStatus; + nsMouseEvent mEvent; + mEvent.eventStructType = NS_MOUSE_EVENT; + mEvent.message = NS_MOUSE_LEFT_CLICK; + HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus); + + if (nsEventStatus_eConsumeNoDefault != mStatus) { + nsAutoString base, href, target; + GetAttribute(nsString(NS_HTML_BASE_HREF), base); + GetAttribute(nsString("href"), href); + GetAttribute(nsString("target"), target); + if (target.Length() == 0) { + GetAttribute(nsString(NS_HTML_BASE_TARGET), target); + } + TriggerLink(aPresContext, base, href, target, PR_TRUE); + aEventStatus = nsEventStatus_eConsumeNoDefault; + } + } + } + break; + + case NS_MOUSE_RIGHT_BUTTON_DOWN: + // XXX Bring up a contextual menu provided by the application + break; + + case NS_MOUSE_ENTER: + //mouse enter doesn't work yet. Use move until then. + if (mTag == nsHTMLAtoms::a) { + nsAutoString base, href, target; + GetAttribute(nsString(NS_HTML_BASE_HREF), base); + GetAttribute(nsString("href"), href); + GetAttribute(nsString("target"), target); + if (target.Length() == 0) { + GetAttribute(nsString(NS_HTML_BASE_TARGET), target); + } + TriggerLink(aPresContext, base, href, target, PR_FALSE); + aEventStatus = nsEventStatus_eConsumeDoDefault; + } + break; + + // XXX this doesn't seem to do anything yet + case NS_MOUSE_EXIT: + if (mTag == nsHTMLAtoms::a) { + nsAutoString empty; + TriggerLink(aPresContext, empty, empty, empty, PR_FALSE); + aEventStatus = nsEventStatus_eConsumeDoDefault; + } + break; + + default: + break; + } + } + return ret; +} + +//---------------------------------------------------------------------- + +// Attribute parsing utility methods + +PRBool nsHTMLTagContent::ParseEnumValue(const nsString& aValue, + EnumTable* aTable, + nsHTMLValue& aResult) +{ + while (nsnull != aTable->tag) { + if (aValue.EqualsIgnoreCase(aTable->tag)) { + aResult.SetIntValue(aTable->value, eHTMLUnit_Enumerated); + return PR_TRUE; + } + aTable++; + } + return PR_FALSE; +} + +PRBool nsHTMLTagContent::EnumValueToString(const nsHTMLValue& aValue, + EnumTable* aTable, + nsString& aResult) +{ + aResult.Truncate(0); + if (aValue.GetUnit() == eHTMLUnit_Enumerated) { + PRInt32 v = aValue.GetIntValue(); + while (nsnull != aTable->tag) { + if (aTable->value == v) { + aResult.Append(aTable->tag); + return PR_TRUE; + } + aTable++; + } + } + return PR_FALSE; +} + +// XXX check all mappings against ebina's usage +static nsHTMLTagContent::EnumTable kAlignTable[] = { + { "left", NS_STYLE_TEXT_ALIGN_LEFT }, + { "right", NS_STYLE_TEXT_ALIGN_RIGHT }, + { "texttop", NS_STYLE_VERTICAL_ALIGN_TEXT_TOP }, + { "baseline", NS_STYLE_VERTICAL_ALIGN_BASELINE }, + { "center", NS_STYLE_TEXT_ALIGN_CENTER }, + { "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM }, + { "top", NS_STYLE_VERTICAL_ALIGN_TOP }, + { "middle", NS_STYLE_VERTICAL_ALIGN_MIDDLE }, + { "absbottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM }, + { "abscenter", NS_STYLE_VERTICAL_ALIGN_MIDDLE }, + { "absmiddle", NS_STYLE_VERTICAL_ALIGN_MIDDLE }, + { 0 } +}; + +PRBool nsHTMLTagContent::ParseAlignParam(const nsString& aString, + nsHTMLValue& aResult) +{ + return ParseEnumValue(aString, kAlignTable, aResult); +} + +PRBool nsHTMLTagContent::AlignParamToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + return EnumValueToString(aValue, kAlignTable, aResult); +} + +static nsHTMLTagContent::EnumTable kDivAlignTable[] = { + { "left", NS_STYLE_TEXT_ALIGN_LEFT }, + { "right", NS_STYLE_TEXT_ALIGN_RIGHT }, + { "center", NS_STYLE_TEXT_ALIGN_CENTER }, + { "middle", NS_STYLE_TEXT_ALIGN_CENTER }, + { "justify", NS_STYLE_TEXT_ALIGN_JUSTIFY }, + { 0 } +}; + +PRBool nsHTMLTagContent::ParseDivAlignParam(const nsString& aString, + nsHTMLValue& aResult) +{ + return ParseEnumValue(aString, kDivAlignTable, aResult); +} + +PRBool nsHTMLTagContent::DivAlignParamToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + return EnumValueToString(aValue, kDivAlignTable, aResult); +} + +/* ----- table specific attribute code ----- */ + +static nsHTMLTagContent::EnumTable kTableAlignTable[] = { + { "left", NS_STYLE_TEXT_ALIGN_LEFT }, + { "right", NS_STYLE_TEXT_ALIGN_RIGHT }, + { "center", NS_STYLE_TEXT_ALIGN_CENTER }, + { "middle", NS_STYLE_TEXT_ALIGN_CENTER }, + { 0 } +}; + +PRBool nsHTMLTagContent::ParseTableAlignParam(const nsString& aString, + nsHTMLValue& aResult) +{ + return ParseEnumValue(aString, kTableAlignTable, aResult); +} + +PRBool nsHTMLTagContent::TableAlignParamToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + return EnumValueToString(aValue, kTableAlignTable, aResult); +} + + +static nsHTMLTagContent::EnumTable kTableCaptionAlignTable[] = { + { "left", NS_STYLE_TEXT_ALIGN_LEFT }, + { "right", NS_STYLE_TEXT_ALIGN_RIGHT }, + { "top", NS_STYLE_VERTICAL_ALIGN_TOP}, + { "bottom",NS_STYLE_VERTICAL_ALIGN_BOTTOM}, + { 0 } +}; + +PRBool nsHTMLTagContent::ParseTableCaptionAlignParam(const nsString& aString, + nsHTMLValue& aResult) +{ + return ParseEnumValue(aString, kTableCaptionAlignTable, aResult); +} + +PRBool nsHTMLTagContent::TableCaptionAlignParamToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + return EnumValueToString(aValue, kTableCaptionAlignTable, aResult); +} + +/* ----- end table specific attribute code ----- */ + + +PRBool +nsHTMLTagContent::ParseValueOrPercent(const nsString& aString, + nsHTMLValue& aResult, + nsHTMLUnit aValueUnit) +{ // XXX should vave min/max values? + nsAutoString tmp(aString); + tmp.CompressWhitespace(PR_TRUE, PR_TRUE); + PRInt32 ec, val = tmp.ToInteger(&ec); + if (NS_OK == ec) { + if (tmp.Last() == '%') {/* XXX not 100% compatible with ebina's code */ + if (val < 0) val = 0; + if (val > 100) val = 100; + aResult.SetPercentValue(float(val)/100.0f); + } else { + if (eHTMLUnit_Pixel == aValueUnit) { + aResult.SetPixelValue(val); + } + else { + aResult.SetIntValue(val, aValueUnit); + } + } + return PR_TRUE; + } + + // Illegal values are mapped to empty + aResult.SetEmptyValue(); + return PR_FALSE; +} + +/* used to parse attribute values that could be either: + * integer (n), + * percent (n%), + * or proportional (n*) + */ +void +nsHTMLTagContent::ParseValueOrPercentOrProportional(const nsString& aString, + nsHTMLValue& aResult, + nsHTMLUnit aValueUnit) +{ // XXX should have min/max values? + nsAutoString tmp(aString); + tmp.CompressWhitespace(PR_TRUE, PR_TRUE); + PRInt32 ec, val = tmp.ToInteger(&ec); + if (tmp.Last() == '%') {/* XXX not 100% compatible with ebina's code */ + if (val < 0) val = 0; + if (val > 100) val = 100; + aResult.SetPercentValue(float(val)/100.0f); + } else if (tmp.Last() == '*') { + if (val < 0) val = 0; + aResult.SetIntValue(val, eHTMLUnit_Proportional); // proportional values are integers + } else { + if (eHTMLUnit_Pixel == aValueUnit) { + aResult.SetPixelValue(val); + } + else { + aResult.SetIntValue(val, aValueUnit); + } + } +} + +PRBool +nsHTMLTagContent::ValueOrPercentToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + aResult.Truncate(0); + switch (aValue.GetUnit()) { + case eHTMLUnit_Integer: + aResult.Append(aValue.GetIntValue(), 10); + return PR_TRUE; + case eHTMLUnit_Pixel: + aResult.Append(aValue.GetPixelValue(), 10); + return PR_TRUE; + case eHTMLUnit_Percent: + aResult.Append(PRInt32(aValue.GetPercentValue() * 100.0f), 10); + aResult.Append('%'); + return PR_TRUE; + } + return PR_FALSE; +} + +PRBool +nsHTMLTagContent::ParseValue(const nsString& aString, PRInt32 aMin, + nsHTMLValue& aResult, nsHTMLUnit aValueUnit) +{ + PRInt32 ec, val = aString.ToInteger(&ec); + if (NS_OK == ec) { + if (val < aMin) val = aMin; + if (eHTMLUnit_Pixel == aValueUnit) { + aResult.SetPixelValue(val); + } + else { + aResult.SetIntValue(val, aValueUnit); + } + return PR_TRUE; + } + + // Illegal values are mapped to empty + aResult.SetEmptyValue(); + return PR_FALSE; +} + +PRBool +nsHTMLTagContent::ParseValue(const nsString& aString, PRInt32 aMin, + PRInt32 aMax, + nsHTMLValue& aResult, nsHTMLUnit aValueUnit) +{ + PRInt32 ec, val = aString.ToInteger(&ec); + if (NS_OK == ec) { + if (val < aMin) val = aMin; + if (val > aMax) val = aMax; + if (eHTMLUnit_Pixel == aValueUnit) { + aResult.SetPixelValue(val); + } + else { + aResult.SetIntValue(val, aValueUnit); + } + return PR_TRUE; + } + + // Illegal values are mapped to empty + aResult.SetEmptyValue(); + return PR_FALSE; +} + +PRBool nsHTMLTagContent::ParseImageProperty(nsIAtom* aAttribute, + const nsString& aString, + nsHTMLValue& aResult) +{ + if ((aAttribute == nsHTMLAtoms::width) || + (aAttribute == nsHTMLAtoms::height)) { + ParseValueOrPercent(aString, aResult, eHTMLUnit_Pixel); + return PR_TRUE; + } + else if ((aAttribute == nsHTMLAtoms::hspace) || + (aAttribute == nsHTMLAtoms::vspace) || + (aAttribute == nsHTMLAtoms::border)) { + ParseValue(aString, 0, aResult, eHTMLUnit_Pixel); + return PR_TRUE; + } + return PR_FALSE; +} + +PRBool nsHTMLTagContent::ImagePropertyToString(nsIAtom* aAttribute, + const nsHTMLValue& aValue, + nsString& aResult) +{ + if ((aAttribute == nsHTMLAtoms::width) || + (aAttribute == nsHTMLAtoms::height) || + (aAttribute == nsHTMLAtoms::border) || + (aAttribute == nsHTMLAtoms::hspace) || + (aAttribute == nsHTMLAtoms::vspace)) { + return ValueOrPercentToString(aValue, aResult); + } + return PR_FALSE; +} + +void +nsHTMLTagContent::MapImagePropertiesInto(nsIStyleContext* aContext, + nsIPresContext* aPresContext) +{ + if (nsnull != mAttributes) { + nsHTMLValue value; + + float p2t = aPresContext->GetPixelsToTwips(); + nsStylePosition* pos = (nsStylePosition*) + aContext->GetMutableStyleData(eStyleStruct_Position); + nsStyleSpacing* spacing = (nsStyleSpacing*) + aContext->GetMutableStyleData(eStyleStruct_Spacing); + + // width: value + GetAttribute(nsHTMLAtoms::width, value); + if (value.GetUnit() == eHTMLUnit_Pixel) { + nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); + pos->mWidth.SetCoordValue(twips); + } + else if (value.GetUnit() == eHTMLUnit_Percent) { + pos->mWidth.SetPercentValue(value.GetPercentValue()); + } + + // height: value + GetAttribute(nsHTMLAtoms::height, value); + if (value.GetUnit() == eHTMLUnit_Pixel) { + nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); + pos->mHeight.SetCoordValue(twips); + } + else if (value.GetUnit() == eHTMLUnit_Percent) { + pos->mHeight.SetPercentValue(value.GetPercentValue()); + } + + // hspace: value + GetAttribute(nsHTMLAtoms::hspace, value); + if (value.GetUnit() == eHTMLUnit_Pixel) { + nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); + spacing->mMargin.SetRight(nsStyleCoord(twips)); + } + else if (value.GetUnit() == eHTMLUnit_Percent) { + spacing->mMargin.SetRight(nsStyleCoord(value.GetPercentValue(), + eStyleUnit_Coord)); + } + + // vspace: value + GetAttribute(nsHTMLAtoms::vspace, value); + if (value.GetUnit() == eHTMLUnit_Pixel) { + nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); + spacing->mMargin.SetBottom(nsStyleCoord(twips)); + } + else if (value.GetUnit() == eHTMLUnit_Percent) { + spacing->mMargin.SetBottom(nsStyleCoord(value.GetPercentValue(), + eStyleUnit_Coord)); + } + } +} + +void +nsHTMLTagContent::MapImageBorderInto(nsIStyleContext* aContext, + nsIPresContext* aPresContext, + nscolor aBorderColors[4]) +{ + if (nsnull != mAttributes) { + nsHTMLValue value; + + // border: pixels + GetAttribute(nsHTMLAtoms::border, value); + if (value.GetUnit() != eHTMLUnit_Pixel) { + if (nsnull == aBorderColors) { + return; + } + // If no border is defined and we are forcing a border, force + // the size to 2 pixels. + value.SetPixelValue(2); + } + + float p2t = aPresContext->GetPixelsToTwips(); + nscoord twips = NSIntPixelsToTwips(value.GetPixelValue(), p2t); + + // Fixup border-padding sums: subtract out the old size and then + // add in the new size. + nsStyleSpacing* spacing = (nsStyleSpacing*) + aContext->GetMutableStyleData(eStyleStruct_Spacing); + nsStyleCoord coord; + coord.SetCoordValue(twips); + spacing->mBorder.SetTop(coord); + spacing->mBorder.SetRight(coord); + spacing->mBorder.SetBottom(coord); + spacing->mBorder.SetLeft(coord); + spacing->mBorderStyle[0] = NS_STYLE_BORDER_STYLE_SOLID; + spacing->mBorderStyle[1] = NS_STYLE_BORDER_STYLE_SOLID; + spacing->mBorderStyle[2] = NS_STYLE_BORDER_STYLE_SOLID; + spacing->mBorderStyle[3] = NS_STYLE_BORDER_STYLE_SOLID; + + // Use supplied colors if provided, otherwise use color for border + // color + if (nsnull != aBorderColors) { + spacing->mBorderColor[0] = aBorderColors[0]; + spacing->mBorderColor[1] = aBorderColors[1]; + spacing->mBorderColor[2] = aBorderColors[2]; + spacing->mBorderColor[3] = aBorderColors[3]; + } + else { + // Color is inherited from "color" + const nsStyleColor* styleColor = (const nsStyleColor*) + aContext->GetStyleData(eStyleStruct_Color); + nscolor color = styleColor->mColor; + spacing->mBorderColor[0] = color; + spacing->mBorderColor[1] = color; + spacing->mBorderColor[2] = color; + spacing->mBorderColor[3] = color; + } + } +} + +PRBool nsHTMLTagContent::ParseColor(const nsString& aString, + nsHTMLValue& aResult) +{ + if (aString.Length() > 0) { + nsAutoString colorStr (aString); + colorStr.CompressWhitespace(); + char cbuf[40]; + colorStr.ToCString(cbuf, sizeof(cbuf)); + nscolor color; + if (NS_ColorNameToRGB(cbuf, &color)) { + aResult.SetStringValue(colorStr); + return PR_TRUE; + } + if (NS_HexToRGB(cbuf, &color)) { + aResult.SetColorValue(color); + return PR_TRUE; + } + } + + // Illegal values are mapped to empty + aResult.SetEmptyValue(); + return PR_FALSE; +} + +PRBool nsHTMLTagContent::ColorToString(const nsHTMLValue& aValue, + nsString& aResult) +{ + if (aValue.GetUnit() == eHTMLUnit_Color) { + nscolor v = aValue.GetColorValue(); + char buf[10]; + PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x", + NS_GET_R(v), NS_GET_G(v), NS_GET_B(v)); + aResult.Truncate(0); + aResult.Append(buf); + return PR_TRUE; + } + if (aValue.GetUnit() == eHTMLUnit_String) { + aValue.GetStringValue(aResult); + return PR_TRUE; + } + if (aValue.GetUnit() == eHTMLUnit_Empty) { // was illegal + aResult.Truncate(); + return PR_TRUE; + } + return PR_FALSE; +} diff --git a/mozilla/layout/html/base/src/nsInlineFrame.cpp b/mozilla/layout/html/base/src/nsInlineFrame.cpp index a20c9f78eb1..25cc288f53f 100644 --- a/mozilla/layout/html/base/src/nsInlineFrame.cpp +++ b/mozilla/layout/html/base/src/nsInlineFrame.cpp @@ -222,6 +222,13 @@ nsInlineFrame::AttributeChanged(nsIPresShell* aShell, nsIContent* aChild, nsIAtom* aAttribute) { + nsresult result = nsHTMLContainerFrame::AttributeChanged(aShell, + aPresContext, + aChild, + aAttribute); + if (NS_OK != result) { + return result; + } if (nsHTMLAtoms::color == aAttribute) { ApplyStyleChangeToTree(*aPresContext, this); ApplyRenderingChangeToTree(*aPresContext, this); diff --git a/mozilla/layout/html/content/src/Makefile b/mozilla/layout/html/content/src/Makefile index 42104c5d4da..ac878876aea 100644 --- a/mozilla/layout/html/content/src/Makefile +++ b/mozilla/layout/html/content/src/Makefile @@ -22,6 +22,7 @@ LIBRARY_NAME = nglhtmlcon_s # Note the sophisticated alphabetical ordering :-| CPPSRCS= \ nsCommentNode.cpp \ + nsDOMStyleDeclaration.cpp \ nsGenericDOMDataNode.cpp \ nsGenericHTMLElement.cpp \ nsHTMLAnchorElement.cpp \ diff --git a/mozilla/layout/html/content/src/makefile.win b/mozilla/layout/html/content/src/makefile.win index 47ab2f2c65a..a72823fcf12 100644 --- a/mozilla/layout/html/content/src/makefile.win +++ b/mozilla/layout/html/content/src/makefile.win @@ -24,6 +24,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ nsCommentNode.cpp \ + nsDOMStyleDeclaration.cpp \ nsGenericDOMDataNode.cpp \ nsGenericHTMLElement.cpp \ nsHTMLAnchorElement.cpp \ @@ -90,6 +91,7 @@ CPPSRCS= \ CPP_OBJS= \ .\$(OBJDIR)\nsCommentNode.obj \ + .\$(OBJDIR)\nsDOMStyleDeclaration.obj \ .\$(OBJDIR)\nsGenericDOMDataNode.obj \ .\$(OBJDIR)\nsGenericHTMLElement.obj \ .\$(OBJDIR)\nsHTMLAnchorElement.obj \ diff --git a/mozilla/layout/html/content/src/nsDOMStyleDeclaration.cpp b/mozilla/layout/html/content/src/nsDOMStyleDeclaration.cpp new file mode 100644 index 00000000000..29927e935da --- /dev/null +++ b/mozilla/layout/html/content/src/nsDOMStyleDeclaration.cpp @@ -0,0 +1,1741 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +#include "nsDOMStyleDeclaration.h" +#include "nsGenericHTMLElement.h" +#include "nsICSSStyleRule.h" +#include "nsICSSParser.h" +#include "nsIStyleRule.h" +#include "nsICSSDeclaration.h" +#include "nsCSSProps.h" +#include "nsHTMLAtoms.h" +#include "nsIHTMLContent.h" +#include "nsIDocument.h" + +nsDOMStyleDeclaration::nsDOMStyleDeclaration(nsIHTMLContent *aContent) +{ + NS_INIT_REFCNT(); + // This reference is not reference-counted. The content + // object tells us when its about to go away. + mContent = aContent; + mScriptObject = nsnull; +} + +nsDOMStyleDeclaration::~nsDOMStyleDeclaration() +{ +} + +NS_IMPL_ADDREF(nsDOMStyleDeclaration); +NS_IMPL_RELEASE(nsDOMStyleDeclaration); + +static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); +static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); + +NS_IMETHODIMP +nsDOMStyleDeclaration::QueryInterface(REFNSIID aIID, + void** aInstancePtr) +{ + NS_PRECONDITION(nsnull != aInstancePtr, "null ptr"); + if (nsnull == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kIDOMCSSStyleDeclarationIID)) { + nsIDOMCSSStyleDeclaration *tmp = this; + AddRef(); + *aInstancePtr = (void*) tmp; + return NS_OK; + } + if (aIID.Equals(kIScriptObjectOwnerIID)) { + nsIScriptObjectOwner *tmp = this; + AddRef(); + *aInstancePtr = (void*) tmp; + return NS_OK; + } + if (aIID.Equals(kISupportsIID)) { + nsIDOMCSSStyleDeclaration *tmp = this; + nsISupports *tmp2 = tmp; + AddRef(); + *aInstancePtr = (void*) tmp2; + return NS_OK; + } + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetScriptObject(nsIScriptContext* aContext, + void** aScriptObject) +{ + nsresult res = NS_OK; + + if (nsnull == mScriptObject) { + nsISupports *parent = nsnull; + if (nsnull != mContent) { + res = mContent->QueryInterface(kISupportsIID, (void **)&parent); + if (NS_OK != res) { + return res; + } + } + nsISupports *supports = (nsISupports *)(nsIDOMCSSStyleDeclaration *)this; + // XXX Should be done through factory + res = NS_NewScriptCSSStyleDeclaration(aContext, + supports, + parent, + (void**)&mScriptObject); + NS_RELEASE(parent); + } + *aScriptObject = mScriptObject; + + return res; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetScriptObject(void* aScriptObject) +{ + mScriptObject = aScriptObject; + return NS_OK; +} + +void +nsDOMStyleDeclaration::DropContent() +{ + mContent = nsnull; +} + +nsresult +nsDOMStyleDeclaration::GetContentStyle(nsICSSDeclaration **aDecl, + PRBool aAllocate) +{ + nsHTMLValue val; + nsIStyleRule* rule; + nsICSSStyleRule* cssRule; + nsresult result = NS_OK; + + *aDecl = nsnull; + if (nsnull != mContent) { + mContent->GetAttribute(nsHTMLAtoms::style, val); + if (eHTMLUnit_ISupports == val.GetUnit()) { + rule = (nsIStyleRule*) val.GetISupportsValue(); + result = rule->QueryInterface(kICSSStyleRuleIID, (void**)&cssRule); + if (NS_OK == result) { + *aDecl = cssRule->GetDeclaration(); + NS_RELEASE(cssRule); + } + NS_RELEASE(rule); + } + else if (PR_TRUE == aAllocate) { + result = NS_NewCSSDeclaration(aDecl); + if (NS_OK == result) { + result = NS_NewCSSStyleRule(&cssRule, nsCSSSelector()); + if (NS_OK == result) { + cssRule->SetDeclaration(*aDecl); + cssRule->SetWeight(0x7fffffff); + rule = (nsIStyleRule *)cssRule; + result = mContent->SetAttribute(nsHTMLAtoms::style, + nsHTMLValue(cssRule), + PR_FALSE); + } + else { + NS_RELEASE(*aDecl); + } + } + } + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetLength(PRUint32* aLength) +{ + nsICSSDeclaration *decl; + nsresult result = GetContentStyle(&decl, PR_FALSE); + + *aLength = 0; + if ((NS_OK == result) && (nsnull != decl)) { + result = decl->Count(aLength); + NS_RELEASE(decl); + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::Item(PRUint32 aIndex, nsString& aReturn) +{ + nsICSSDeclaration *decl; + nsresult result = GetContentStyle(&decl, PR_FALSE); + + aReturn.SetLength(0); + if ((NS_OK == result) && (nsnull != decl)) { + result = decl->GetNthProperty(aIndex, aReturn); + NS_RELEASE(decl); + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPropertyValue(const nsString& aPropertyName, + nsString& aReturn) +{ + nsCSSValue val; + nsICSSDeclaration *decl; + nsresult result = GetContentStyle(&decl, PR_FALSE); + + aReturn.SetLength(0); + if ((NS_OK == result) && (nsnull != decl)) { + char prop[50]; + aPropertyName.ToCString(prop, sizeof(prop)); + result = decl->GetValue(prop, val); + NS_RELEASE(decl); + if (NS_OK == result) { + PRInt32 propID = nsCSSProps::LookupName(prop); + nsCSSValue::ValueToString(aReturn, val, propID); + } + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPropertyPriority(const nsString& aPropertyName, + nsString& aReturn) +{ + nsICSSDeclaration *decl; + nsresult result = GetContentStyle(&decl, PR_FALSE); + PRBool isImportant = PR_FALSE; + + if ((NS_OK == result) && (nsnull != decl)) { + char prop[50]; + aPropertyName.ToCString(prop, sizeof(prop)); + result = decl->GetValueIsImportant(prop, isImportant); + NS_RELEASE(decl); + } + + if ((NS_OK == result) && isImportant) { + aReturn.SetString("!important"); + } + else { + aReturn.SetLength(0); + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetProperty(const nsString& aPropertyName, + const nsString& aValue, + const nsString& aPriority) +{ + nsAutoString declString; + nsICSSDeclaration *decl; + nsresult result = GetContentStyle(&decl, PR_TRUE); + + if ((NS_OK == result) && (nsnull != decl)) { + declString.SetString(aPropertyName); + declString.Append(":"); + declString.Append(aValue); + + nsICSSParser* css; + result = NS_NewCSSParser(&css); + if (NS_OK == result) { + result = css->ParseAndAppendDeclaration(declString, nsnull, *decl); + if (NS_OK == result) { + if (aPriority.Equals("!important")) { + char prop[50]; + aPropertyName.ToCString(prop, sizeof(prop)); + decl->SetValueImportant(prop); + } + nsIDocument *doc; + result = mContent->GetDocument(doc); + if (NS_OK == result) { + doc->AttributeChanged(mContent, nsHTMLAtoms::style); + NS_RELEASE(doc); + } + } + } + } + + return result; +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetAzimuth(nsString& aAzimuth) +{ + return GetPropertyValue("azimuth", aAzimuth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetAzimuth(const nsString& aAzimuth) +{ + return SetProperty("azimuth", aAzimuth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackground(nsString& aBackground) +{ + return GetPropertyValue("background", aBackground); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackground(const nsString& aBackground) +{ + return SetProperty("background", aBackground, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackgroundAttachment(nsString& aBackgroundAttachment) +{ + return GetPropertyValue("background-attachment", aBackgroundAttachment); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackgroundAttachment(const nsString& aBackgroundAttachment) +{ + return SetProperty("background-attachment", aBackgroundAttachment, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackgroundColor(nsString& aBackgroundColor) +{ + return GetPropertyValue("background-color", aBackgroundColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackgroundColor(const nsString& aBackgroundColor) +{ + return SetProperty("background-color", aBackgroundColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackgroundImage(nsString& aBackgroundImage) +{ + return GetPropertyValue("background-image", aBackgroundImage); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackgroundImage(const nsString& aBackgroundImage) +{ + return SetProperty("background-image", aBackgroundImage, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackgroundPosition(nsString& aBackgroundPosition) +{ + return GetPropertyValue("background-position", aBackgroundPosition); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackgroundPosition(const nsString& aBackgroundPosition) +{ + return SetProperty("background-position", aBackgroundPosition, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBackgroundRepeat(nsString& aBackgroundRepeat) +{ + return GetPropertyValue("background-repeat", aBackgroundRepeat); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBackgroundRepeat(const nsString& aBackgroundRepeat) +{ + return SetProperty("background-repeat", aBackgroundRepeat, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorder(nsString& aBorder) +{ + return GetPropertyValue("border", aBorder); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorder(const nsString& aBorder) +{ + return SetProperty("border", aBorder, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderCollapse(nsString& aBorderCollapse) +{ + return GetPropertyValue("border-collapse", aBorderCollapse); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderCollapse(const nsString& aBorderCollapse) +{ + return SetProperty("border-collapse", aBorderCollapse, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderColor(nsString& aBorderColor) +{ + return GetPropertyValue("border-color", aBorderColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderColor(const nsString& aBorderColor) +{ + return SetProperty("border-color", aBorderColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderSpacing(nsString& aBorderSpacing) +{ + return GetPropertyValue("border-spacing", aBorderSpacing); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderSpacing(const nsString& aBorderSpacing) +{ + return SetProperty("border-spacing", aBorderSpacing, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderStyle(nsString& aBorderStyle) +{ + return GetPropertyValue("border-style", aBorderStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderStyle(const nsString& aBorderStyle) +{ + return SetProperty("border-style", aBorderStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderTop(nsString& aBorderTop) +{ + return GetPropertyValue("border-top", aBorderTop); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderTop(const nsString& aBorderTop) +{ + return SetProperty("border-top", aBorderTop, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderRight(nsString& aBorderRight) +{ + return GetPropertyValue("border-right", aBorderRight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderRight(const nsString& aBorderRight) +{ + return SetProperty("border-right", aBorderRight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderBottom(nsString& aBorderBottom) +{ + return GetPropertyValue("border-bottom", aBorderBottom); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderBottom(const nsString& aBorderBottom) +{ + return SetProperty("border-bottom", aBorderBottom, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderLeft(nsString& aBorderLeft) +{ + return GetPropertyValue("border-left", aBorderLeft); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderLeft(const nsString& aBorderLeft) +{ + return SetProperty("border-left", aBorderLeft, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderTopColor(nsString& aBorderTopColor) +{ + return GetPropertyValue("border-top-color", aBorderTopColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderTopColor(const nsString& aBorderTopColor) +{ + return SetProperty("border-top-color", aBorderTopColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderRightColor(nsString& aBorderRightColor) +{ + return GetPropertyValue("border-right-color", aBorderRightColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderRightColor(const nsString& aBorderRightColor) +{ + return SetProperty("border-right-color", aBorderRightColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderBottomColor(nsString& aBorderBottomColor) +{ + return GetPropertyValue("border-bottom-color", aBorderBottomColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderBottomColor(const nsString& aBorderBottomColor) +{ + return SetProperty("border-bottom-color", aBorderBottomColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderLeftColor(nsString& aBorderLeftColor) +{ + return GetPropertyValue("border-left-color", aBorderLeftColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderLeftColor(const nsString& aBorderLeftColor) +{ + return SetProperty("border-left-color", aBorderLeftColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderTopStyle(nsString& aBorderTopStyle) +{ + return GetPropertyValue("border-top-style", aBorderTopStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderTopStyle(const nsString& aBorderTopStyle) +{ + return SetProperty("border-top-style", aBorderTopStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderRightStyle(nsString& aBorderRightStyle) +{ + return GetPropertyValue("border-right-style", aBorderRightStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderRightStyle(const nsString& aBorderRightStyle) +{ + return SetProperty("border-right-style", aBorderRightStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderBottomStyle(nsString& aBorderBottomStyle) +{ + return GetPropertyValue("border-bottom-style", aBorderBottomStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderBottomStyle(const nsString& aBorderBottomStyle) +{ + return SetProperty("border-bottom-style", aBorderBottomStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderLeftStyle(nsString& aBorderLeftStyle) +{ + return GetPropertyValue("border-left-style", aBorderLeftStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderLeftStyle(const nsString& aBorderLeftStyle) +{ + return SetProperty("border-left-style", aBorderLeftStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderTopWidth(nsString& aBorderTopWidth) +{ + return GetPropertyValue("border-top-width", aBorderTopWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderTopWidth(const nsString& aBorderTopWidth) +{ + return SetProperty("border-top-width", aBorderTopWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderRightWidth(nsString& aBorderRightWidth) +{ + return GetPropertyValue("border-right-width", aBorderRightWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderRightWidth(const nsString& aBorderRightWidth) +{ + return SetProperty("border-right-width", aBorderRightWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderBottomWidth(nsString& aBorderBottomWidth) +{ + return GetPropertyValue("border-bottom-width", aBorderBottomWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderBottomWidth(const nsString& aBorderBottomWidth) +{ + return SetProperty("border-bottom-width", aBorderBottomWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderLeftWidth(nsString& aBorderLeftWidth) +{ + return GetPropertyValue("border-left-width", aBorderLeftWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderLeftWidth(const nsString& aBorderLeftWidth) +{ + return SetProperty("border-left-width", aBorderLeftWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBorderWidth(nsString& aBorderWidth) +{ + return GetPropertyValue("border-width", aBorderWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBorderWidth(const nsString& aBorderWidth) +{ + return SetProperty("border-width", aBorderWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetBottom(nsString& aBottom) +{ + return GetPropertyValue("bottom", aBottom); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetBottom(const nsString& aBottom) +{ + return SetProperty("bottom", aBottom, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCaptionSide(nsString& aCaptionSide) +{ + return GetPropertyValue("caption-side", aCaptionSide); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCaptionSide(const nsString& aCaptionSide) +{ + return SetProperty("caption-side", aCaptionSide, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetClear(nsString& aClear) +{ + return GetPropertyValue("clear", aClear); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetClear(const nsString& aClear) +{ + return SetProperty("clear", aClear, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetClip(nsString& aClip) +{ + return GetPropertyValue("clip", aClip); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetClip(const nsString& aClip) +{ + return SetProperty("clip", aClip, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetColor(nsString& aColor) +{ + return GetPropertyValue("color", aColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetColor(const nsString& aColor) +{ + return SetProperty("color", aColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetContent(nsString& aContent) +{ + return GetPropertyValue("content", aContent); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetContent(const nsString& aContent) +{ + return SetProperty("content", aContent, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCounterIncrement(nsString& aCounterIncrement) +{ + return GetPropertyValue("counter-increment", aCounterIncrement); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCounterIncrement(const nsString& aCounterIncrement) +{ + return SetProperty("counter-increment", aCounterIncrement, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCounterReset(nsString& aCounterReset) +{ + return GetPropertyValue("counter-reset", aCounterReset); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCounterReset(const nsString& aCounterReset) +{ + return SetProperty("counter-reset", aCounterReset, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCue(nsString& aCue) +{ + return GetPropertyValue("cue", aCue); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCue(const nsString& aCue) +{ + return SetProperty("cue", aCue, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCueAfter(nsString& aCueAfter) +{ + return GetPropertyValue("cue-after", aCueAfter); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCueAfter(const nsString& aCueAfter) +{ + return SetProperty("cue-after", aCueAfter, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCueBefore(nsString& aCueBefore) +{ + return GetPropertyValue("cue-before", aCueBefore); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCueBefore(const nsString& aCueBefore) +{ + return SetProperty("cue-before", aCueBefore, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetCursor(nsString& aCursor) +{ + return GetPropertyValue("cursor", aCursor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetCursor(const nsString& aCursor) +{ + return SetProperty("cursor", aCursor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetDirection(nsString& aDirection) +{ + return GetPropertyValue("direction", aDirection); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetDirection(const nsString& aDirection) +{ + return SetProperty("direction", aDirection, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetDisplay(nsString& aDisplay) +{ + return GetPropertyValue("display", aDisplay); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetDisplay(const nsString& aDisplay) +{ + return SetProperty("display", aDisplay, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetElevation(nsString& aElevation) +{ + return GetPropertyValue("elevation", aElevation); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetElevation(const nsString& aElevation) +{ + return SetProperty("elevation", aElevation, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetEmptyCells(nsString& aEmptyCells) +{ + return GetPropertyValue("empty-cells", aEmptyCells); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetEmptyCells(const nsString& aEmptyCells) +{ + return SetProperty("empty-cells", aEmptyCells, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetStyleFloat(nsString& aStyleFloat) +{ + return GetPropertyValue("style-float", aStyleFloat); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetStyleFloat(const nsString& aStyleFloat) +{ + return SetProperty("style-float", aStyleFloat, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFont(nsString& aFont) +{ + return GetPropertyValue("font", aFont); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFont(const nsString& aFont) +{ + return SetProperty("font", aFont, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontFamily(nsString& aFontFamily) +{ + return GetPropertyValue("font-family", aFontFamily); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontFamily(const nsString& aFontFamily) +{ + return SetProperty("font-family", aFontFamily, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontSize(nsString& aFontSize) +{ + return GetPropertyValue("font-size", aFontSize); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontSize(const nsString& aFontSize) +{ + return SetProperty("font-size", aFontSize, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontSizeAdjust(nsString& aFontSizeAdjust) +{ + return GetPropertyValue("font-size-adjust", aFontSizeAdjust); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontSizeAdjust(const nsString& aFontSizeAdjust) +{ + return SetProperty("font-size-adjust", aFontSizeAdjust, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontStretch(nsString& aFontStretch) +{ + return GetPropertyValue("font-stretch", aFontStretch); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontStretch(const nsString& aFontStretch) +{ + return SetProperty("font-stretch", aFontStretch, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontStyle(nsString& aFontStyle) +{ + return GetPropertyValue("font-style", aFontStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontStyle(const nsString& aFontStyle) +{ + return SetProperty("font-style", aFontStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontVariant(nsString& aFontVariant) +{ + return GetPropertyValue("font-variant", aFontVariant); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontVariant(const nsString& aFontVariant) +{ + return SetProperty("font-variant", aFontVariant, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetFontWeight(nsString& aFontWeight) +{ + return GetPropertyValue("font-weight", aFontWeight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetFontWeight(const nsString& aFontWeight) +{ + return SetProperty("font-weight", aFontWeight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetHeight(nsString& aHeight) +{ + return GetPropertyValue("height", aHeight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetHeight(const nsString& aHeight) +{ + return SetProperty("height", aHeight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetLeft(nsString& aLeft) +{ + return GetPropertyValue("left", aLeft); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetLeft(const nsString& aLeft) +{ + return SetProperty("left", aLeft, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetLetterSpacing(nsString& aLetterSpacing) +{ + return GetPropertyValue("letter-spacing", aLetterSpacing); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetLetterSpacing(const nsString& aLetterSpacing) +{ + return SetProperty("letter-spacing", aLetterSpacing, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetLineHeight(nsString& aLineHeight) +{ + return GetPropertyValue("line-height", aLineHeight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetLineHeight(const nsString& aLineHeight) +{ + return SetProperty("line-height", aLineHeight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetListStyle(nsString& aListStyle) +{ + return GetPropertyValue("list-style", aListStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetListStyle(const nsString& aListStyle) +{ + return SetProperty("list-style", aListStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetListStyleImage(nsString& aListStyleImage) +{ + return GetPropertyValue("list-style-image", aListStyleImage); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetListStyleImage(const nsString& aListStyleImage) +{ + return SetProperty("list-style-image", aListStyleImage, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetListStylePosition(nsString& aListStylePosition) +{ + return GetPropertyValue("list-style-position", aListStylePosition); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetListStylePosition(const nsString& aListStylePosition) +{ + return SetProperty("list-style-position", aListStylePosition, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetListStyleType(nsString& aListStyleType) +{ + return GetPropertyValue("list-style-type", aListStyleType); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetListStyleType(const nsString& aListStyleType) +{ + return SetProperty("list-style-type", aListStyleType, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMargin(nsString& aMargin) +{ + return GetPropertyValue("margin", aMargin); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMargin(const nsString& aMargin) +{ + return SetProperty("margin", aMargin, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarginTop(nsString& aMarginTop) +{ + return GetPropertyValue("margin-top", aMarginTop); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarginTop(const nsString& aMarginTop) +{ + return SetProperty("margin-top", aMarginTop, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarginRight(nsString& aMarginRight) +{ + return GetPropertyValue("margin-right", aMarginRight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarginRight(const nsString& aMarginRight) +{ + return SetProperty("margin-right", aMarginRight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarginBottom(nsString& aMarginBottom) +{ + return GetPropertyValue("margin-bottom", aMarginBottom); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarginBottom(const nsString& aMarginBottom) +{ + return SetProperty("margin-bottom", aMarginBottom, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarginLeft(nsString& aMarginLeft) +{ + return GetPropertyValue("margin-left", aMarginLeft); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarginLeft(const nsString& aMarginLeft) +{ + return SetProperty("margin-left", aMarginLeft, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarkerOffset(nsString& aMarkerOffset) +{ + return GetPropertyValue("marker-offset", aMarkerOffset); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarkerOffset(const nsString& aMarkerOffset) +{ + return SetProperty("marker-offset", aMarkerOffset, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMarks(nsString& aMarks) +{ + return GetPropertyValue("marks", aMarks); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMarks(const nsString& aMarks) +{ + return SetProperty("marks", aMarks, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMaxHeight(nsString& aMaxHeight) +{ + return GetPropertyValue("max-height", aMaxHeight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMaxHeight(const nsString& aMaxHeight) +{ + return SetProperty("max-height", aMaxHeight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMaxWidth(nsString& aMaxWidth) +{ + return GetPropertyValue("max-width", aMaxWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMaxWidth(const nsString& aMaxWidth) +{ + return SetProperty("max-width", aMaxWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMinHeight(nsString& aMinHeight) +{ + return GetPropertyValue("min-height", aMinHeight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMinHeight(const nsString& aMinHeight) +{ + return SetProperty("min-height", aMinHeight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetMinWidth(nsString& aMinWidth) +{ + return GetPropertyValue("min-width", aMinWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetMinWidth(const nsString& aMinWidth) +{ + return SetProperty("min-width", aMinWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOrphans(nsString& aOrphans) +{ + return GetPropertyValue("orphans", aOrphans); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOrphans(const nsString& aOrphans) +{ + return SetProperty("orphans", aOrphans, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOutline(nsString& aOutline) +{ + return GetPropertyValue("outline", aOutline); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOutline(const nsString& aOutline) +{ + return SetProperty("outline", aOutline, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOutlineColor(nsString& aOutlineColor) +{ + return GetPropertyValue("outline-color", aOutlineColor); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOutlineColor(const nsString& aOutlineColor) +{ + return SetProperty("outline-color", aOutlineColor, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOutlineStyle(nsString& aOutlineStyle) +{ + return GetPropertyValue("outline-style", aOutlineStyle); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOutlineStyle(const nsString& aOutlineStyle) +{ + return SetProperty("outline-style", aOutlineStyle, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOutlineWidth(nsString& aOutlineWidth) +{ + return GetPropertyValue("outline-width", aOutlineWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOutlineWidth(const nsString& aOutlineWidth) +{ + return SetProperty("outline-width", aOutlineWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetOverflow(nsString& aOverflow) +{ + return GetPropertyValue("overflow", aOverflow); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetOverflow(const nsString& aOverflow) +{ + return SetProperty("overflow", aOverflow, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPadding(nsString& aPadding) +{ + return GetPropertyValue("padding", aPadding); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPadding(const nsString& aPadding) +{ + return SetProperty("padding", aPadding, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPaddingTop(nsString& aPaddingTop) +{ + return GetPropertyValue("padding-top", aPaddingTop); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPaddingTop(const nsString& aPaddingTop) +{ + return SetProperty("padding-top", aPaddingTop, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPaddingRight(nsString& aPaddingRight) +{ + return GetPropertyValue("padding-right", aPaddingRight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPaddingRight(const nsString& aPaddingRight) +{ + return SetProperty("padding-right", aPaddingRight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPaddingBottom(nsString& aPaddingBottom) +{ + return GetPropertyValue("padding-bottom", aPaddingBottom); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPaddingBottom(const nsString& aPaddingBottom) +{ + return SetProperty("padding-bottom", aPaddingBottom, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPaddingLeft(nsString& aPaddingLeft) +{ + return GetPropertyValue("padding-left", aPaddingLeft); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPaddingLeft(const nsString& aPaddingLeft) +{ + return SetProperty("padding-left", aPaddingLeft, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPage(nsString& aPage) +{ + return GetPropertyValue("page", aPage); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPage(const nsString& aPage) +{ + return SetProperty("page", aPage, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPageBreakAfter(nsString& aPageBreakAfter) +{ + return GetPropertyValue("page-break-after", aPageBreakAfter); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPageBreakAfter(const nsString& aPageBreakAfter) +{ + return SetProperty("page-break-after", aPageBreakAfter, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPageBreakBefore(nsString& aPageBreakBefore) +{ + return GetPropertyValue("page-break-before", aPageBreakBefore); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPageBreakBefore(const nsString& aPageBreakBefore) +{ + return SetProperty("page-break-before", aPageBreakBefore, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPageBreakInside(nsString& aPageBreakInside) +{ + return GetPropertyValue("page-break-inside", aPageBreakInside); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPageBreakInside(const nsString& aPageBreakInside) +{ + return SetProperty("page-break-inside", aPageBreakInside, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPause(nsString& aPause) +{ + return GetPropertyValue("pause", aPause); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPause(const nsString& aPause) +{ + return SetProperty("pause", aPause, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPauseAfter(nsString& aPauseAfter) +{ + return GetPropertyValue("pause-after", aPauseAfter); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPauseAfter(const nsString& aPauseAfter) +{ + return SetProperty("pause-after", aPauseAfter, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPauseBefore(nsString& aPauseBefore) +{ + return GetPropertyValue("pause-before", aPauseBefore); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPauseBefore(const nsString& aPauseBefore) +{ + return SetProperty("pause-before", aPauseBefore, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPitch(nsString& aPitch) +{ + return GetPropertyValue("pitch", aPitch); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPitch(const nsString& aPitch) +{ + return SetProperty("pitch", aPitch, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPitchRange(nsString& aPitchRange) +{ + return GetPropertyValue("pitch-range", aPitchRange); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPitchRange(const nsString& aPitchRange) +{ + return SetProperty("pitch-range", aPitchRange, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPlayDuring(nsString& aPlayDuring) +{ + return GetPropertyValue("play-during", aPlayDuring); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPlayDuring(const nsString& aPlayDuring) +{ + return SetProperty("play-during", aPlayDuring, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetPosition(nsString& aPosition) +{ + return GetPropertyValue("position", aPosition); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetPosition(const nsString& aPosition) +{ + return SetProperty("position", aPosition, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetQuotes(nsString& aQuotes) +{ + return GetPropertyValue("quotes", aQuotes); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetQuotes(const nsString& aQuotes) +{ + return SetProperty("quotes", aQuotes, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetRichness(nsString& aRichness) +{ + return GetPropertyValue("richness", aRichness); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetRichness(const nsString& aRichness) +{ + return SetProperty("richness", aRichness, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetRight(nsString& aRight) +{ + return GetPropertyValue("right", aRight); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetRight(const nsString& aRight) +{ + return SetProperty("right", aRight, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSize(nsString& aSize) +{ + return GetPropertyValue("size", aSize); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSize(const nsString& aSize) +{ + return SetProperty("size", aSize, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSpeak(nsString& aSpeak) +{ + return GetPropertyValue("speak", aSpeak); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSpeak(const nsString& aSpeak) +{ + return SetProperty("speak", aSpeak, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSpeakHeader(nsString& aSpeakHeader) +{ + return GetPropertyValue("speak-header", aSpeakHeader); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSpeakHeader(const nsString& aSpeakHeader) +{ + return SetProperty("speak-header", aSpeakHeader, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSpeakNumeral(nsString& aSpeakNumeral) +{ + return GetPropertyValue("speak-numeral", aSpeakNumeral); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSpeakNumeral(const nsString& aSpeakNumeral) +{ + return SetProperty("speak-numeral", aSpeakNumeral, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSpeakPunctuation(nsString& aSpeakPunctuation) +{ + return GetPropertyValue("speak-punctuation", aSpeakPunctuation); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSpeakPunctuation(const nsString& aSpeakPunctuation) +{ + return SetProperty("speak-punctuation", aSpeakPunctuation, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetSpeechRate(nsString& aSpeechRate) +{ + return GetPropertyValue("speech-rate", aSpeechRate); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetSpeechRate(const nsString& aSpeechRate) +{ + return SetProperty("speech-rate", aSpeechRate, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetStress(nsString& aStress) +{ + return GetPropertyValue("stress", aStress); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetStress(const nsString& aStress) +{ + return SetProperty("stress", aStress, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTableLayout(nsString& aTableLayout) +{ + return GetPropertyValue("table-layout", aTableLayout); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTableLayout(const nsString& aTableLayout) +{ + return SetProperty("table-layout", aTableLayout, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTextAlign(nsString& aTextAlign) +{ + return GetPropertyValue("text-align", aTextAlign); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTextAlign(const nsString& aTextAlign) +{ + return SetProperty("text-align", aTextAlign, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTextDecoration(nsString& aTextDecoration) +{ + return GetPropertyValue("text-decoration", aTextDecoration); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTextDecoration(const nsString& aTextDecoration) +{ + return SetProperty("text-decoration", aTextDecoration, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTextIndent(nsString& aTextIndent) +{ + return GetPropertyValue("text-indent", aTextIndent); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTextIndent(const nsString& aTextIndent) +{ + return SetProperty("text-indent", aTextIndent, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTextShadow(nsString& aTextShadow) +{ + return GetPropertyValue("text-shadow", aTextShadow); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTextShadow(const nsString& aTextShadow) +{ + return SetProperty("text-shadow", aTextShadow, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTextTransform(nsString& aTextTransform) +{ + return GetPropertyValue("text-transform", aTextTransform); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTextTransform(const nsString& aTextTransform) +{ + return SetProperty("text-transform", aTextTransform, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetTop(nsString& aTop) +{ + return GetPropertyValue("top", aTop); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetTop(const nsString& aTop) +{ + return SetProperty("top", aTop, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetUnicodeBidi(nsString& aUnicodeBidi) +{ + return GetPropertyValue("unicode-bidi", aUnicodeBidi); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetUnicodeBidi(const nsString& aUnicodeBidi) +{ + return SetProperty("unicode-bidi", aUnicodeBidi, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetVerticalAlign(nsString& aVerticalAlign) +{ + return GetPropertyValue("vertical-align", aVerticalAlign); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetVerticalAlign(const nsString& aVerticalAlign) +{ + return SetProperty("vertical-align", aVerticalAlign, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetVisibility(nsString& aVisibility) +{ + return GetPropertyValue("visibility", aVisibility); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetVisibility(const nsString& aVisibility) +{ + return SetProperty("visibility", aVisibility, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetVoiceFamily(nsString& aVoiceFamily) +{ + return GetPropertyValue("voice-family", aVoiceFamily); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetVoiceFamily(const nsString& aVoiceFamily) +{ + return SetProperty("voice-family", aVoiceFamily, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetVolume(nsString& aVolume) +{ + return GetPropertyValue("volume", aVolume); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetVolume(const nsString& aVolume) +{ + return SetProperty("volume", aVolume, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetWhiteSpace(nsString& aWhiteSpace) +{ + return GetPropertyValue("white-space", aWhiteSpace); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetWhiteSpace(const nsString& aWhiteSpace) +{ + return SetProperty("white-space", aWhiteSpace, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetWidows(nsString& aWidows) +{ + return GetPropertyValue("widows", aWidows); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetWidows(const nsString& aWidows) +{ + return SetProperty("widows", aWidows, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetWidth(nsString& aWidth) +{ + return GetPropertyValue("width", aWidth); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetWidth(const nsString& aWidth) +{ + return SetProperty("width", aWidth, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetWordSpacing(nsString& aWordSpacing) +{ + return GetPropertyValue("word-spacing", aWordSpacing); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetWordSpacing(const nsString& aWordSpacing) +{ + return SetProperty("word-spacing", aWordSpacing, ""); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::GetZIndex(nsString& aZIndex) +{ + return GetPropertyValue("z-index", aZIndex); +} + +NS_IMETHODIMP +nsDOMStyleDeclaration::SetZIndex(const nsString& aZIndex) +{ + return SetProperty("z-index", aZIndex, ""); +} + diff --git a/mozilla/layout/html/content/src/nsDOMStyleDeclaration.h b/mozilla/layout/html/content/src/nsDOMStyleDeclaration.h new file mode 100644 index 00000000000..bd9699a8cdd --- /dev/null +++ b/mozilla/layout/html/content/src/nsDOMStyleDeclaration.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ +#ifndef nsDOMStyleDeclaration_h___ +#define nsDOMStyleDeclaration_h___ + +#include "nsISupports.h" +#include "nsIDOMCSSStyleDeclaration.h" +#include "nsIScriptObjectOwner.h" + +class nsIHTMLContent; +class nsICSSDeclaration; + +class nsDOMStyleDeclaration : public nsIDOMCSSStyleDeclaration, + public nsIScriptObjectOwner +{ +public: + nsDOMStyleDeclaration(nsIHTMLContent *aContent); + virtual ~nsDOMStyleDeclaration(); + + NS_DECL_ISUPPORTS + + NS_DECL_IDOMCSSSTYLEDECLARATION + + // nsIScriptObjectOwner interface + NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); + NS_IMETHOD SetScriptObject(void* aScriptObject); + + void DropContent(); + +protected: + nsresult GetContentStyle(nsICSSDeclaration **aDecl, PRBool aAllocate); + + void *mScriptObject; + nsIHTMLContent *mContent; +}; + +#endif // nsDOMStyleDeclaration_h___ diff --git a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp index e9e99b00ed6..b8c125b256c 100644 --- a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp @@ -59,7 +59,10 @@ #include "nsDOMCID.h" #include "nsIServiceManager.h" #include "nsIDOMScriptObjectFactory.h" +#include "nsIDOMCSSStyleDeclaration.h" +#include "nsDOMStyleDeclaration.h" #include "prprf.h" +#include "prmem.h" // XXX todo: add in missing out-of-memory checks @@ -80,6 +83,7 @@ static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID); +static NS_DEFINE_IID(kIDOMCSSStyleDeclarationIID, NS_IDOMCSSSTYLEDECLARATION_IID); // Attribute helper class used to wrap up an attribute with a dom // object that implements nsIDOMAttribute and nsIDOMNode and @@ -160,7 +164,7 @@ class nsChildContentList : public nsIDOMNodeList, public nsIScriptObjectOwner { public: - nsChildContentList(); + nsChildContentList(nsGenericHTMLContainerElement *aContent); virtual ~nsChildContentList() {} NS_DECL_ISUPPORTS @@ -171,24 +175,10 @@ public: // nsIDOMNodeList interface NS_DECL_IDOMNODELIST - // Methods stolen from nsVoidArray - PRInt32 Count() { return mArray.Count(); } - nsIContent* ElementAt(PRInt32 aIndex) const - { return (nsIContent*)mArray.ElementAt(aIndex); } - PRBool InsertElementAt(nsIContent* aElement, PRInt32 aIndex) - { return mArray.InsertElementAt(aElement, aIndex); } - PRBool ReplaceElementAt(nsIContent* aElement, PRInt32 aIndex) - { return mArray.ReplaceElementAt(aElement, aIndex); } - PRBool AppendElement(nsIContent* aElement) - { return mArray.AppendElement(aElement); } - PRBool RemoveElementAt(PRInt32 aIndex) - { return mArray.RemoveElementAt(aIndex); } - PRInt32 IndexOf(nsIContent* aPossibleElement) const - { return mArray.IndexOf(aPossibleElement); } - void Compact() { mArray.Compact(); } + void DropContent(); private: - nsVoidArray mArray; + nsGenericHTMLContainerElement *mContent; void *mScriptObject; }; @@ -638,7 +628,7 @@ nsGenericHTMLElement::nsGenericHTMLElement() mAttributes = nsnull; mTag = nsnull; mContent = nsnull; - mScriptObject = nsnull; + mDOMSlots = nsnull; mListenerManager = nsnull; } @@ -649,7 +639,31 @@ nsGenericHTMLElement::~nsGenericHTMLElement() } NS_IF_RELEASE(mTag); NS_IF_RELEASE(mListenerManager); - // XXX what about mScriptObject? it's now safe to GC it... + if (nsnull != mDOMSlots) { + if (nsnull != mDOMSlots->mChildNodes) { + mDOMSlots->mChildNodes->DropContent(); + NS_RELEASE(mDOMSlots->mChildNodes); + } + if (nsnull != mDOMSlots->mStyle) { + mDOMSlots->mStyle->DropContent(); + NS_RELEASE(mDOMSlots->mStyle); + } + // XXX Should really be arena managed + PR_DELETE(mDOMSlots); + } +} + +nsDOMSlots * +nsGenericHTMLElement::GetDOMSlots() +{ + if (nsnull == mDOMSlots) { + mDOMSlots = PR_NEW(nsDOMSlots); + mDOMSlots->mScriptObject = nsnull; + mDOMSlots->mChildNodes = nsnull; + mDOMSlots->mStyle = nsnull; + } + + return mDOMSlots; } void @@ -933,6 +947,26 @@ nsGenericHTMLElement::SetClassName(const nsString& aClassName) return NS_OK; } +nsresult +nsGenericHTMLElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) +{ + nsresult res = NS_OK; + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mStyle) { + slots->mStyle = new nsDOMStyleDeclaration(mContent); + if (nsnull == slots->mStyle) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(slots->mStyle); + } + + res = slots->mStyle->QueryInterface(kIDOMCSSStyleDeclarationIID, + (void **)aStyle); + + return res; +} + nsresult nsGenericHTMLElement::GetDocument(nsIDocument*& aResult) const { @@ -1655,7 +1689,9 @@ nsGenericHTMLElement::GetScriptObject(nsIScriptContext* aContext, void** aScriptObject) { nsresult res = NS_OK; - if (nsnull == mScriptObject) { + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mScriptObject) { nsIDOMScriptObjectFactory *factory; res = GetScriptObjectFactory(&factory); @@ -1666,17 +1702,19 @@ nsGenericHTMLElement::GetScriptObject(nsIScriptContext* aContext, nsAutoString tag; mTag->ToString(tag); res = factory->NewScriptElement(tag, aContext, mContent, - mParent, (void**)&mScriptObject); + mParent, (void**)&slots->mScriptObject); NS_RELEASE(factory); } - *aScriptObject = mScriptObject; + *aScriptObject = slots->mScriptObject; return res; } nsresult nsGenericHTMLElement::SetScriptObject(void *aScriptObject) { - mScriptObject = aScriptObject; + nsDOMSlots *slots = GetDOMSlots(); + + slots->mScriptObject = aScriptObject; return NS_OK; } @@ -2680,6 +2718,20 @@ nsGenericHTMLLeafElement::Equals(nsIDOMNode* aNode, PRBool aDeep, return NS_OK; } +nsresult +nsGenericHTMLLeafElement::GetChildNodes(nsIDOMNodeList** aChildNodes) +{ + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mChildNodes) { + slots->mChildNodes = new nsChildContentList(nsnull); + NS_ADDREF(slots->mChildNodes); + } + + return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); +} + + nsresult nsGenericHTMLLeafElement::BeginConvertToXIF(nsXIFConverter& aConverter) const { @@ -2745,9 +2797,12 @@ nsGenericHTMLLeafElement::SizeOf(nsISizeOfHandler* aHandler) const //---------------------------------------------------------------------- -nsChildContentList::nsChildContentList() +nsChildContentList::nsChildContentList(nsGenericHTMLContainerElement *aContent) { NS_INIT_REFCNT(); + // This reference is not reference-counted. The content + // object tells us when its about to go away. + mContent = aContent; mScriptObject = nsnull; } @@ -2787,7 +2842,7 @@ nsChildContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptOb { nsresult res = NS_OK; if (nsnull == mScriptObject) { - res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, nsnull, (void**)&mScriptObject); + res = NS_NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, mContent, (void**)&mScriptObject); } *aScriptObject = mScriptObject; return res; @@ -2803,7 +2858,14 @@ nsChildContentList::SetScriptObject(void *aScriptObject) NS_IMETHODIMP nsChildContentList::GetLength(PRUint32* aLength) { - *aLength = (PRUint32)mArray.Count(); + if (nsnull != mContent) { + PRInt32 length; + mContent->ChildCount(length); + *aLength = (PRUint32)length; + } + else { + *aLength = 0; + } return NS_OK; } @@ -2813,9 +2875,14 @@ nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) nsIContent *content; nsresult res = NS_OK; - content = (nsIContent *)mArray.ElementAt(aIndex); - if (nsnull != content) { - res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + if (nsnull != mContent) { + mContent->ChildAt(aIndex, content); + if (nsnull != content) { + res = content->QueryInterface(kIDOMNodeIID, (void**)aReturn); + } + else { + *aReturn = nsnull; + } } else { *aReturn = nsnull; @@ -2824,23 +2891,25 @@ nsChildContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn) return res; } +void +nsChildContentList::DropContent() +{ + mContent = nsnull; +} //---------------------------------------------------------------------- nsGenericHTMLContainerElement::nsGenericHTMLContainerElement() { - mChildren = new nsChildContentList(); - mChildren->AddRef(); } nsGenericHTMLContainerElement::~nsGenericHTMLContainerElement() { - PRInt32 n = mChildren->Count(); + PRInt32 n = mChildren.Count(); for (PRInt32 i = 0; i < n; i++) { - nsIContent* kid = mChildren->ElementAt(i); + nsIContent* kid = (nsIContent *)mChildren.ElementAt(i); NS_RELEASE(kid); } - mChildren->Release(); } nsresult @@ -2866,13 +2935,20 @@ nsGenericHTMLContainerElement::Equals(nsIDOMNode* aNode, PRBool aDeep, nsresult nsGenericHTMLContainerElement::GetChildNodes(nsIDOMNodeList** aChildNodes) { - return mChildren->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); + nsDOMSlots *slots = GetDOMSlots(); + + if (nsnull == slots->mChildNodes) { + slots->mChildNodes = new nsChildContentList(this); + NS_ADDREF(slots->mChildNodes); + } + + return slots->mChildNodes->QueryInterface(kIDOMNodeListIID, (void **)aChildNodes); } nsresult nsGenericHTMLContainerElement::GetHasChildNodes(PRBool* aReturn) { - if (0 != mChildren->Count()) { + if (0 != mChildren.Count()) { *aReturn = PR_TRUE; } else { @@ -2884,7 +2960,7 @@ nsGenericHTMLContainerElement::GetHasChildNodes(PRBool* aReturn) nsresult nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) { - nsIContent *child = mChildren->ElementAt(0); + nsIContent *child = (nsIContent *)mChildren.ElementAt(0); if (nsnull != child) { nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node @@ -2897,7 +2973,7 @@ nsGenericHTMLContainerElement::GetFirstChild(nsIDOMNode** aNode) nsresult nsGenericHTMLContainerElement::GetLastChild(nsIDOMNode** aNode) { - nsIContent *child = mChildren->ElementAt(mChildren->Count()-1); + nsIContent *child = (nsIContent *)mChildren.ElementAt(mChildren.Count()-1); if (nsnull != child) { nsresult res = child->QueryInterface(kIDOMNodeIID, (void**)aNode); NS_ASSERTION(NS_OK == res, "Must be a DOM Node"); // must be a DOM Node @@ -3094,7 +3170,7 @@ nsGenericHTMLContainerElement::FinishConvertToXIF(nsXIFConverter& aConverter) co nsresult nsGenericHTMLContainerElement::Compact() { - mChildren->Compact(); + mChildren.Compact(); return NS_OK; } @@ -3108,7 +3184,7 @@ nsGenericHTMLContainerElement::CanContainChildren(PRBool& aResult) const nsresult nsGenericHTMLContainerElement::ChildCount(PRInt32& aCount) const { - aCount = mChildren->Count(); + aCount = mChildren.Count(); return NS_OK; } @@ -3116,7 +3192,7 @@ nsresult nsGenericHTMLContainerElement::ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { - nsIContent *child = mChildren->ElementAt(aIndex); + nsIContent *child = (nsIContent *)mChildren.ElementAt(aIndex); if (nsnull != child) { NS_ADDREF(child); } @@ -3129,7 +3205,7 @@ nsGenericHTMLContainerElement::IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const { NS_PRECONDITION(nsnull != aPossibleChild, "null ptr"); - aIndex = mChildren->IndexOf(aPossibleChild); + aIndex = mChildren.IndexOf(aPossibleChild); return NS_OK; } @@ -3139,7 +3215,7 @@ nsGenericHTMLContainerElement::InsertChildAt(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION(nsnull != aKid, "null ptr"); - PRBool rv = mChildren->InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/ + PRBool rv = mChildren.InsertElementAt(aKid, aIndex);/* XXX fix up void array api to use nsresult's*/ if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3160,8 +3236,8 @@ nsGenericHTMLContainerElement::ReplaceChildAt(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION(nsnull != aKid, "null ptr"); - nsIContent* oldKid = mChildren->ElementAt(aIndex); - PRBool rv = mChildren->ReplaceElementAt(aKid, aIndex); + nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); + PRBool rv = mChildren.ReplaceElementAt(aKid, aIndex); if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3183,7 +3259,7 @@ nsresult nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) { NS_PRECONDITION((nsnull != aKid) && (aKid != mContent), "null ptr"); - PRBool rv = mChildren->AppendElement(aKid); + PRBool rv = mChildren.AppendElement(aKid); if (rv) { NS_ADDREF(aKid); aKid->SetParent(mContent); @@ -3191,7 +3267,7 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) if (nsnull != doc) { aKid->SetDocument(doc); if (aNotify) { - doc->ContentAppended(mContent, mChildren->Count() - 1); + doc->ContentAppended(mContent, mChildren.Count() - 1); } } } @@ -3201,10 +3277,10 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify) nsresult nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { - nsIContent* oldKid = mChildren->ElementAt(aIndex); + nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex); if (nsnull != oldKid ) { nsIDocument* doc = mDocument; - PRBool rv = mChildren->RemoveElementAt(aIndex); + PRBool rv = mChildren.RemoveElementAt(aIndex); if (aNotify) { if (nsnull != doc) { doc->ContentRemoved(mContent, oldKid, aIndex); diff --git a/mozilla/layout/html/content/src/nsGenericHTMLElement.h b/mozilla/layout/html/content/src/nsGenericHTMLElement.h index 6eaa886f9a2..693510e0771 100644 --- a/mozilla/layout/html/content/src/nsGenericHTMLElement.h +++ b/mozilla/layout/html/content/src/nsGenericHTMLElement.h @@ -47,6 +47,20 @@ class nsIStyleRule; class nsISupportsArray; class nsIDOMScriptObjectFactory; class nsChildContentList; +class nsDOMStyleDeclaration; + + +// There are a set of DOM- and scripting-specific instance variables +// that may only be instantiated when a content object is accessed +// through the DOM. Rather than burn actual slots in the content +// objects for each of these instance variables, we put them off +// in a side structure that's only allocated when the content is +// accessed through the DOM. +typedef struct { + void *mScriptObject; + nsChildContentList *mChildNodes; + nsDOMStyleDeclaration *mStyle; +} nsDOMSlots; class nsGenericHTMLElement : public nsIJSScriptObject { public: @@ -89,6 +103,7 @@ public: nsresult SetDir(const nsString& aDir); nsresult GetClassName(nsString& aClassName); nsresult SetClassName(const nsString& aClassName); + nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle); // nsIDOMEventReceiver interface nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); @@ -152,7 +167,10 @@ public: virtual void Finalize(JSContext *aContext); // Implementation for nsISupports - NS_DECL_ISUPPORTS + NS_IMETHOD QueryInterface(REFNSIID aIID, + void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void); + NS_IMETHOD_(nsrefcnt) Release(void); //---------------------------------------- @@ -289,6 +307,8 @@ public: static nsIDOMScriptObjectFactory *gScriptObjectFactory; + nsDOMSlots *GetDOMSlots(); + // Up pointer to the real content object that we are // supporting. Sometimes there is work that we just can't do // ourselves, so this is needed to ask the real object to do the @@ -299,8 +319,8 @@ public: nsIContent* mParent; nsIHTMLAttributes* mAttributes; nsIAtom* mTag; - void* mScriptObject; nsIEventListenerManager* mListenerManager; + nsDOMSlots *mDOMSlots; }; //---------------------------------------------------------------------- @@ -315,10 +335,7 @@ public: // Remainder of nsIDOMHTMLElement (and nsIDOMNode) nsresult Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn); - nsresult GetChildNodes(nsIDOMNodeList** aChildNodes) { - *aChildNodes = nsnull; - return NS_OK; - } + nsresult GetChildNodes(nsIDOMNodeList** aChildNodes); nsresult GetHasChildNodes(PRBool* aHasChildNodes) { *aHasChildNodes = PR_FALSE; return NS_OK; @@ -422,7 +439,7 @@ public: nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify); nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify); - nsChildContentList *mChildren; + nsVoidArray mChildren; }; //---------------------------------------------------------------------- @@ -562,6 +579,9 @@ public: } \ NS_IMETHOD SetClassName(const nsString& aClassName) { \ return _g.SetClassName(aClassName); \ + } \ + NS_IMETHOD GetStyle(nsIDOMCSSStyleDeclaration** aStyle) { \ + return _g.GetStyle(aStyle); \ } /** diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index ad359d96e12..11b8948c487 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -518,8 +518,8 @@ nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets) NS_ADDREF(mApplets); } - *aApplets = (nsIDOMHTMLCollection *)mImages; - NS_ADDREF(mImages); + *aApplets = (nsIDOMHTMLCollection *)mApplets; + NS_ADDREF(mApplets); return NS_OK; } @@ -829,8 +829,18 @@ nsHTMLDocument::GetLastModified(nsString& aLastModified) NS_IMETHODIMP nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds) { - //XXX TBI - return NS_ERROR_NOT_IMPLEMENTED; + if (nsnull == mEmbeds) { + mEmbeds = new nsContentList(this, "EMBED"); + if (nsnull == mEmbeds) { + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(mEmbeds); + } + + *aEmbeds = (nsIDOMHTMLCollection *)mEmbeds; + NS_ADDREF(mEmbeds); + + return NS_OK; } NS_IMETHODIMP diff --git a/mozilla/layout/html/style/public/nsICSSParser.h b/mozilla/layout/html/style/public/nsICSSParser.h index b12e3eff839..1dfd596f1d5 100644 --- a/mozilla/layout/html/style/public/nsICSSParser.h +++ b/mozilla/layout/html/style/public/nsICSSParser.h @@ -25,6 +25,7 @@ class nsIStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; +class nsICSSDeclaration; #define NS_ICSS_PARSER_IID \ { 0xcc9c0610, 0x968c, 0x11d1, \ @@ -51,6 +52,11 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult) = 0; + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) = 0; + }; // Values or'd in the GetInfoMask; other bits are reserved diff --git a/mozilla/layout/html/style/src/nsCSSDeclaration.cpp b/mozilla/layout/html/style/src/nsCSSDeclaration.cpp index 4c6bfa05c43..5cfeaef158d 100644 --- a/mozilla/layout/html/style/src/nsCSSDeclaration.cpp +++ b/mozilla/layout/html/style/src/nsCSSDeclaration.cpp @@ -268,6 +268,118 @@ nsCSSValue::~nsCSSValue(void) Reset(); } +// XXX shouldn't this get moved to color code? +static const char* RGBToCSSString(nscolor aColor) +{ + const char* result = nsnull; + + PRInt32 r = NS_GET_R(aColor); + PRInt32 g = NS_GET_G(aColor); + PRInt32 b = NS_GET_B(aColor); + + PRInt32 index = 0; + PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); + CSSColorEntry* entry = nsnull; + + for (index = 0; index < count; index++) + { + entry = &css_rgb_table[index]; + if (entry->r == r) + { + if (entry->g == g && entry->b == b) + { + result = entry->name; + break; + } + } + else if (entry->r > r) + { + break; + } + } + return result; +} + + +void +nsCSSValue::ValueToString(nsString& aBuffer, const nsCSSValue& aValue, + PRInt32 aPropID) +{ + nsCSSUnit unit = aValue.GetUnit(); + + if (eCSSUnit_Null == unit) { + return; + } + + if (eCSSUnit_String == unit) { + nsAutoString buffer; + aValue.GetStringValue(buffer); + aBuffer.Append(buffer); + } + else if (eCSSUnit_Integer == unit) { + aBuffer.Append(aValue.GetIntValue(), 10); + } + else if (eCSSUnit_Enumerated == unit) { + const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); + if (name != nsnull) { + aBuffer.Append(name); + } + } + else if (eCSSUnit_Color == unit){ + nscolor color = aValue.GetColorValue(); + const char* name = RGBToCSSString(color); + + if (name != nsnull) + aBuffer.Append(name); + else + { + aBuffer.Append("rgb("); + aBuffer.Append(NS_GET_R(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_G(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_B(color), 10); + aBuffer.Append(')'); + } + } + else if (eCSSUnit_Percent == unit) { + aBuffer.Append(aValue.GetPercentValue() * 100.0f); + } + else if (eCSSUnit_Percent < unit) { // length unit + aBuffer.Append(aValue.GetFloatValue()); + } + + switch (unit) { + case eCSSUnit_Null: break; + case eCSSUnit_Auto: aBuffer.Append("auto"); break; + case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; + case eCSSUnit_None: aBuffer.Append("none"); break; + case eCSSUnit_Normal: aBuffer.Append("normal"); break; + case eCSSUnit_String: break; + case eCSSUnit_Integer: break; + case eCSSUnit_Enumerated: break; + case eCSSUnit_Color: break; + case eCSSUnit_Percent: aBuffer.Append("%"); break; + case eCSSUnit_Number: break; + case eCSSUnit_Inch: aBuffer.Append("in"); break; + case eCSSUnit_Foot: aBuffer.Append("ft"); break; + case eCSSUnit_Mile: aBuffer.Append("mi"); break; + case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; + case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; + case eCSSUnit_Meter: aBuffer.Append("m"); break; + case eCSSUnit_Kilometer: aBuffer.Append("km"); break; + case eCSSUnit_Point: aBuffer.Append("pt"); break; + case eCSSUnit_Pica: aBuffer.Append("pc"); break; + case eCSSUnit_Didot: aBuffer.Append("dt"); break; + case eCSSUnit_Cicero: aBuffer.Append("cc"); break; + case eCSSUnit_EM: aBuffer.Append("em"); break; + case eCSSUnit_EN: aBuffer.Append("en"); break; + case eCSSUnit_XHeight: aBuffer.Append("ex"); break; + case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; + case eCSSUnit_Pixel: aBuffer.Append("px"); break; + } +} + nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); @@ -772,7 +884,7 @@ void nsCSSList::List(FILE* out, PRInt32 aIndent) const class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); - + CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); @@ -791,10 +903,14 @@ public: nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); - + nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); + virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsresult Count(PRUint32* aCount); + nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); @@ -2211,115 +2327,25 @@ nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) return NS_OK; } -// XXX shouldn't this get moved to color code? -static const char* RGBToCSSString(nscolor aColor) +nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, + PRBool& aIsImportant) { - const char* result = nsnull; + nsCSSValue val; - PRInt32 r = NS_GET_R(aColor); - PRInt32 g = NS_GET_G(aColor); - PRInt32 b = NS_GET_B(aColor); - - PRInt32 index = 0; - PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); - CSSColorEntry* entry = nsnull; - - for (index = 0; index < count; index++) - { - entry = &css_rgb_table[index]; - if (entry->r == r) - { - if (entry->g == g && entry->b == b) - { - result = entry->name; - break; - } + if (nsnull != mImportant) { + mImportant->GetValue(aProperty, val); + if (eCSSUnit_Null != val.GetUnit()) { + aIsImportant = PR_TRUE; } - else if (entry->r > r) - { - break; + else { + aIsImportant = PR_FALSE; } } - return result; -} - - -static void -ValueToString(const nsCSSValue& aValue, PRInt32 aPropID, nsString& aBuffer) -{ - nsCSSUnit unit = aValue.GetUnit(); - - if (eCSSUnit_Null == unit) { - return; + else { + aIsImportant = PR_FALSE; } - if (eCSSUnit_String == unit) { - nsAutoString buffer; - aValue.GetStringValue(buffer); - aBuffer.Append(buffer); - } - else if (eCSSUnit_Integer == unit) { - aBuffer.Append(aValue.GetIntValue(), 10); - } - else if (eCSSUnit_Enumerated == unit) { - const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); - if (name != nsnull) { - aBuffer.Append(name); - } - } - else if (eCSSUnit_Color == unit){ - nscolor color = aValue.GetColorValue(); - const char* name = RGBToCSSString(color); - - if (name != nsnull) - aBuffer.Append(name); - else - { - aBuffer.Append("rgb("); - aBuffer.Append(NS_GET_R(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_G(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_B(color), 10); - aBuffer.Append(')'); - } - } - else if (eCSSUnit_Percent == unit) { - aBuffer.Append(aValue.GetPercentValue() * 100.0f); - } - else if (eCSSUnit_Percent < unit) { // length unit - aBuffer.Append(aValue.GetFloatValue()); - } - - switch (unit) { - case eCSSUnit_Null: break; - case eCSSUnit_Auto: aBuffer.Append("auto"); break; - case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; - case eCSSUnit_None: aBuffer.Append("none"); break; - case eCSSUnit_Normal: aBuffer.Append("normal"); break; - case eCSSUnit_String: break; - case eCSSUnit_Integer: break; - case eCSSUnit_Enumerated: break; - case eCSSUnit_Color: break; - case eCSSUnit_Percent: aBuffer.Append("%"); break; - case eCSSUnit_Number: break; - case eCSSUnit_Inch: aBuffer.Append("in"); break; - case eCSSUnit_Foot: aBuffer.Append("ft"); break; - case eCSSUnit_Mile: aBuffer.Append("mi"); break; - case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; - case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; - case eCSSUnit_Meter: aBuffer.Append("m"); break; - case eCSSUnit_Kilometer: aBuffer.Append("km"); break; - case eCSSUnit_Point: aBuffer.Append("pt"); break; - case eCSSUnit_Pica: aBuffer.Append("pc"); break; - case eCSSUnit_Didot: aBuffer.Append("dt"); break; - case eCSSUnit_Cicero: aBuffer.Append("cc"); break; - case eCSSUnit_EM: aBuffer.Append("em"); break; - case eCSSUnit_EN: aBuffer.Append("en"); break; - case eCSSUnit_XHeight: aBuffer.Append("ex"); break; - case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; - case eCSSUnit_Pixel: aBuffer.Append("px"); break; - } + return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) @@ -2347,7 +2373,7 @@ nsresult CSSDeclarationImpl::ToString(nsString& aString) } aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); - ValueToString(value, property, aString); + nsCSSValue::ValueToString(aString, value, property); if (PR_TRUE == important) { aString.Append(" ! important"); } @@ -2400,6 +2426,34 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +nsresult +CSSDeclarationImpl::Count(PRUint32* aCount) +{ + if (nsnull != mOrder) { + *aCount = (PRUint32)mOrder->Count(); + } + else { + *aCount = 0; + } + + return NS_OK; +} + +nsresult +CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) +{ + aReturn.SetLength(0); + if (nsnull != mOrder) { + PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); + if (0 <= property) { + aReturn.Append(nsCSSProps::kNameTable[property].name); + } + } + + return NS_OK; +} + + NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { diff --git a/mozilla/layout/html/style/src/nsCSSParser.cpp b/mozilla/layout/html/style/src/nsCSSParser.cpp index 75f07413ca0..92cc83485a1 100644 --- a/mozilla/layout/html/style/src/nsCSSParser.cpp +++ b/mozilla/layout/html/style/src/nsCSSParser.cpp @@ -202,6 +202,10 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult); + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration); protected: PRBool GetToken(PRInt32* aErrorCode, PRBool aSkipWS); @@ -448,6 +452,40 @@ CSSParserImpl::ParseDeclarations(const nsString& aDeclaration, return NS_OK; } +NS_METHOD +CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) +{ + nsString* str = new nsString(aBuffer); + if (nsnull == str) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsIUnicharInputStream* input = nsnull; + nsresult rv = NS_NewStringUnicharInputStream(&input, str); + if (NS_OK != rv) { + return rv; + } + + mScanner = new nsCSSScanner(); + mScanner->Init(input); + NS_RELEASE(input); + + mURL = aBaseURL; + NS_IF_ADDREF(mURL); + + mInHead = PR_FALSE; + PRInt32 errorCode = NS_OK; + + ParseDeclaration(&errorCode, &aDeclaration, PR_FALSE); + + delete mScanner; + mScanner = nsnull; + NS_IF_RELEASE(mURL); + + return NS_OK; +} + //---------------------------------------------------------------------- PRBool CSSParserImpl::GetToken(PRInt32* aErrorCode, PRBool aSkipWS) diff --git a/mozilla/layout/html/style/src/nsICSSDeclaration.h b/mozilla/layout/html/style/src/nsICSSDeclaration.h index 646563e2fb5..255b79939f5 100644 --- a/mozilla/layout/html/style/src/nsICSSDeclaration.h +++ b/mozilla/layout/html/style/src/nsICSSDeclaration.h @@ -112,6 +112,10 @@ public: void SetNoneValue(void); void SetNormalValue(void); + static void ValueToString(nsString& aBuffer, + const nsCSSValue& aValue, + PRInt32 aPropID = -1); + // debugging methods void AppendToString(nsString& aBuffer, PRInt32 aPropID = -1) const; void ToString(nsString& aBuffer, PRInt32 aPropID = -1) const; @@ -326,6 +330,10 @@ public: virtual nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue) = 0; virtual nsresult GetImportantValues(nsICSSDeclaration*& aResult) = 0; + virtual nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant) = 0; + + virtual nsresult Count(PRUint32* aCount) = 0; + virtual nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn) = 0; virtual nsresult ToString(nsString& aString) = 0; diff --git a/mozilla/layout/style/nsCSSDeclaration.cpp b/mozilla/layout/style/nsCSSDeclaration.cpp index 4c6bfa05c43..5cfeaef158d 100644 --- a/mozilla/layout/style/nsCSSDeclaration.cpp +++ b/mozilla/layout/style/nsCSSDeclaration.cpp @@ -268,6 +268,118 @@ nsCSSValue::~nsCSSValue(void) Reset(); } +// XXX shouldn't this get moved to color code? +static const char* RGBToCSSString(nscolor aColor) +{ + const char* result = nsnull; + + PRInt32 r = NS_GET_R(aColor); + PRInt32 g = NS_GET_G(aColor); + PRInt32 b = NS_GET_B(aColor); + + PRInt32 index = 0; + PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); + CSSColorEntry* entry = nsnull; + + for (index = 0; index < count; index++) + { + entry = &css_rgb_table[index]; + if (entry->r == r) + { + if (entry->g == g && entry->b == b) + { + result = entry->name; + break; + } + } + else if (entry->r > r) + { + break; + } + } + return result; +} + + +void +nsCSSValue::ValueToString(nsString& aBuffer, const nsCSSValue& aValue, + PRInt32 aPropID) +{ + nsCSSUnit unit = aValue.GetUnit(); + + if (eCSSUnit_Null == unit) { + return; + } + + if (eCSSUnit_String == unit) { + nsAutoString buffer; + aValue.GetStringValue(buffer); + aBuffer.Append(buffer); + } + else if (eCSSUnit_Integer == unit) { + aBuffer.Append(aValue.GetIntValue(), 10); + } + else if (eCSSUnit_Enumerated == unit) { + const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); + if (name != nsnull) { + aBuffer.Append(name); + } + } + else if (eCSSUnit_Color == unit){ + nscolor color = aValue.GetColorValue(); + const char* name = RGBToCSSString(color); + + if (name != nsnull) + aBuffer.Append(name); + else + { + aBuffer.Append("rgb("); + aBuffer.Append(NS_GET_R(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_G(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_B(color), 10); + aBuffer.Append(')'); + } + } + else if (eCSSUnit_Percent == unit) { + aBuffer.Append(aValue.GetPercentValue() * 100.0f); + } + else if (eCSSUnit_Percent < unit) { // length unit + aBuffer.Append(aValue.GetFloatValue()); + } + + switch (unit) { + case eCSSUnit_Null: break; + case eCSSUnit_Auto: aBuffer.Append("auto"); break; + case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; + case eCSSUnit_None: aBuffer.Append("none"); break; + case eCSSUnit_Normal: aBuffer.Append("normal"); break; + case eCSSUnit_String: break; + case eCSSUnit_Integer: break; + case eCSSUnit_Enumerated: break; + case eCSSUnit_Color: break; + case eCSSUnit_Percent: aBuffer.Append("%"); break; + case eCSSUnit_Number: break; + case eCSSUnit_Inch: aBuffer.Append("in"); break; + case eCSSUnit_Foot: aBuffer.Append("ft"); break; + case eCSSUnit_Mile: aBuffer.Append("mi"); break; + case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; + case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; + case eCSSUnit_Meter: aBuffer.Append("m"); break; + case eCSSUnit_Kilometer: aBuffer.Append("km"); break; + case eCSSUnit_Point: aBuffer.Append("pt"); break; + case eCSSUnit_Pica: aBuffer.Append("pc"); break; + case eCSSUnit_Didot: aBuffer.Append("dt"); break; + case eCSSUnit_Cicero: aBuffer.Append("cc"); break; + case eCSSUnit_EM: aBuffer.Append("em"); break; + case eCSSUnit_EN: aBuffer.Append("en"); break; + case eCSSUnit_XHeight: aBuffer.Append("ex"); break; + case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; + case eCSSUnit_Pixel: aBuffer.Append("px"); break; + } +} + nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); @@ -772,7 +884,7 @@ void nsCSSList::List(FILE* out, PRInt32 aIndent) const class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); - + CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); @@ -791,10 +903,14 @@ public: nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); - + nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); + virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsresult Count(PRUint32* aCount); + nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); @@ -2211,115 +2327,25 @@ nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) return NS_OK; } -// XXX shouldn't this get moved to color code? -static const char* RGBToCSSString(nscolor aColor) +nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, + PRBool& aIsImportant) { - const char* result = nsnull; + nsCSSValue val; - PRInt32 r = NS_GET_R(aColor); - PRInt32 g = NS_GET_G(aColor); - PRInt32 b = NS_GET_B(aColor); - - PRInt32 index = 0; - PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); - CSSColorEntry* entry = nsnull; - - for (index = 0; index < count; index++) - { - entry = &css_rgb_table[index]; - if (entry->r == r) - { - if (entry->g == g && entry->b == b) - { - result = entry->name; - break; - } + if (nsnull != mImportant) { + mImportant->GetValue(aProperty, val); + if (eCSSUnit_Null != val.GetUnit()) { + aIsImportant = PR_TRUE; } - else if (entry->r > r) - { - break; + else { + aIsImportant = PR_FALSE; } } - return result; -} - - -static void -ValueToString(const nsCSSValue& aValue, PRInt32 aPropID, nsString& aBuffer) -{ - nsCSSUnit unit = aValue.GetUnit(); - - if (eCSSUnit_Null == unit) { - return; + else { + aIsImportant = PR_FALSE; } - if (eCSSUnit_String == unit) { - nsAutoString buffer; - aValue.GetStringValue(buffer); - aBuffer.Append(buffer); - } - else if (eCSSUnit_Integer == unit) { - aBuffer.Append(aValue.GetIntValue(), 10); - } - else if (eCSSUnit_Enumerated == unit) { - const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); - if (name != nsnull) { - aBuffer.Append(name); - } - } - else if (eCSSUnit_Color == unit){ - nscolor color = aValue.GetColorValue(); - const char* name = RGBToCSSString(color); - - if (name != nsnull) - aBuffer.Append(name); - else - { - aBuffer.Append("rgb("); - aBuffer.Append(NS_GET_R(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_G(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_B(color), 10); - aBuffer.Append(')'); - } - } - else if (eCSSUnit_Percent == unit) { - aBuffer.Append(aValue.GetPercentValue() * 100.0f); - } - else if (eCSSUnit_Percent < unit) { // length unit - aBuffer.Append(aValue.GetFloatValue()); - } - - switch (unit) { - case eCSSUnit_Null: break; - case eCSSUnit_Auto: aBuffer.Append("auto"); break; - case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; - case eCSSUnit_None: aBuffer.Append("none"); break; - case eCSSUnit_Normal: aBuffer.Append("normal"); break; - case eCSSUnit_String: break; - case eCSSUnit_Integer: break; - case eCSSUnit_Enumerated: break; - case eCSSUnit_Color: break; - case eCSSUnit_Percent: aBuffer.Append("%"); break; - case eCSSUnit_Number: break; - case eCSSUnit_Inch: aBuffer.Append("in"); break; - case eCSSUnit_Foot: aBuffer.Append("ft"); break; - case eCSSUnit_Mile: aBuffer.Append("mi"); break; - case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; - case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; - case eCSSUnit_Meter: aBuffer.Append("m"); break; - case eCSSUnit_Kilometer: aBuffer.Append("km"); break; - case eCSSUnit_Point: aBuffer.Append("pt"); break; - case eCSSUnit_Pica: aBuffer.Append("pc"); break; - case eCSSUnit_Didot: aBuffer.Append("dt"); break; - case eCSSUnit_Cicero: aBuffer.Append("cc"); break; - case eCSSUnit_EM: aBuffer.Append("em"); break; - case eCSSUnit_EN: aBuffer.Append("en"); break; - case eCSSUnit_XHeight: aBuffer.Append("ex"); break; - case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; - case eCSSUnit_Pixel: aBuffer.Append("px"); break; - } + return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) @@ -2347,7 +2373,7 @@ nsresult CSSDeclarationImpl::ToString(nsString& aString) } aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); - ValueToString(value, property, aString); + nsCSSValue::ValueToString(aString, value, property); if (PR_TRUE == important) { aString.Append(" ! important"); } @@ -2400,6 +2426,34 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +nsresult +CSSDeclarationImpl::Count(PRUint32* aCount) +{ + if (nsnull != mOrder) { + *aCount = (PRUint32)mOrder->Count(); + } + else { + *aCount = 0; + } + + return NS_OK; +} + +nsresult +CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) +{ + aReturn.SetLength(0); + if (nsnull != mOrder) { + PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); + if (0 <= property) { + aReturn.Append(nsCSSProps::kNameTable[property].name); + } + } + + return NS_OK; +} + + NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index 75f07413ca0..92cc83485a1 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -202,6 +202,10 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult); + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration); protected: PRBool GetToken(PRInt32* aErrorCode, PRBool aSkipWS); @@ -448,6 +452,40 @@ CSSParserImpl::ParseDeclarations(const nsString& aDeclaration, return NS_OK; } +NS_METHOD +CSSParserImpl::ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) +{ + nsString* str = new nsString(aBuffer); + if (nsnull == str) { + return NS_ERROR_OUT_OF_MEMORY; + } + nsIUnicharInputStream* input = nsnull; + nsresult rv = NS_NewStringUnicharInputStream(&input, str); + if (NS_OK != rv) { + return rv; + } + + mScanner = new nsCSSScanner(); + mScanner->Init(input); + NS_RELEASE(input); + + mURL = aBaseURL; + NS_IF_ADDREF(mURL); + + mInHead = PR_FALSE; + PRInt32 errorCode = NS_OK; + + ParseDeclaration(&errorCode, &aDeclaration, PR_FALSE); + + delete mScanner; + mScanner = nsnull; + NS_IF_RELEASE(mURL); + + return NS_OK; +} + //---------------------------------------------------------------------- PRBool CSSParserImpl::GetToken(PRInt32* aErrorCode, PRBool aSkipWS) diff --git a/mozilla/layout/style/nsCSSStruct.cpp b/mozilla/layout/style/nsCSSStruct.cpp index 4c6bfa05c43..5cfeaef158d 100644 --- a/mozilla/layout/style/nsCSSStruct.cpp +++ b/mozilla/layout/style/nsCSSStruct.cpp @@ -268,6 +268,118 @@ nsCSSValue::~nsCSSValue(void) Reset(); } +// XXX shouldn't this get moved to color code? +static const char* RGBToCSSString(nscolor aColor) +{ + const char* result = nsnull; + + PRInt32 r = NS_GET_R(aColor); + PRInt32 g = NS_GET_G(aColor); + PRInt32 b = NS_GET_B(aColor); + + PRInt32 index = 0; + PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); + CSSColorEntry* entry = nsnull; + + for (index = 0; index < count; index++) + { + entry = &css_rgb_table[index]; + if (entry->r == r) + { + if (entry->g == g && entry->b == b) + { + result = entry->name; + break; + } + } + else if (entry->r > r) + { + break; + } + } + return result; +} + + +void +nsCSSValue::ValueToString(nsString& aBuffer, const nsCSSValue& aValue, + PRInt32 aPropID) +{ + nsCSSUnit unit = aValue.GetUnit(); + + if (eCSSUnit_Null == unit) { + return; + } + + if (eCSSUnit_String == unit) { + nsAutoString buffer; + aValue.GetStringValue(buffer); + aBuffer.Append(buffer); + } + else if (eCSSUnit_Integer == unit) { + aBuffer.Append(aValue.GetIntValue(), 10); + } + else if (eCSSUnit_Enumerated == unit) { + const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); + if (name != nsnull) { + aBuffer.Append(name); + } + } + else if (eCSSUnit_Color == unit){ + nscolor color = aValue.GetColorValue(); + const char* name = RGBToCSSString(color); + + if (name != nsnull) + aBuffer.Append(name); + else + { + aBuffer.Append("rgb("); + aBuffer.Append(NS_GET_R(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_G(color), 10); + aBuffer.Append(","); + aBuffer.Append(NS_GET_B(color), 10); + aBuffer.Append(')'); + } + } + else if (eCSSUnit_Percent == unit) { + aBuffer.Append(aValue.GetPercentValue() * 100.0f); + } + else if (eCSSUnit_Percent < unit) { // length unit + aBuffer.Append(aValue.GetFloatValue()); + } + + switch (unit) { + case eCSSUnit_Null: break; + case eCSSUnit_Auto: aBuffer.Append("auto"); break; + case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; + case eCSSUnit_None: aBuffer.Append("none"); break; + case eCSSUnit_Normal: aBuffer.Append("normal"); break; + case eCSSUnit_String: break; + case eCSSUnit_Integer: break; + case eCSSUnit_Enumerated: break; + case eCSSUnit_Color: break; + case eCSSUnit_Percent: aBuffer.Append("%"); break; + case eCSSUnit_Number: break; + case eCSSUnit_Inch: aBuffer.Append("in"); break; + case eCSSUnit_Foot: aBuffer.Append("ft"); break; + case eCSSUnit_Mile: aBuffer.Append("mi"); break; + case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; + case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; + case eCSSUnit_Meter: aBuffer.Append("m"); break; + case eCSSUnit_Kilometer: aBuffer.Append("km"); break; + case eCSSUnit_Point: aBuffer.Append("pt"); break; + case eCSSUnit_Pica: aBuffer.Append("pc"); break; + case eCSSUnit_Didot: aBuffer.Append("dt"); break; + case eCSSUnit_Cicero: aBuffer.Append("cc"); break; + case eCSSUnit_EM: aBuffer.Append("em"); break; + case eCSSUnit_EN: aBuffer.Append("en"); break; + case eCSSUnit_XHeight: aBuffer.Append("ex"); break; + case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; + case eCSSUnit_Pixel: aBuffer.Append("px"); break; + } +} + nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) { Reset(); @@ -772,7 +884,7 @@ void nsCSSList::List(FILE* out, PRInt32 aIndent) const class CSSDeclarationImpl : public nsICSSDeclaration { public: void* operator new(size_t size); - + CSSDeclarationImpl(void); ~CSSDeclarationImpl(void); @@ -791,10 +903,14 @@ public: nsresult GetValue(PRInt32 aProperty, nsCSSValue& aValue); nsresult GetImportantValues(nsICSSDeclaration*& aResult); - + nsresult GetValueIsImportant(const char *aProperty, PRBool& aIsImportant); + virtual nsresult ToString(nsString& aString); void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + nsresult Count(PRUint32* aCount); + nsresult GetNthProperty(PRUint32 aIndex, nsString& aReturn); private: CSSDeclarationImpl(const CSSDeclarationImpl& aCopy); @@ -2211,115 +2327,25 @@ nsresult CSSDeclarationImpl::GetImportantValues(nsICSSDeclaration*& aResult) return NS_OK; } -// XXX shouldn't this get moved to color code? -static const char* RGBToCSSString(nscolor aColor) +nsresult CSSDeclarationImpl::GetValueIsImportant(const char *aProperty, + PRBool& aIsImportant) { - const char* result = nsnull; + nsCSSValue val; - PRInt32 r = NS_GET_R(aColor); - PRInt32 g = NS_GET_G(aColor); - PRInt32 b = NS_GET_B(aColor); - - PRInt32 index = 0; - PRInt32 count = sizeof(css_rgb_table)/sizeof(CSSColorEntry); - CSSColorEntry* entry = nsnull; - - for (index = 0; index < count; index++) - { - entry = &css_rgb_table[index]; - if (entry->r == r) - { - if (entry->g == g && entry->b == b) - { - result = entry->name; - break; - } + if (nsnull != mImportant) { + mImportant->GetValue(aProperty, val); + if (eCSSUnit_Null != val.GetUnit()) { + aIsImportant = PR_TRUE; } - else if (entry->r > r) - { - break; + else { + aIsImportant = PR_FALSE; } } - return result; -} - - -static void -ValueToString(const nsCSSValue& aValue, PRInt32 aPropID, nsString& aBuffer) -{ - nsCSSUnit unit = aValue.GetUnit(); - - if (eCSSUnit_Null == unit) { - return; + else { + aIsImportant = PR_FALSE; } - if (eCSSUnit_String == unit) { - nsAutoString buffer; - aValue.GetStringValue(buffer); - aBuffer.Append(buffer); - } - else if (eCSSUnit_Integer == unit) { - aBuffer.Append(aValue.GetIntValue(), 10); - } - else if (eCSSUnit_Enumerated == unit) { - const char* name = nsCSSProps::LookupProperty(aPropID, aValue.GetIntValue()); - if (name != nsnull) { - aBuffer.Append(name); - } - } - else if (eCSSUnit_Color == unit){ - nscolor color = aValue.GetColorValue(); - const char* name = RGBToCSSString(color); - - if (name != nsnull) - aBuffer.Append(name); - else - { - aBuffer.Append("rgb("); - aBuffer.Append(NS_GET_R(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_G(color), 10); - aBuffer.Append(","); - aBuffer.Append(NS_GET_B(color), 10); - aBuffer.Append(')'); - } - } - else if (eCSSUnit_Percent == unit) { - aBuffer.Append(aValue.GetPercentValue() * 100.0f); - } - else if (eCSSUnit_Percent < unit) { // length unit - aBuffer.Append(aValue.GetFloatValue()); - } - - switch (unit) { - case eCSSUnit_Null: break; - case eCSSUnit_Auto: aBuffer.Append("auto"); break; - case eCSSUnit_Inherit: aBuffer.Append("inherit"); break; - case eCSSUnit_None: aBuffer.Append("none"); break; - case eCSSUnit_Normal: aBuffer.Append("normal"); break; - case eCSSUnit_String: break; - case eCSSUnit_Integer: break; - case eCSSUnit_Enumerated: break; - case eCSSUnit_Color: break; - case eCSSUnit_Percent: aBuffer.Append("%"); break; - case eCSSUnit_Number: break; - case eCSSUnit_Inch: aBuffer.Append("in"); break; - case eCSSUnit_Foot: aBuffer.Append("ft"); break; - case eCSSUnit_Mile: aBuffer.Append("mi"); break; - case eCSSUnit_Millimeter: aBuffer.Append("mm"); break; - case eCSSUnit_Centimeter: aBuffer.Append("cm"); break; - case eCSSUnit_Meter: aBuffer.Append("m"); break; - case eCSSUnit_Kilometer: aBuffer.Append("km"); break; - case eCSSUnit_Point: aBuffer.Append("pt"); break; - case eCSSUnit_Pica: aBuffer.Append("pc"); break; - case eCSSUnit_Didot: aBuffer.Append("dt"); break; - case eCSSUnit_Cicero: aBuffer.Append("cc"); break; - case eCSSUnit_EM: aBuffer.Append("em"); break; - case eCSSUnit_EN: aBuffer.Append("en"); break; - case eCSSUnit_XHeight: aBuffer.Append("ex"); break; - case eCSSUnit_CapHeight: aBuffer.Append("cap"); break; - case eCSSUnit_Pixel: aBuffer.Append("px"); break; - } + return NS_OK; } nsresult CSSDeclarationImpl::ToString(nsString& aString) @@ -2347,7 +2373,7 @@ nsresult CSSDeclarationImpl::ToString(nsString& aString) } aString.Append(nsCSSProps::kNameTable[property].name); aString.Append(": "); - ValueToString(value, property, aString); + nsCSSValue::ValueToString(aString, value, property); if (PR_TRUE == important) { aString.Append(" ! important"); } @@ -2400,6 +2426,34 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +nsresult +CSSDeclarationImpl::Count(PRUint32* aCount) +{ + if (nsnull != mOrder) { + *aCount = (PRUint32)mOrder->Count(); + } + else { + *aCount = 0; + } + + return NS_OK; +} + +nsresult +CSSDeclarationImpl::GetNthProperty(PRUint32 aIndex, nsString& aReturn) +{ + aReturn.SetLength(0); + if (nsnull != mOrder) { + PRInt32 property = (PRInt32)mOrder->ElementAt(aIndex); + if (0 <= property) { + aReturn.Append(nsCSSProps::kNameTable[property].name); + } + } + + return NS_OK; +} + + NS_HTML nsresult NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult) { diff --git a/mozilla/layout/style/nsICSSParser.h b/mozilla/layout/style/nsICSSParser.h index b12e3eff839..1dfd596f1d5 100644 --- a/mozilla/layout/style/nsICSSParser.h +++ b/mozilla/layout/style/nsICSSParser.h @@ -25,6 +25,7 @@ class nsIStyleSheet; class nsIUnicharInputStream; class nsIURL; class nsString; +class nsICSSDeclaration; #define NS_ICSS_PARSER_IID \ { 0xcc9c0610, 0x968c, 0x11d1, \ @@ -51,6 +52,11 @@ public: NS_IMETHOD ParseDeclarations(const nsString& aDeclaration, nsIURL* aBaseURL, nsIStyleRule*& aResult) = 0; + + NS_IMETHOD ParseAndAppendDeclaration(const nsString& aBuffer, + nsIURL* aBaseURL, + nsICSSDeclaration& aDeclaration) = 0; + }; // Values or'd in the GetInfoMask; other bits are reserved