Bug 949722 - Assigning to '.onerror' of XHR appends an event listener, rather than overwriting it (only in workers), r=khuey
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Sat, 21 Dec 2013 02:22:13 +0200
changeset 171874 cb453dc051dd331349353d5ba338c0765520c54b
parent 171873 f71e6905567f49c184a99a805e5bd8dc05518ec6
child 171875 e9d4787444d387c30e2023a7577a12f9d27c33f0
push id5166
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:47:54 +0000
treeherdermozilla-aurora@977eb2548b2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs949722
milestone29.0a1
Bug 949722 - Assigning to '.onerror' of XHR appends an event listener, rather than overwriting it (only in workers), r=khuey
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
dom/src/events/nsJSEventListener.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/test/errorwarning_worker.js
dom/workers/test/xhr_worker.js
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -520,18 +520,17 @@ nsEventListenerManager::ListenerCanHandl
     return true;
   }
   if (aEvent->message == NS_USER_DEFINED_EVENT) {
     if (mIsMainThreadELM) {
       return aLs->mTypeAtom == aEvent->userType;
     }
     return aLs->mTypeString.Equals(aEvent->typeString);
   }
-  MOZ_ASSERT_IF(aEvent->eventStructType != NS_SCRIPT_ERROR_EVENT,
-                mIsMainThreadELM);
+  MOZ_ASSERT(mIsMainThreadELM);
   return aLs->mEventType == aEvent->message;
 }
 
 void
 nsEventListenerManager::AddEventListenerByType(const EventListenerHolder& aListener, 
                                                const nsAString& aType,
                                                const EventListenerFlags& aFlags)
 {
@@ -590,21 +589,16 @@ nsEventListenerManager::SetEventHandlerI
     // If we didn't find a script listener or no listeners existed
     // create and add a new one.
     EventListenerFlags flags;
     flags.mListenerIsJSListener = true;
 
     nsCOMPtr<nsIJSEventListener> scriptListener;
     NS_NewJSEventListener(aScopeObject, mTarget, aName,
                           aHandler, getter_AddRefs(scriptListener));
-
-    if (!aName && aTypeString.EqualsLiteral("error")) {
-      eventType = NS_LOAD_ERROR;
-    }
-
     EventListenerHolder holder(scriptListener);
     AddEventListenerInternal(holder, eventType, aName, aTypeString, flags,
                              true);
 
     ls = FindEventHandler(eventType, aName, aTypeString);
   } else {
     nsIJSEventListener* scriptListener = ls->GetJSListener();
     MOZ_ASSERT(scriptListener,
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -477,17 +477,17 @@ public:
     return handler ? handler->EventHandler() : nullptr;
   }
   mozilla::dom::OnErrorEventHandlerNonNull* GetOnErrorEventHandler()
   {
     const nsEventHandler* handler;
     if (mIsMainThreadELM) {
       handler = GetEventHandlerInternal(nsGkAtoms::onerror, EmptyString());
     } else {
-      handler = GetEventHandlerInternal(nullptr, NS_LITERAL_STRING("onerror"));
+      handler = GetEventHandlerInternal(nullptr, NS_LITERAL_STRING("error"));
     }
     return handler ? handler->OnErrorEventHandler() : nullptr;
   }
   mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler()
   {
     const nsEventHandler* handler =
       GetEventHandlerInternal(nsGkAtoms::onbeforeunload, EmptyString());
     return handler ? handler->OnBeforeUnloadEventHandler() : nullptr;
--- a/dom/src/events/nsJSEventListener.cpp
+++ b/dom/src/events/nsJSEventListener.cpp
@@ -164,17 +164,19 @@ nsJSEventListener::HandleEvent(nsIDOMEve
     EventOrString msgOrEvent;
     Optional<nsAString> fileName;
     Optional<uint32_t> lineNumber;
     Optional<uint32_t> columnNumber;
 
     NS_ENSURE_TRUE(aEvent, NS_ERROR_UNEXPECTED);
     InternalScriptErrorEvent* scriptEvent =
       aEvent->GetInternalNSEvent()->AsScriptErrorEvent();
-    if (scriptEvent && scriptEvent->message == NS_LOAD_ERROR) {
+    if (scriptEvent &&
+        (scriptEvent->message == NS_LOAD_ERROR ||
+         scriptEvent->typeString.EqualsLiteral("error"))) {
       errorMsg = scriptEvent->errorMsg;
       msgOrEvent.SetAsString() = static_cast<nsAString*>(&errorMsg);
 
       file = scriptEvent->fileName;
       fileName = &file;
 
       lineNumber.Construct();
       lineNumber.Value() = scriptEvent->lineNr;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1218,31 +1218,33 @@ public:
         nsEventStatus status = nsEventStatus_eIgnore;
         nsIScriptGlobalObject* sgo;
 
         if (aWorkerPrivate) {
           WorkerGlobalScope* globalTarget = aWorkerPrivate->GlobalScope();
           MOZ_ASSERT(target == globalTarget->GetWrapperPreserveColor());
 
           // Icky, we have to fire an InternalScriptErrorEvent...
-          InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
+          MOZ_ASSERT(!NS_IsMainThread());
+          InternalScriptErrorEvent event(true, NS_USER_DEFINED_EVENT);
           event.lineNr = aLineNumber;
           event.errorMsg = aMessage.get();
           event.fileName = aFilename.get();
           event.typeString = NS_LITERAL_STRING("error");
 
           nsIDOMEventTarget* target = static_cast<nsIDOMEventTarget*>(globalTarget);
           if (NS_FAILED(nsEventDispatcher::Dispatch(target, nullptr, &event,
                                                     nullptr, &status))) {
             NS_WARNING("Failed to dispatch worker thread error event!");
             status = nsEventStatus_eIgnore;
           }
         }
         else if ((sgo = nsJSUtils::GetStaticScriptGlobal(target))) {
           // Icky, we have to fire an InternalScriptErrorEvent...
+          MOZ_ASSERT(NS_IsMainThread());
           InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
           event.lineNr = aLineNumber;
           event.errorMsg = aMessage.get();
           event.fileName = aFilename.get();
 
           if (NS_FAILED(sgo->HandleScriptError(&event, &status))) {
             NS_WARNING("Failed to dispatch main thread error event!");
             status = nsEventStatus_eIgnore;
@@ -3208,16 +3210,17 @@ WorkerPrivateParent<Derived>::BroadcastE
     JSContext* cx = windowAction.mJSContext;
 
     AutoCxPusher autoPush(cx);
 
     nsCOMPtr<nsIScriptGlobalObject> sgo =
       do_QueryInterface(windowAction.mWindow);
     MOZ_ASSERT(sgo);
 
+    MOZ_ASSERT(NS_IsMainThread());
     InternalScriptErrorEvent event(true, NS_LOAD_ERROR);
     event.lineNr = aLineNumber;
     event.errorMsg = aMessage.BeginReading();
     event.fileName = aFilename.BeginReading();
 
     nsEventStatus status = nsEventStatus_eIgnore;
     rv = sgo->HandleScriptError(&event, &status);
     if (NS_FAILED(rv)) {
--- a/dom/workers/test/errorwarning_worker.js
+++ b/dom/workers/test/errorwarning_worker.js
@@ -31,8 +31,12 @@ onmessage = function(event) {
     }
 
   } else {
     postMessage({ type: 'finish' });
   }
 }
 
 onerror = errorHandler;
+onerror = onerror;
+if (!onerror || onerror != onerror) {
+  throw "onerror wasn't set properly";
+}
--- a/dom/workers/test/xhr_worker.js
+++ b/dom/workers/test/xhr_worker.js
@@ -24,24 +24,28 @@ xhr.onload = onload;
 xhr.addEventListener("load", onload, false);
 xhr.removeEventListener("load", onload, false);
 if (!xhr.onload) {
   var message = { type: "error",
                   error: "Lost message listener!" };
   postMessage(message);
 }
 
-xhr.addEventListener("error", function(event) {
+xhr.onerror = function(event) {
   if (event.target != xhr) {
     throw "onerror event.target != xhr";
   }
   var message = { type: "error",
                   error: event.target.status };
   postMessage(message);
-}, false);
+};
+xhr.onerror = xhr.onerror;
+if (!xhr.onerror || xhr.onerror != xhr.onerror) {
+  throw "onerror wasn't set properly";
+}
 
 function onprogress(event) {
   if (event.target != xhr) {
     throw "onprogress event.target != xhr";
   }
   var message = { type: "progress",
                   current: event.loaded,
                   total: event.total };