From e1b7f01e77b9adcbcae98e21c4a12cbf614d332f Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Thu, 20 Dec 2001 10:16:25 +0000 Subject: [PATCH] Fixing bug 111752. DOM0 quirk, document.open() when called with 3 or more arguments should call window.open() to make calls to 'open(url, name, features);' when called from within the document scope open a new window. r=hidday@geocities.com, sr=brendan@mozilla.org. --- dom/src/base/nsDOMClassInfo.cpp | 73 +++++++++++++++++++++++++++++---- dom/src/base/nsDOMClassInfo.h | 7 +++- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index 5a9e4cb0029..97575e9b6b8 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -847,6 +847,7 @@ JSString *nsDOMClassInfo::sOnpaint_id = nsnull; JSString *nsDOMClassInfo::sOnresize_id = nsnull; JSString *nsDOMClassInfo::sOnscroll_id = nsnull; JSString *nsDOMClassInfo::sScrollIntoView_id = nsnull; +JSString *nsDOMClassInfo::sOpen_id = nsnull; const JSClass *nsDOMClassInfo::sObjectClass = nsnull; @@ -855,9 +856,11 @@ static inline JSObject * GetGlobalJSObject(JSContext *cx, JSObject *obj) { JSObject *tmp; + while ((tmp = ::JS_GetParent(cx, obj))) { obj = tmp; } + return obj; } @@ -913,6 +916,7 @@ nsDOMClassInfo::DefineStaticJSStrings(JSContext *cx) sOnresize_id = ::JS_InternString(cx, "onresize"); sOnscroll_id = ::JS_InternString(cx, "onscroll"); sScrollIntoView_id = ::JS_InternString(cx, "scrollIntoView"); + sOpen_id = ::JS_InternString(cx, "open"); return NS_OK; } @@ -2266,12 +2270,7 @@ nsDOMClassInfo::PostCreate(nsIXPConnectWrappedNative *wrapper, } #endif - JSObject *global = obj; - JSObject *tmp; - - while ((tmp = ::JS_GetParent(cx, global))) { - global = tmp; - } + JSObject *global = GetGlobalJSObject(cx, obj); jsval val; if (!::JS_GetProperty(cx, global, ci_data.mName, &val)) { @@ -2386,8 +2385,13 @@ static inline const PRUnichar * JSValIDToString(JSContext *aJSContext, const jsval idval) { JSString *str = JS_ValueToString(aJSContext, idval); - if(!str) + + if(!str) { + NS_ERROR("JS_ValueToString() returned null!"); + return nsnull; + } + return NS_REINTERPRET_CAST(const PRUnichar*, JS_GetStringChars(str)); } @@ -2563,6 +2567,7 @@ nsDOMClassInfo::ShutDown() sOnresize_id = jsnullstring; sOnscroll_id = jsnullstring; sScrollIntoView_id = jsnullstring; + sOpen_id = jsnullstring; NS_IF_RELEASE(sXPConnect); NS_IF_RELEASE(sSecMan); @@ -2635,7 +2640,6 @@ needsSecurityCheck(JSContext *cx, nsIXPConnectWrappedNative *wrapper) } while (!fp_obj); if (fp_obj) { - JSObject *global = GetGlobalJSObject(cx, fp_obj); JSObject *wrapper_obj = nsnull; @@ -3536,7 +3540,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // A readonly "replaceable" property is being set, or a // readwrite "replaceable" property is being set w/o being // fully qualified. Define the property on obj with the value - // undefined to override the predefined property. + // undefined to override the predefined property. This is done + // for compatibility with other browsers. *_retval = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), @@ -4199,6 +4204,7 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // HTMLDocument helper +// static nsresult nsHTMLDocumentSH::ResolveImpl(nsIXPConnectWrappedNative *wrapper, jsval id, nsISupports **result) @@ -4220,6 +4226,45 @@ nsHTMLDocumentSH::ResolveImpl(nsIXPConnectWrappedNative *wrapper, jsval id, return doc->ResolveName(name, nsnull, result); } +// static +JSBool JS_DLL_CALLBACK +nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + if (argc > 2) { + JSObject *global = GetGlobalJSObject(cx, obj); + + // DOM0 quirk that makes document.open() call window.open() if + // called with 3 or more arguments. + + return ::JS_CallFunctionName(cx, global, "open", argc, argv, rval); + } + + nsCOMPtr wrapper; + + nsresult rv = + sXPConnect->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrapper)); + NS_ENSURE_SUCCESS(rv, JS_FALSE); + + nsCOMPtr native; + rv = wrapper->GetNative(getter_AddRefs(native)); + NS_ENSURE_SUCCESS(rv, JS_FALSE); + + nsCOMPtr doc(do_QueryInterface(native)); + NS_ENSURE_TRUE(doc, JS_FALSE); + + nsCOMPtr retval; + + rv = doc->Open(getter_AddRefs(retval)); + NS_ENSURE_SUCCESS(rv, PR_FALSE); + + rv = WrapNative(cx, ::JS_GetGlobalObject(cx), retval, + NS_GET_IID(nsIDOMDocument), rval); + NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!"); + + return NS_SUCCEEDED(rv); +} + NS_IMETHODIMP nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsval id, PRUint32 flags, @@ -4242,6 +4287,16 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return ok ? NS_OK : NS_ERROR_FAILURE; } + + if (id == STRING_TO_JSVAL(sOpen_id)) { + JSFunction *fnc = + ::JS_DefineFunction(cx, obj, ::JS_GetStringBytes(sOpen_id), + DocumentOpen, 0, JSPROP_ENUMERATE); + + *objp = obj; + + return fnc ? NS_OK : NS_ERROR_UNEXPECTED; + } } return nsDocumentSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval); diff --git a/dom/src/base/nsDOMClassInfo.h b/dom/src/base/nsDOMClassInfo.h index 43b1f18500f..61df4c53244 100644 --- a/dom/src/base/nsDOMClassInfo.h +++ b/dom/src/base/nsDOMClassInfo.h @@ -183,6 +183,7 @@ protected: static JSString *sOnresize_id; static JSString *sOnscroll_id; static JSString *sScrollIntoView_id; + static JSString *sOpen_id; static const JSClass *sObjectClass; }; @@ -507,8 +508,10 @@ protected: { } - nsresult ResolveImpl(nsIXPConnectWrappedNative *wrapper, jsval id, - nsISupports **result); + static nsresult ResolveImpl(nsIXPConnectWrappedNative *wrapper, jsval id, + nsISupports **result); + static JSBool DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval); public: NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,