diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index dbe74ea151b7..5e426dad08b0 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -24,6 +24,7 @@ #include "nsIDOMNSHTMLFormElement.h" #include "nsIDOMHTMLCollection.h" #include "nsIScriptObjectOwner.h" +#include "nsIScriptContextOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIHTMLContent.h" #include "nsGenericHTMLElement.h" @@ -51,7 +52,8 @@ class nsHTMLFormElement : public nsIDOMHTMLFormElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, public nsIHTMLContent, - public nsIForm + public nsIForm, + public nsIJSScriptObject { public: nsHTMLFormElement(nsIAtom* aTag); @@ -103,6 +105,16 @@ public: // nsIHTMLContent NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner) + // nsIJSScriptObject + virtual PRBool AddProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool GetProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool SetProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool EnumerateProperty(JSContext *aContext); + virtual PRBool Resolve(JSContext *aContext, jsval aID); + virtual PRBool Convert(JSContext *aContext, jsval aID); + virtual void Finalize(JSContext *aContext); + // nsIForm NS_IMETHOD AddElement(nsIFormControl* aElement); NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const; @@ -188,6 +200,15 @@ nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); NS_IMETHODIMP nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { + // Note that this has to stay above the generic element + // QI macro, since it overrides the nsIJSScriptObject implementation + // from the generic element. + if (aIID.Equals(kIJSScriptObjectIID)) { + nsIJSScriptObject* tmp = this; + *aInstancePtr = (void*) tmp; + AddRef(); + return NS_OK; + } NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this) if (aIID.Equals(kIFormIID)) { *aInstancePtr = (void*)(nsIForm*)this; @@ -473,6 +494,99 @@ nsHTMLFormElement::NamedItem(const nsString& aName, nsIDOMElement** aReturn) return result; } +PRBool +nsHTMLFormElement::AddProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.AddProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.DeleteProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::GetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.GetProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.SetProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::EnumerateProperty(JSContext *aContext) +{ + return mInner.EnumerateProperty(aContext); +} + +PRBool +nsHTMLFormElement::Resolve(JSContext *aContext, jsval aID) +{ + nsCOMPtr element; + char* str = JS_GetStringBytes(JS_ValueToString(aContext, aID)); + nsAutoString name(str); + nsresult result = NS_OK; + PRBool ret = PR_TRUE; + + result = NamedItem(name, getter_AddRefs(element)); + if (NS_SUCCEEDED(result) && element) { + nsCOMPtr owner = do_QueryInterface(element); + + if (owner) { + nsCOMPtr scriptContext; + + if (nsnull != mInner.mDocument) { + nsCOMPtr contextOwner; + + contextOwner = getter_AddRefs(mInner.mDocument->GetScriptContextOwner()); + if (contextOwner) { + result = contextOwner->GetScriptContext(getter_AddRefs(scriptContext)); + } + } + else { + scriptContext = dont_AddRef((nsIScriptContext*)JS_GetContextPrivate(aContext)); + } + + JSObject* obj; + if (scriptContext) { + result = owner->GetScriptObject(scriptContext, (void**)&obj); + if (NS_SUCCEEDED(result) && (nsnull != obj)) { + JSObject* myObj; + result = mInner.GetScriptObject(scriptContext, (void**)&myObj); + ret = ::JS_DefineProperty(aContext, myObj, + str, OBJECT_TO_JSVAL(obj), + nsnull, nsnull, 0); + } + } + } + } + else { + ret = mInner.Resolve(aContext, aID); + } + + if (NS_FAILED(result)) { + ret = PR_FALSE; + } + + return ret; +} + +PRBool +nsHTMLFormElement::Convert(JSContext *aContext, jsval aID) +{ + return mInner.Convert(aContext, aID); +} + +void +nsHTMLFormElement::Finalize(JSContext *aContext) +{ + mInner.Finalize(aContext); +} // nsFormControlList implementation, this could go away if there were a lightweight collection implementation somewhere diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index bdc702f05c25..1d220e501b17 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -159,6 +159,9 @@ NS_IMPL_RELEASE(nsHTMLImageElement) nsresult nsHTMLImageElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { + // Note that this has to stay above the generic element + // QI macro, since it overrides the nsIJSScriptObject implementation + // from the generic element. if (aIID.Equals(kIJSScriptObjectIID)) { nsIJSScriptObject* tmp = this; *aInstancePtr = (void*) tmp; diff --git a/layout/html/content/src/nsHTMLFormElement.cpp b/layout/html/content/src/nsHTMLFormElement.cpp index dbe74ea151b7..5e426dad08b0 100644 --- a/layout/html/content/src/nsHTMLFormElement.cpp +++ b/layout/html/content/src/nsHTMLFormElement.cpp @@ -24,6 +24,7 @@ #include "nsIDOMNSHTMLFormElement.h" #include "nsIDOMHTMLCollection.h" #include "nsIScriptObjectOwner.h" +#include "nsIScriptContextOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIHTMLContent.h" #include "nsGenericHTMLElement.h" @@ -51,7 +52,8 @@ class nsHTMLFormElement : public nsIDOMHTMLFormElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, public nsIHTMLContent, - public nsIForm + public nsIForm, + public nsIJSScriptObject { public: nsHTMLFormElement(nsIAtom* aTag); @@ -103,6 +105,16 @@ public: // nsIHTMLContent NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner) + // nsIJSScriptObject + virtual PRBool AddProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool GetProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool SetProperty(JSContext *aContext, jsval aID, jsval *aVp); + virtual PRBool EnumerateProperty(JSContext *aContext); + virtual PRBool Resolve(JSContext *aContext, jsval aID); + virtual PRBool Convert(JSContext *aContext, jsval aID); + virtual void Finalize(JSContext *aContext); + // nsIForm NS_IMETHOD AddElement(nsIFormControl* aElement); NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const; @@ -188,6 +200,15 @@ nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); NS_IMETHODIMP nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { + // Note that this has to stay above the generic element + // QI macro, since it overrides the nsIJSScriptObject implementation + // from the generic element. + if (aIID.Equals(kIJSScriptObjectIID)) { + nsIJSScriptObject* tmp = this; + *aInstancePtr = (void*) tmp; + AddRef(); + return NS_OK; + } NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this) if (aIID.Equals(kIFormIID)) { *aInstancePtr = (void*)(nsIForm*)this; @@ -473,6 +494,99 @@ nsHTMLFormElement::NamedItem(const nsString& aName, nsIDOMElement** aReturn) return result; } +PRBool +nsHTMLFormElement::AddProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.AddProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::DeleteProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.DeleteProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::GetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.GetProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::SetProperty(JSContext *aContext, jsval aID, jsval *aVp) +{ + return mInner.SetProperty(aContext, aID, aVp); +} + +PRBool +nsHTMLFormElement::EnumerateProperty(JSContext *aContext) +{ + return mInner.EnumerateProperty(aContext); +} + +PRBool +nsHTMLFormElement::Resolve(JSContext *aContext, jsval aID) +{ + nsCOMPtr element; + char* str = JS_GetStringBytes(JS_ValueToString(aContext, aID)); + nsAutoString name(str); + nsresult result = NS_OK; + PRBool ret = PR_TRUE; + + result = NamedItem(name, getter_AddRefs(element)); + if (NS_SUCCEEDED(result) && element) { + nsCOMPtr owner = do_QueryInterface(element); + + if (owner) { + nsCOMPtr scriptContext; + + if (nsnull != mInner.mDocument) { + nsCOMPtr contextOwner; + + contextOwner = getter_AddRefs(mInner.mDocument->GetScriptContextOwner()); + if (contextOwner) { + result = contextOwner->GetScriptContext(getter_AddRefs(scriptContext)); + } + } + else { + scriptContext = dont_AddRef((nsIScriptContext*)JS_GetContextPrivate(aContext)); + } + + JSObject* obj; + if (scriptContext) { + result = owner->GetScriptObject(scriptContext, (void**)&obj); + if (NS_SUCCEEDED(result) && (nsnull != obj)) { + JSObject* myObj; + result = mInner.GetScriptObject(scriptContext, (void**)&myObj); + ret = ::JS_DefineProperty(aContext, myObj, + str, OBJECT_TO_JSVAL(obj), + nsnull, nsnull, 0); + } + } + } + } + else { + ret = mInner.Resolve(aContext, aID); + } + + if (NS_FAILED(result)) { + ret = PR_FALSE; + } + + return ret; +} + +PRBool +nsHTMLFormElement::Convert(JSContext *aContext, jsval aID) +{ + return mInner.Convert(aContext, aID); +} + +void +nsHTMLFormElement::Finalize(JSContext *aContext) +{ + mInner.Finalize(aContext); +} // nsFormControlList implementation, this could go away if there were a lightweight collection implementation somewhere diff --git a/layout/html/content/src/nsHTMLImageElement.cpp b/layout/html/content/src/nsHTMLImageElement.cpp index bdc702f05c25..1d220e501b17 100644 --- a/layout/html/content/src/nsHTMLImageElement.cpp +++ b/layout/html/content/src/nsHTMLImageElement.cpp @@ -159,6 +159,9 @@ NS_IMPL_RELEASE(nsHTMLImageElement) nsresult nsHTMLImageElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { + // Note that this has to stay above the generic element + // QI macro, since it overrides the nsIJSScriptObject implementation + // from the generic element. if (aIID.Equals(kIJSScriptObjectIID)) { nsIJSScriptObject* tmp = this; *aInstancePtr = (void*) tmp;