From cacd57b2aeefffa82ee1b3efbe279ea82d2dfcef Mon Sep 17 00:00:00 2001 From: "jst%netscape.com" Date: Fri, 2 Nov 2001 04:49:07 +0000 Subject: [PATCH] Fixing bug 52120. Make mozilla pass the expected arguments to window.onerror. r=jkeiser@iname.com, sr=jband@netscape.com --- .../html/content/src/nsHTMLScriptElement.cpp | 16 +++++- dom/src/base/nsDOMClassInfo.cpp | 24 +++++---- dom/src/base/nsJSEnvironment.cpp | 48 ++++++++++-------- dom/src/events/Makefile.in | 3 ++ dom/src/events/makefile.win | 3 ++ dom/src/events/nsJSEventListener.cpp | 50 ++++++++++++++----- widget/public/nsGUIEvent.h | 10 ++++ 7 files changed, 112 insertions(+), 42 deletions(-) diff --git a/content/html/content/src/nsHTMLScriptElement.cpp b/content/html/content/src/nsHTMLScriptElement.cpp index f12d1e200998..70259c76f653 100644 --- a/content/html/content/src/nsHTMLScriptElement.cpp +++ b/content/html/content/src/nsHTMLScriptElement.cpp @@ -50,6 +50,7 @@ #include "nsIScriptLoaderObserver.h" #include "nsIScriptElement.h" #include "nsGUIEvent.h" +#include "nsIURI.h" class nsHTMLScriptElement : public nsGenericHTMLContainerElement, public nsIDOMHTMLScriptElement, @@ -316,10 +317,23 @@ nsHTMLScriptElement::ScriptAvailable(nsresult aResult, GetPresContext(this, getter_AddRefs(presContext)); nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; + nsScriptErrorEvent event; event.eventStructType = NS_EVENT; event.message = NS_SCRIPT_ERROR; + + event.lineNr = aLineNo; + + NS_NAMED_LITERAL_STRING(errorString, "Error loading script"); + event.errorMsg = errorString.get(); + + nsXPIDLCString spec; + aURI->GetSpec(getter_Copies(spec)); + + NS_ConvertUTF8toUCS2 fileName(spec); + + event.fileName = fileName.get(); + rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); } diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index 41ed5fa3cc2c..3d4695ac2e14 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -315,6 +315,7 @@ struct nsDOMClassInfoData const nsIID *mProtoChainInterface; const nsIID **mInterfaces; PRUint32 mScriptableFlags; + PRPackedBool mHasClassInterface; #ifdef NS_DEBUG PRUint32 mDebugID; #endif @@ -338,6 +339,7 @@ struct nsDOMClassInfoData nsnull, \ nsnull, \ _flags, \ + PR_TRUE, \ NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \ }, @@ -903,7 +905,7 @@ nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID) } -#define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr) \ +#define _DOM_CLASSINFO_MAP_BEGIN(_class, _ifptr, _has_class_if) \ { \ nsDOMClassInfoData &d = sClassInfoData[eDOMClassInfo_##_class##_id]; \ NS_ASSERTION(!d.mProtoChainInterface, "Redeclaration of DOM classinfo " \ @@ -911,13 +913,17 @@ nsDOMClassInfo::RegisterClassProtos(PRInt32 aClassInfoID) NS_ASSERTION(!d.mInterfaces, "Redeclaration of DOM classinfo " \ "interface list!"); \ d.mProtoChainInterface = _ifptr; \ + d.mHasClassInterface = _has_class_if; \ static const nsIID *interface_list[] = { #define DOM_CLASSINFO_MAP_BEGIN(_class, _interface) \ - _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface)) + _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), PR_TRUE) #define DOM_CLASSINFO_MAP_BEGIN_NO_PRIMARY_INTERFACE(_class) \ - _DOM_CLASSINFO_MAP_BEGIN(_class, nsnull) + _DOM_CLASSINFO_MAP_BEGIN(_class, nsnull, PR_TRUE) + +#define DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(_class, _interface) \ + _DOM_CLASSINFO_MAP_BEGIN(_class, &NS_GET_IID(_interface), PR_FALSE) #define DOM_CLASSINFO_MAP_ENTRY(_if) \ &NS_GET_IID(_if), @@ -1169,7 +1175,7 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLDelElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLDelElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLModElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END @@ -1254,7 +1260,7 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLInsElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLInsElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLModElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END @@ -1356,12 +1362,12 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLSpacerElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLSpacerElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLSpanElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLSpanElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END @@ -1425,12 +1431,12 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLUnknownElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLUnknownElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END - DOM_CLASSINFO_MAP_BEGIN(HTMLWBRElement, nsIDOMHTMLElement) + DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(HTMLWBRElement, nsIDOMHTMLElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement) DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES DOM_CLASSINFO_MAP_END diff --git a/dom/src/base/nsJSEnvironment.cpp b/dom/src/base/nsJSEnvironment.cpp index 46de6b222f26..12c9027a15b3 100644 --- a/dom/src/base/nsJSEnvironment.cpp +++ b/dom/src/base/nsJSEnvironment.cpp @@ -113,10 +113,27 @@ NS_ScriptErrorReporter(JSContext *cx, nsCOMPtr owner; if(NS_FAILED(globalObject->GetGlobalObjectOwner(getter_AddRefs(owner))) || !owner) { - NS_WARN_IF_FALSE(PR_FALSE, "Failed to get a global Object Owner"); + NS_WARNING("Failed to get a global Object Owner"); return; } + nsAutoString fileName, msg; + + if (report) { + fileName.AssignWithConversion(report->filename); + + const PRUnichar *m = NS_REINTERPRET_CAST(const PRUnichar*, + report->ucmessage); + + if (m) { + msg.Assign(m); + } + } + + if (msg.IsEmpty() && message) { + msg.AssignWithConversion(message); + } + //send error event first, then proceed nsCOMPtr docShell; globalObject->GetDocShell(getter_AddRefs(docShell)); @@ -128,13 +145,18 @@ NS_ScriptErrorReporter(JSContext *cx, docShell->GetPresContext(getter_AddRefs(presContext)); if(presContext && errorDepth < 2) { - nsEvent errorevent; + nsScriptErrorEvent errorevent; errorevent.eventStructType = NS_EVENT; errorevent.message = NS_SCRIPT_ERROR; + errorevent.fileName = fileName.get(); + errorevent.errorMsg = msg.get(); + errorevent.lineNr = report ? report->lineno : -1; + // HandleDOMEvent() must be synchronous for the recursion block // (errorDepth) to work. - globalObject->HandleDOMEvent(presContext, &errorevent, nsnull, NS_EVENT_FLAG_INIT, &status); + globalObject->HandleDOMEvent(presContext, &errorevent, nsnull, + NS_EVENT_FLAG_INIT, &status); } errorDepth--; @@ -166,30 +188,16 @@ NS_ScriptErrorReporter(JSContext *cx, } if (report) { - nsAutoString fileUni, msg; - fileUni.AssignWithConversion(report->filename); PRUint32 column = report->uctokenptr - report->uclinebuf; - const PRUnichar *m = NS_REINTERPRET_CAST(const PRUnichar*, - report->ucmessage); - - if (!m && message) { - msg.AssignWithConversion(message); - - m = msg.get(); - } - - rv = errorObject->Init(m, fileUni.get(), + rv = errorObject->Init(msg.get(), fileName.get(), NS_REINTERPRET_CAST(const PRUnichar*, report->uclinebuf), report->lineno, column, report->flags, category); } else if (message) { - nsAutoString messageUni; - messageUni.AssignWithConversion(message); - - rv = errorObject->Init(messageUni.get(), nsnull, nsnull, - 0, 0, 0, category); + rv = errorObject->Init(msg.get(), nsnull, nsnull, 0, 0, 0, + category); } if (NS_SUCCEEDED(rv)) diff --git a/dom/src/events/Makefile.in b/dom/src/events/Makefile.in index 1ff01c231908..6df31b95737e 100644 --- a/dom/src/events/Makefile.in +++ b/dom/src/events/Makefile.in @@ -33,6 +33,9 @@ REQUIRES = xpcom \ js \ caps \ xpconnect \ + content \ + widget \ + gfx \ $(NULL) CPPSRCS = \ diff --git a/dom/src/events/makefile.win b/dom/src/events/makefile.win index 704bc466bc7e..acb615360586 100644 --- a/dom/src/events/makefile.win +++ b/dom/src/events/makefile.win @@ -29,6 +29,9 @@ REQUIRES = xpcom \ js \ caps \ xpconnect \ + content \ + widget \ + gfx \ $(NULL) DEFINES=-D_IMPL_NS_DOM -DWIN32_LEAN_AND_MEAN diff --git a/dom/src/events/nsJSEventListener.cpp b/dom/src/events/nsJSEventListener.cpp index 6a97c8400dc7..e205f83a794a 100644 --- a/dom/src/events/nsJSEventListener.cpp +++ b/dom/src/events/nsJSEventListener.cpp @@ -43,6 +43,8 @@ #include "nsIScriptSecurityManager.h" #include "nsIScriptContext.h" #include "nsIXPConnect.h" +#include "nsIPrivateDOMEvent.h" +#include "nsGUIEvent.h" /* @@ -87,7 +89,10 @@ nsresult nsJSEventListener::SetEventName(nsIAtom* aName) nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent) { jsval funval; - jsval argv[1]; + jsval arg; + jsval *argv = &arg; + PRInt32 argc = 0; + void *stackPtr; // For JS_[Push|Pop]Arguments() nsAutoString eventString; // XXX This doesn't seem like the correct context on which to execute // the event handler. Might need to get one from the JS thread context @@ -119,9 +124,8 @@ nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent) // root nsCOMPtr wrapper; - rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), - mObject, NS_GET_IID(nsISupports), - getter_AddRefs(wrapper)); + rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), mObject, + NS_GET_IID(nsISupports), getter_AddRefs(wrapper)); NS_ENSURE_SUCCESS(rv, rv); JSObject* obj = nsnull; @@ -139,20 +143,42 @@ nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent) return NS_OK; } - rv = xpc->WrapNative(cx, obj, aEvent, NS_GET_IID(nsIDOMEvent), - getter_AddRefs(wrapper)); - NS_ENSURE_SUCCESS(rv, rv); + if (eventString.Equals(NS_LITERAL_STRING("onerror"))) { + nsCOMPtr priv(do_QueryInterface(aEvent)); + NS_ENSURE_TRUE(priv, NS_ERROR_UNEXPECTED); - JSObject *eventObj = nsnull; - rv = wrapper->GetJSObject(&eventObj); - NS_ENSURE_SUCCESS(rv, rv); + nsScriptErrorEvent *event; + + priv->GetInternalNSEvent((nsEvent**)&event); + + argv = ::JS_PushArguments(cx, &stackPtr, "WWi", event->errorMsg, + event->fileName, event->lineNr); + NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY); + + argc = 3; + } else { + rv = xpc->WrapNative(cx, obj, aEvent, NS_GET_IID(nsIDOMEvent), + getter_AddRefs(wrapper)); + NS_ENSURE_SUCCESS(rv, rv); + + JSObject *eventObj = nsnull; + rv = wrapper->GetJSObject(&eventObj); + NS_ENSURE_SUCCESS(rv, rv); + + argv[0] = OBJECT_TO_JSVAL(eventObj); + argc = 1; + } - argv[0] = OBJECT_TO_JSVAL(eventObj); PRBool jsBoolResult; PRBool returnResult = (mReturnResult == nsReturnResult_eReverseReturnResult); - rv = mContext->CallEventHandler(obj, JSVAL_TO_OBJECT(funval), 1, argv, + rv = mContext->CallEventHandler(obj, JSVAL_TO_OBJECT(funval), argc, argv, &jsBoolResult, returnResult); + + if (argv != &arg) { + ::JS_PopArguments(cx, &stackPtr); + } + if (NS_FAILED(rv)) { return rv; } diff --git a/widget/public/nsGUIEvent.h b/widget/public/nsGUIEvent.h index 58ba2938e5be..038681853526 100644 --- a/widget/public/nsGUIEvent.h +++ b/widget/public/nsGUIEvent.h @@ -115,6 +115,16 @@ struct nsGUIEvent : public nsEvent { void* nativeMsg; }; +/** + * Script error event + */ + +struct nsScriptErrorEvent : public nsEvent { + PRInt32 lineNr; + const PRUnichar* errorMsg; + const PRUnichar* fileName; +}; + /** * Window resize event */