diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 7549e587361..24bfa993225 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -6156,6 +6156,22 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs, return NS_OK; } +class CommandDispatcher : public nsRunnable +{ +public: + CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher, + const nsAString& aAction) + : mDispatcher(aDispatcher), mAction(aAction) {} + + NS_IMETHOD Run() + { + return mDispatcher->UpdateCommands(mAction); + } + + nsCOMPtr mDispatcher; + nsString mAction; +}; + NS_IMETHODIMP nsGlobalWindow::UpdateCommands(const nsAString& anAction) { @@ -6170,7 +6186,10 @@ nsGlobalWindow::UpdateCommands(const nsAString& anAction) // Retrieve the command dispatcher and call updateCommands on it. nsCOMPtr xulCommandDispatcher; xulDoc->GetCommandDispatcher(getter_AddRefs(xulCommandDispatcher)); - xulCommandDispatcher->UpdateCommands(anAction); + if (xulCommandDispatcher) { + nsContentUtils::AddScriptRunner(new CommandDispatcher(xulCommandDispatcher, + anAction)); + } } return NS_OK; diff --git a/mozilla/dom/src/base/nsJSEnvironment.cpp b/mozilla/dom/src/base/nsJSEnvironment.cpp index 2c3254db49d..9343645bf0a 100644 --- a/mozilla/dom/src/base/nsJSEnvironment.cpp +++ b/mozilla/dom/src/base/nsJSEnvironment.cpp @@ -420,6 +420,129 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal, return called; } +class ScriptErrorEvent : public nsRunnable +{ +public: + ScriptErrorEvent(nsIScriptGlobalObject* aScriptGlobal, + PRUint32 aLineNr, PRUint32 aColumn, PRUint32 aFlags, + const nsAString& aErrorMsg, + const nsAString& aFileName, + const nsAString& aSourceLine, + PRBool aDispatchEvent) + : mScriptGlobal(aScriptGlobal), mLineNr(aLineNr), mColumn(aColumn), + mFlags(aFlags), mErrorMsg(aErrorMsg), mFileName(aFileName), + mSourceLine(aSourceLine), mDispatchEvent(aDispatchEvent) {} + + NS_IMETHOD Run() + { + nsEventStatus status = nsEventStatus_eIgnore; + // First, notify the DOM that we have a script error. + if (mDispatchEvent) { + nsCOMPtr win(do_QueryInterface(mScriptGlobal)); + nsIDocShell* docShell = win ? win->GetDocShell() : nsnull; + if (docShell && + !JSREPORT_IS_WARNING(mFlags) && + !sHandlingScriptError) { + sHandlingScriptError = PR_TRUE; // Recursion prevention + + nsCOMPtr presContext; + docShell->GetPresContext(getter_AddRefs(presContext)); + + if (presContext) { + nsScriptErrorEvent errorevent(PR_TRUE, NS_LOAD_ERROR); + + errorevent.fileName = mFileName.get(); + + nsCOMPtr sop(do_QueryInterface(win)); + NS_ENSURE_STATE(sop); + nsIPrincipal* p = sop->GetPrincipal(); + NS_ENSURE_STATE(p); + + PRBool sameOrigin = mFileName.IsVoid(); + + if (p && !sameOrigin) { + nsCOMPtr errorURI; + NS_NewURI(getter_AddRefs(errorURI), mFileName); + if (errorURI) { + // FIXME: Once error reports contain the origin of the + // error (principals) we should change this to do the + // security check based on the principals and not + // URIs. See bug 387476. + sameOrigin = NS_SUCCEEDED(p->CheckMayLoad(errorURI, PR_FALSE)); + } + } + + NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error."); + if (sameOrigin) { + errorevent.errorMsg = mErrorMsg.get(); + errorevent.lineNr = mLineNr; + } else { + NS_WARNING("Not same origin error!"); + errorevent.errorMsg = xoriginMsg.get(); + errorevent.lineNr = 0; + } + + nsEventDispatcher::Dispatch(win, presContext, &errorevent, nsnull, + &status); + } + + sHandlingScriptError = PR_FALSE; + } + } + + if (status != nsEventStatus_eConsumeNoDefault) { + // Make an nsIScriptError and populate it with information from + // this error. + nsCOMPtr errorObject = + do_CreateInstance("@mozilla.org/scripterror;1"); + + if (errorObject != nsnull) { + nsresult rv = NS_ERROR_NOT_AVAILABLE; + + // Set category to chrome or content + nsCOMPtr scriptPrincipal = + do_QueryInterface(mScriptGlobal); + NS_ASSERTION(scriptPrincipal, "Global objects must implement " + "nsIScriptObjectPrincipal"); + nsCOMPtr systemPrincipal; + sSecurityManager->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); + const char * category = + scriptPrincipal->GetPrincipal() == systemPrincipal + ? "chrome javascript" + : "content javascript"; + + rv = errorObject->Init(mErrorMsg.get(), mFileName.get(), + mSourceLine.get(), + mLineNr, mColumn, mFlags, + category); + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + consoleService->LogMessage(errorObject); + } + } + } + } + return NS_OK; + } + + + nsCOMPtr mScriptGlobal; + PRUint32 mLineNr; + PRUint32 mColumn; + PRUint32 mFlags; + nsString mErrorMsg; + nsString mFileName; + nsString mSourceLine; + PRBool mDispatchEvent; + + static PRBool sHandlingScriptError; +}; + +PRBool ScriptErrorEvent::sHandlingScriptError = PR_FALSE; + // NOTE: This function could be refactored to use the above. The only reason // it has not been done is that the code below only fills the error event // after it has a good nsPresContext - whereas using the above function @@ -432,8 +555,6 @@ NS_ScriptErrorReporter(JSContext *cx, // XXX this means we are not going to get error reports on non DOM contexts nsIScriptContext *context = nsJSUtils::GetDynamicScriptContext(cx); - nsEventStatus status = nsEventStatus_eIgnore; - // Note: we must do this before running any more code on cx (if cx is the // dynamic script context). ::JS_ClearPendingException(cx); @@ -443,9 +564,11 @@ NS_ScriptErrorReporter(JSContext *cx, if (globalObject) { nsAutoString fileName, msg; - NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error."); - - fileName.AssignWithConversion(report->filename); + if (!report->filename) { + fileName.SetIsVoid(PR_TRUE); + } else { + fileName.AssignWithConversion(report->filename); + } const PRUnichar *m = reinterpret_cast (report->ucmessage); @@ -457,113 +580,20 @@ NS_ScriptErrorReporter(JSContext *cx, msg.AssignWithConversion(message); } - // First, notify the DOM that we have a script error. + /* We do not try to report Out Of Memory via a dom * event because the dom event handler would encounter * an OOM exception trying to process the event, and * then we'd need to generate a new OOM event for that * new OOM instance -- this isn't pretty. */ - { - // Scope to make sure we're not using |win| in the rest of - // this function when we should be using |globalObject|. We - // only need |win| for the event dispatch. - nsCOMPtr win(do_QueryInterface(globalObject)); - nsIDocShell *docShell = win ? win->GetDocShell() : nsnull; - if (docShell && - (report->errorNumber != JSMSG_OUT_OF_MEMORY && - !JSREPORT_IS_WARNING(report->flags))) { - static PRInt32 errorDepth; // Recursion prevention - ++errorDepth; - - nsCOMPtr presContext; - docShell->GetPresContext(getter_AddRefs(presContext)); - - if (presContext && errorDepth < 2) { - nsScriptErrorEvent errorevent(PR_TRUE, NS_LOAD_ERROR); - - errorevent.fileName = fileName.get(); - - nsCOMPtr sop(do_QueryInterface(win)); - nsIPrincipal *p = sop->GetPrincipal(); - - PRBool sameOrigin = (report->filename == nsnull); - - if (p && !sameOrigin) { - nsCOMPtr errorURI; - NS_NewURI(getter_AddRefs(errorURI), report->filename); - - nsCOMPtr codebase; - p->GetURI(getter_AddRefs(codebase)); - - if (errorURI && codebase) { - // FIXME: Once error reports contain the origin of the - // error (principals) we should change this to do the - // security check based on the principals and not - // URIs. See bug 387476. - sameOrigin = - NS_SUCCEEDED(sSecurityManager-> - CheckSameOriginURI(errorURI, codebase, - PR_FALSE)); - } - } - - if (sameOrigin) { - errorevent.errorMsg = msg.get(); - errorevent.lineNr = report->lineno; - } else { - errorevent.errorMsg = xoriginMsg.get(); - errorevent.lineNr = 0; - } - - // Dispatch() must be synchronous for the recursion block - // (errorDepth) to work. - nsEventDispatcher::Dispatch(win, presContext, &errorevent, nsnull, - &status); - } - - --errorDepth; - } - } - - if (status != nsEventStatus_eConsumeNoDefault) { - // Make an nsIScriptError and populate it with information from - // this error. - nsCOMPtr errorObject = - do_CreateInstance("@mozilla.org/scripterror;1"); - - if (errorObject != nsnull) { - nsresult rv = NS_ERROR_NOT_AVAILABLE; - - // Set category to chrome or content - nsCOMPtr scriptPrincipal = - do_QueryInterface(globalObject); - NS_ASSERTION(scriptPrincipal, "Global objects must implement " - "nsIScriptObjectPrincipal"); - nsCOMPtr systemPrincipal; - sSecurityManager->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - const char * category = - scriptPrincipal->GetPrincipal() == systemPrincipal - ? "chrome javascript" - : "content javascript"; - - PRUint32 column = report->uctokenptr - report->uclinebuf; - - rv = errorObject->Init(msg.get(), fileName.get(), - reinterpret_cast - (report->uclinebuf), - report->lineno, column, report->flags, - category); - - if (NS_SUCCEEDED(rv)) { - nsCOMPtr consoleService = - do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) { - consoleService->LogMessage(errorObject); - } - } - } - } + nsAutoString sourceLine; + sourceLine.Assign(reinterpret_cast(report->uclinebuf)); + nsContentUtils::AddScriptRunner( + new ScriptErrorEvent(globalObject, report->lineno, + report->uctokenptr - report->uclinebuf, + report->flags, msg, fileName, sourceLine, + report->errorNumber != JSMSG_OUT_OF_MEMORY)); } } @@ -588,8 +618,7 @@ NS_ScriptErrorReporter(JSContext *cx, } else { error.Append(message); } - if (status != nsEventStatus_eIgnore && !JSREPORT_IS_WARNING(report->flags)) - error.Append(" Error was suppressed by event handler\n"); + fprintf(stderr, "%s\n", error.get()); fflush(stderr); #endif diff --git a/mozilla/dom/tests/mochitest/bugs/Makefile.in b/mozilla/dom/tests/mochitest/bugs/Makefile.in index 9223c1ae975..97dcb80782c 100644 --- a/mozilla/dom/tests/mochitest/bugs/Makefile.in +++ b/mozilla/dom/tests/mochitest/bugs/Makefile.in @@ -81,6 +81,7 @@ _TEST_FILES = \ iframe_bug440572.html \ test_bug504862.html \ file_bug504862.html \ + test_bug531176.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/mozilla/dom/tests/mochitest/bugs/test_bug531176.html b/mozilla/dom/tests/mochitest/bugs/test_bug531176.html new file mode 100644 index 00000000000..a534794cf4e --- /dev/null +++ b/mozilla/dom/tests/mochitest/bugs/test_bug531176.html @@ -0,0 +1,61 @@ + + + + + Test for Bug 531176 + + + + + +Mozilla Bug 531176 +

+ +
+
+
+
+
+ + diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index aacf89090f8..76a70354e15 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -90,6 +90,7 @@ #include "nsDisplayList.h" #include "nsITheme.h" #include "nsThemeConstants.h" +#include "nsPLDOMEvent.h" NS_IMETHODIMP nsComboboxControlFrame::RedisplayTextEvent::Run() @@ -1485,18 +1486,9 @@ nsComboboxControlFrame::OnOptionSelected(nsPresContext* aPresContext, void nsComboboxControlFrame::FireValueChangeEvent() { // Fire ValueChange event to indicate data value of combo box has changed - nsCOMPtr event; - nsPresContext* presContext = PresContext(); - if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(presContext, nsnull, - NS_LITERAL_STRING("Events"), - getter_AddRefs(event)))) { - event->InitEvent(NS_LITERAL_STRING("ValueChange"), PR_TRUE, PR_TRUE); - - nsCOMPtr privateEvent(do_QueryInterface(event)); - privateEvent->SetTrusted(PR_TRUE); - nsEventDispatcher::DispatchDOMEvent(mContent, nsnull, event, nsnull, - nsnull); - } + nsCOMPtr node = do_QueryInterface(mContent); + nsContentUtils::AddScriptRunner(new nsPLDOMEvent(node, + NS_LITERAL_STRING("ValueChange"))); } void