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