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;