Bug 687332: Part 2 - Move event handlers off of DOM objects and keep track of them solely in the event listener manager. r=smaug,bz
authorKyle Huey <khuey@kylehuey.com>
Thu, 30 Aug 2012 20:45:16 -0700
changeset 107551 0a1f4d81635adf13c29c71aa80d4e44198125119
parent 107550 9baa8a16f944ba4b8bfa4656cf645819e87fc7b3
child 107552 e3f700f4d0cb300c911ace391bf73454491887b6
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, bz
bugs687332
milestone18.0a1
Bug 687332: Part 2 - Move event handlers off of DOM objects and keep track of them solely in the event listener manager. r=smaug,bz
content/base/public/nsIDOMFileReader.idl
content/base/public/nsIEventSource.idl
content/base/public/nsIWebSocket.idl
content/base/public/nsIXMLHttpRequest.idl
content/base/src/FileIOObject.cpp
content/base/src/FileIOObject.h
content/base/src/nsDOMFileReader.cpp
content/base/src/nsDOMFileReader.h
content/base/src/nsEventSource.cpp
content/base/src/nsEventSource.h
content/base/src/nsGkAtomList.h
content/base/src/nsINode.cpp
content/base/src/nsWebSocket.cpp
content/base/src/nsWebSocket.h
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/base/test/test_XHR.html
content/base/test/test_xhr_abort_after_load.html
content/events/src/nsDOMEventTargetHelper.cpp
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
dom/base/DOMRequest.cpp
dom/base/DOMRequest.h
dom/base/nsGlobalWindow.cpp
dom/base/nsIDOMDOMRequest.idl
dom/base/nsScreen.cpp
dom/base/nsScreen.h
dom/battery/BatteryManager.cpp
dom/battery/BatteryManager.h
dom/battery/nsIDOMBatteryManager.idl
dom/bluetooth/BluetoothAdapter.cpp
dom/bluetooth/BluetoothAdapter.h
dom/bluetooth/BluetoothDevice.cpp
dom/bluetooth/BluetoothDevice.h
dom/bluetooth/BluetoothManager.cpp
dom/bluetooth/BluetoothManager.h
dom/bluetooth/nsIDOMBluetoothAdapter.idl
dom/bluetooth/nsIDOMBluetoothDevice.idl
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
dom/file/FileHandle.cpp
dom/file/FileHandle.h
dom/file/FileRequest.cpp
dom/file/FileRequest.h
dom/file/LockedFile.cpp
dom/file/LockedFile.h
dom/file/nsIDOMFileHandle.idl
dom/file/nsIDOMFileRequest.idl
dom/file/nsIDOMLockedFile.idl
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBDatabase.h
dom/indexedDB/IDBRequest.cpp
dom/indexedDB/IDBRequest.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
dom/indexedDB/nsIIDBDatabase.idl
dom/indexedDB/nsIIDBOpenDBRequest.idl
dom/indexedDB/nsIIDBRequest.idl
dom/indexedDB/nsIIDBTransaction.idl
dom/indexedDB/test/test_autoIncrement.html
dom/indexedDB/test/test_file_quota.html
dom/indexedDB/test/test_filehandle_quota.html
dom/indexedDB/test/test_unique_index_update.html
dom/indexedDB/test/unit/test_add_twice_failure.js
dom/indexedDB/test/unit/test_index_empty_keyPath.js
dom/indexedDB/test/unit/test_indexes.js
dom/indexedDB/test/unit/test_key_requirements.js
dom/indexedDB/test/unit/test_keys.js
dom/indexedDB/test/unit/test_traffic_jam.js
dom/interfaces/base/nsIDOMScreen.idl
dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
dom/interfaces/notification/nsIDOMDesktopNotification.idl
dom/interfaces/offline/nsIDOMOfflineResourceList.idl
dom/network/interfaces/nsIDOMConnection.idl
dom/network/interfaces/nsIDOMMobileConnection.idl
dom/network/src/Connection.cpp
dom/network/src/Connection.h
dom/network/src/MobileConnection.cpp
dom/network/src/MobileConnection.h
dom/sms/interfaces/nsIDOMSmsManager.idl
dom/sms/interfaces/nsIDOMSmsRequest.idl
dom/sms/src/SmsManager.cpp
dom/sms/src/SmsManager.h
dom/sms/src/SmsRequest.cpp
dom/sms/src/SmsRequest.h
dom/src/notification/nsDesktopNotification.cpp
dom/src/notification/nsDesktopNotification.h
dom/src/offline/nsDOMOfflineResourceList.cpp
dom/src/offline/nsDOMOfflineResourceList.h
dom/telephony/Telephony.cpp
dom/telephony/Telephony.h
dom/telephony/TelephonyCall.cpp
dom/telephony/TelephonyCall.h
dom/telephony/Voicemail.cpp
dom/telephony/Voicemail.h
dom/telephony/nsIDOMTelephony.idl
dom/telephony/nsIDOMTelephonyCall.idl
dom/telephony/nsIDOMVoicemail.idl
js/xpconnect/src/nsXPConnect.cpp
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
 interface nsIDOMDOMError;
 
-[scriptable, builtinclass, uuid(faed1779-b523-4060-8c3b-7199f347b273)]
+[scriptable, builtinclass, uuid(62a1628e-c856-4aee-8273-d0c62488e2ca)]
 interface nsIDOMFileReader : nsIDOMEventTarget
 {
   [implicit_jscontext]
   void readAsArrayBuffer(in nsIDOMBlob filedata);
   void readAsBinaryString(in nsIDOMBlob filedata);
   void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMBlob file);
 
@@ -24,22 +24,22 @@ interface nsIDOMFileReader : nsIDOMEvent
   const unsigned short LOADING = 1;
   const unsigned short DONE = 2;
   readonly attribute unsigned short readyState;
 
   [implicit_jscontext]
   readonly attribute jsval result;
   readonly attribute nsIDOMDOMError error;
 
-  attribute nsIDOMEventListener onloadstart;
-  attribute nsIDOMEventListener onprogress;
-  attribute nsIDOMEventListener onload;
-  attribute nsIDOMEventListener onabort;
-  attribute nsIDOMEventListener onerror;
-  attribute nsIDOMEventListener onloadend;
+  [implicit_jscontext] attribute jsval onloadstart;
+  [implicit_jscontext] attribute jsval onprogress;
+  [implicit_jscontext] attribute jsval onload;
+  [implicit_jscontext] attribute jsval onabort;
+  [implicit_jscontext] attribute jsval onerror;
+  [implicit_jscontext] attribute jsval onloadend;
 };
 
 %{ C++
 #define NS_FILEREADER_CID                            \
 {0x06aa7c21, 0xfe05, 0x4cf2,                         \
 {0xb1, 0xc4, 0x0c, 0x71, 0x26, 0xa4, 0xf7, 0x13}}
 #define NS_FILEREADER_CONTRACTID \
 "@mozilla.org/files/filereader;1"
--- a/content/base/public/nsIEventSource.idl
+++ b/content/base/public/nsIEventSource.idl
@@ -12,36 +12,36 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMEventListener;
 interface nsIPrincipal;
 interface nsIScriptContext;
 interface nsPIDOMWindow;
 
-[scriptable, uuid(a3d3181e-47c1-4f2e-b2c7-94775a86f5c5)]
+[scriptable, uuid(778e5ae3-c72c-4d4b-9dc7-4a6477651957)]
 interface nsIEventSource : nsISupports
 {
   readonly attribute DOMString url;
 
   // ready state
   const unsigned short CONNECTING = 0;
   const unsigned short OPEN = 1;
   const unsigned short CLOSED = 2;
   readonly attribute long readyState;
 
   // if true then cross-site Access-Control requests are made using credentials
   // such as cookies and authorization headers. Never affects same-site
   // requests.
   readonly attribute boolean withCredentials;
 
   // event handler attributes
-  attribute nsIDOMEventListener onopen;
-  attribute nsIDOMEventListener onmessage;
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onopen;
+  [implicit_jscontext] attribute jsval onmessage;
+  [implicit_jscontext] attribute jsval onerror;
 
   /**
    * Close the connection, if any, and set the readyState attribute to CLOSED.
    * If the connection is already closed, the method does nothing.
    */
   void close();
 
   /**
--- a/content/base/public/nsIWebSocket.idl
+++ b/content/base/public/nsIWebSocket.idl
@@ -21,17 +21,17 @@ class nsString;
 
 /**
  * The nsIWebSocket interface enables Web applications to maintain
  * bidirectional communications with server-side processes as described in:
  *
  * http://dev.w3.org/html5/websockets/
  *
  */
-[scriptable, uuid(e59c8c65-df29-485c-a00b-8fac3dc1573a)]
+[scriptable, uuid(5224dbe7-58ac-43e6-93ba-f288a1421dff)]
 interface nsIWebSocket : nsISupports
 {
   readonly attribute DOMString url;
   readonly attribute DOMString extensions;
   readonly attribute DOMString protocol;
 
   //ready state
   const unsigned short CONNECTING = 0;
@@ -42,20 +42,20 @@ interface nsIWebSocket : nsISupports
 
   readonly attribute unsigned long bufferedAmount;
 
   // "blob" by default: can set to "blob" or "arraybuffer": setting to other
   // values will throw SYNTAX_ERR exception.
   attribute DOMString binaryType;
 
   // event handler attributes
-  attribute nsIDOMEventListener onopen;
-  attribute nsIDOMEventListener onmessage;
-  attribute nsIDOMEventListener onerror;
-  attribute nsIDOMEventListener onclose;
+  [implicit_jscontext] attribute jsval onopen;
+  [implicit_jscontext] attribute jsval onmessage;
+  [implicit_jscontext] attribute jsval onerror;
+  [implicit_jscontext] attribute jsval onclose;
 
   /**
    * Transmits data to other end of the connection.
    * @param data The data to be transmitted.  Arraybuffers and Blobs are sent as
    * binary data.  Strings are sent as UTF-8 text data.  Other types are
    * converted to a String and sent as a String.
    * @return if the connection is still established and the data was queued or
    *         sent successfully.
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -37,26 +37,26 @@ dictionary XMLHttpRequestParameters
   boolean mozAnon;
 
   /**
    * If true, the same origin policy will not be enforced on the request.
    */
   boolean mozSystem;
 };
 
-[scriptable, builtinclass, uuid(5e346bf8-7083-4ef8-b9b9-736a1b5aa7ab)]
+[scriptable, builtinclass, uuid(a137d5e6-81e2-4fa3-a791-26459df723ff)]
 interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
   // event handler attributes
-  attribute nsIDOMEventListener onabort;
-  attribute nsIDOMEventListener onerror;
-  attribute nsIDOMEventListener onload;
-  attribute nsIDOMEventListener onloadstart;
-  attribute nsIDOMEventListener onprogress;
-  attribute nsIDOMEventListener ontimeout;
-  attribute nsIDOMEventListener onloadend;
+  [implicit_jscontext] attribute jsval onabort;
+  [implicit_jscontext] attribute jsval onerror;
+  [implicit_jscontext] attribute jsval onload;
+  [implicit_jscontext] attribute jsval onloadstart;
+  [implicit_jscontext] attribute jsval onprogress;
+  [implicit_jscontext] attribute jsval ontimeout;
+  [implicit_jscontext] attribute jsval onloadend;
 };
 
 [scriptable, builtinclass, uuid(8dbd2448-740a-412c-b314-434f24a1c510)]
 interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
   // for future use
 };
 
 /**
@@ -95,17 +95,17 @@ interface nsIXMLHttpRequestUpload : nsIX
  *   The 'onload', 'onerror', and 'onreadystatechange' attributes moved to
  *   nsIJSXMLHttpRequest, but if you're coding in C++ you should avoid using
  *   those.
  *
  * Conclusion: Do not use event listeners on XMLHttpRequest from C++, unless
  * you're aware of all the security implications.  And then think twice about
  * it.
  */
-[scriptable, uuid(2ed23d20-9d6d-47fd-b60f-2416dbd57005)]
+[scriptable, uuid(8e9768b4-339c-413c-a210-0c74934eb9e1)]
 interface nsIXMLHttpRequest : nsISupports
 {
   /**
    * The request uses a channel in order to perform the
    * request.  This attribute represents the channel used
    * for the request.  NULL if the channel has not yet been
    * created.
    *
@@ -366,17 +366,17 @@ interface nsIXMLHttpRequest : nsISupport
    * readyState changes, the callback function will be called.
    * This attribute should not be used from native code!!
    *
    * After the initial response, all event listeners will be cleared.
    * // XXXbz what does that mean, exactly?   
    *
    * Call open() before setting an onreadystatechange listener.
    */
-  attribute nsIDOMEventListener onreadystatechange;
+  [implicit_jscontext] attribute jsval onreadystatechange;
 
   /**
    * If true, the request will be sent without cookie and authentication
    * headers.
    */
   readonly attribute boolean mozAnon;
 
   /**
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -29,32 +29,30 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressNotifier)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mError)
   // Can't traverse mChannel because it's a multithreaded object.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressNotifier)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+ 
+NS_IMPL_EVENT_HANDLER(FileIOObject, abort);
+NS_IMPL_EVENT_HANDLER(FileIOObject, error);
+NS_IMPL_EVENT_HANDLER(FileIOObject, progress);
 
 FileIOObject::FileIOObject()
   : mProgressEventWasDelayed(false),
     mTimerIsActive(false),
     mReadyState(0),
     mTotal(0), mTransferred(0)
 {}
 
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -35,19 +35,22 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Common methods
   NS_METHOD Abort();
   NS_METHOD GetReadyState(uint16_t* aReadyState);
   NS_METHOD GetError(nsIDOMDOMError** aError);
 
-  NS_DECL_AND_IMPL_EVENT_HANDLER(abort);
-  NS_DECL_AND_IMPL_EVENT_HANDLER(error);
-  NS_DECL_AND_IMPL_EVENT_HANDLER(progress);
+  NS_METHOD GetOnabort(JSContext* aCx, JS::Value* aValue);
+  NS_METHOD SetOnabort(JSContext* aCx, const JS::Value& aValue);
+  NS_METHOD GetOnerror(JSContext* aCx, JS::Value* aValue);
+  NS_METHOD SetOnerror(JSContext* aCx, const JS::Value& aValue);
+  NS_METHOD GetOnprogress(JSContext* aCx, JS::Value* aValue);
+  NS_METHOD SetOnprogress(JSContext* aCx, const JS::Value& aValue);
 
   NS_DECL_NSITIMERCALLBACK
 
   NS_DECL_NSISTREAMLISTENER
 
   NS_DECL_NSIREQUESTOBSERVER
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileIOObject,
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -57,29 +57,23 @@ using namespace mozilla;
 using mozilla::dom::FileIOObject;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
                                                   FileIOObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(load)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(loadstart)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(loadend)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
                                                 FileIOObject)
   tmp->mResultArrayBuffer = nullptr;
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(load)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(loadstart)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(loadend)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsDOMFileReader,
                                                nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mResultArrayBuffer)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
@@ -91,16 +85,23 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileReader)
 NS_INTERFACE_MAP_END_INHERITING(FileIOObject)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMFileReader, FileIOObject)
 NS_IMPL_RELEASE_INHERITED(nsDOMFileReader, FileIOObject)
 
+NS_IMPL_EVENT_HANDLER(nsDOMFileReader, load)
+NS_IMPL_EVENT_HANDLER(nsDOMFileReader, loadend)
+NS_IMPL_EVENT_HANDLER(nsDOMFileReader, loadstart)
+NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, abort, FileIOObject)
+NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, progress, FileIOObject)
+NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
+
 void
 nsDOMFileReader::RootResultArrayBuffer()
 {
   nsContentUtils::PreserveWrapper(
     static_cast<nsIDOMEventTarget*>(
       static_cast<nsDOMEventTargetHelper*>(this)), this);
 }
 
@@ -134,23 +135,16 @@ nsDOMFileReader::Init()
     NS_ENSURE_SUCCESS(rv, rv);
   }
   NS_ENSURE_STATE(subjectPrincipal);
   mPrincipal.swap(subjectPrincipal);
 
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(nsDOMFileReader, load)
-NS_IMPL_EVENT_HANDLER(nsDOMFileReader, loadstart)
-NS_IMPL_EVENT_HANDLER(nsDOMFileReader, loadend)
-NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, abort, FileIOObject)
-NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, progress, FileIOObject)
-NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
-
 NS_IMETHODIMP
 nsDOMFileReader::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
                             uint32_t argc, jsval *argv)
 {
   nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(aOwner);
   if (!owner) {
     NS_WARNING("Unexpected nsIJSNativeInitializer owner");
     return NS_OK;
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -42,20 +42,16 @@ public:
 
   NS_DECL_NSIDOMFILEREADER
 
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
   // nsIInterfaceRequestor 
   NS_DECL_NSIINTERFACEREQUESTOR
 
-  NS_DECL_EVENT_HANDLER(load)
-  NS_DECL_EVENT_HANDLER(loadend)
-  NS_DECL_EVENT_HANDLER(loadstart)
-
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
                         uint32_t argc, jsval* argv);
 
   // FileIOObject overrides
   NS_IMETHOD DoAbort(nsAString& aEvent);
   NS_IMETHOD DoOnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
                              nsresult aStatus, nsAString& aSuccessEvent,
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -77,19 +77,16 @@ nsEventSource::~nsEventSource()
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsEventSource)
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsEventSource)
   bool isBlack = tmp->IsBlack();
   if (isBlack || tmp->mWaitingForOnStopRequest) {
     if (tmp->mListenerManager) {
       tmp->mListenerManager->UnmarkGrayJSListeners();
-      NS_UNMARK_LISTENER_WRAPPER(Open)
-      NS_UNMARK_LISTENER_WRAPPER(Message)
-      NS_UNMARK_LISTENER_WRAPPER(Error)
     }
     if (!isBlack && tmp->PreservingWrapper()) {
       xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor());
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
@@ -108,27 +105,21 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsEventSource,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSrc)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNotificationCallbacks)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLoadGroup)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHttpChannel)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTimer)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnOpenListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnMessageListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mUnicodeDecoder)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsEventSource, nsDOMEventTargetHelper)
   tmp->Close();
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnOpenListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnMessageListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(EventSource, nsEventSource)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsEventSource)
   NS_INTERFACE_MAP_ENTRY(nsIEventSource)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
@@ -138,23 +129,24 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(EventSource)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsEventSource, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsEventSource, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsEventSource, open)
+NS_IMPL_EVENT_HANDLER(nsEventSource, message)
+NS_IMPL_EVENT_HANDLER(nsEventSource, error)
+
 void
 nsEventSource::DisconnectFromOwner()
 {
   nsDOMEventTargetHelper::DisconnectFromOwner();
-  NS_DISCONNECT_EVENT_HANDLER(Open)
-  NS_DISCONNECT_EVENT_HANDLER(Message)
-  NS_DISCONNECT_EVENT_HANDLER(Error)
   Close();
 }
 
 //-----------------------------------------------------------------------------
 // nsEventSource::nsIEventSource
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
@@ -175,34 +167,16 @@ nsEventSource::GetReadyState(int32_t *aR
 NS_IMETHODIMP
 nsEventSource::GetWithCredentials(bool *aWithCredentials)
 {
   NS_ENSURE_ARG_POINTER(aWithCredentials);
   *aWithCredentials = mWithCredentials;
   return NS_OK;
 }
 
-#define NS_EVENTSRC_IMPL_DOMEVENTLISTENER(_eventlistenername, _eventlistener)  \
-  NS_IMETHODIMP                                                                \
-  nsEventSource::GetOn##_eventlistenername(nsIDOMEventListener * *aListener)   \
-  {                                                                            \
-    return GetInnerEventListener(_eventlistener, aListener);                   \
-  }                                                                            \
-                                                                               \
-  NS_IMETHODIMP                                                                \
-  nsEventSource::SetOn##_eventlistenername(nsIDOMEventListener * aListener)    \
-  {                                                                            \
-    return RemoveAddEventListener(NS_LITERAL_STRING(#_eventlistenername),      \
-                                  _eventlistener, aListener);                  \
-  }
-
-NS_EVENTSRC_IMPL_DOMEVENTLISTENER(open, mOnOpenListener)
-NS_EVENTSRC_IMPL_DOMEVENTLISTENER(error, mOnErrorListener)
-NS_EVENTSRC_IMPL_DOMEVENTLISTENER(message, mOnMessageListener)
-
 NS_IMETHODIMP
 nsEventSource::Close()
 {
   if (mReadyState == nsIEventSource::CLOSED) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
--- a/content/base/src/nsEventSource.h
+++ b/content/base/src/nsEventSource.h
@@ -187,20 +187,16 @@ protected:
   bool mWaitingForOnStopRequest;
 
   // used while reading the input streams
   nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
   nsresult mLastConvertionResult;
   nsString mLastFieldName;
   nsString mLastFieldValue;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnOpenListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnMessageListener;
-
   nsCOMPtr<nsILoadGroup> mLoadGroup;
 
   /**
    * The notification callbacks the channel had initially.
    * We want to forward things here as needed.
    */
   nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
   nsCOMPtr<nsIChannelEventSink>   mChannelEventSink;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -611,41 +611,63 @@ GK_ATOM(observer, "observer")
 GK_ATOM(observes, "observes")
 GK_ATOM(odd, "odd")
 GK_ATOM(OFF, "OFF")
 GK_ATOM(ol, "ol")
 GK_ATOM(omitXmlDeclaration, "omit-xml-declaration")
 GK_ATOM(onabort, "onabort")
 GK_ATOM(onafterprint, "onafterprint")
 GK_ATOM(onafterscriptexecute, "onafterscriptexecute")
+GK_ATOM(onalerting, "onalerting")
 GK_ATOM(onanimationend, "onanimationend")
 GK_ATOM(onanimationiteration, "onanimationiteration")
 GK_ATOM(onanimationstart, "onanimationstart")
+GK_ATOM(onauthorize, "onauthorize")
 GK_ATOM(onAppCommand, "onAppCommand")
 GK_ATOM(onbeforecopy, "onbeforecopy")
 GK_ATOM(onbeforecut, "onbeforecut")
 GK_ATOM(onbeforepaste, "onbeforepaste")
 GK_ATOM(onbeforeprint, "onbeforeprint")
 GK_ATOM(onbeforescriptexecute, "onbeforescriptexecute")
 GK_ATOM(onbeforeunload, "onbeforeunload")
 GK_ATOM(onblocked, "onblocked")
 GK_ATOM(onblur, "onblur")
 GK_ATOM(onbroadcast, "onbroadcast")
+GK_ATOM(onbusy, "onbusy")
+GK_ATOM(oncached, "oncached")
+GK_ATOM(oncallschanged, "oncallschanged")
+GK_ATOM(oncancel, "oncancel")
+GK_ATOM(oncardstatechange, "oncardstatechange")
 GK_ATOM(onchange, "onchange")
+GK_ATOM(onchargingchange, "onchargingchange")
+GK_ATOM(onchargingtimechange, "onchargingtimechange")
+GK_ATOM(onchecking, "onchecking")
 GK_ATOM(onclick, "onclick")
 GK_ATOM(onclose, "onclose")
 GK_ATOM(oncommand, "oncommand")
 GK_ATOM(oncommandupdate, "oncommandupdate")
+GK_ATOM(oncomplete, "oncomplete")
 GK_ATOM(oncompositionend, "oncompositionend")
 GK_ATOM(oncompositionstart, "oncompositionstart")
 GK_ATOM(oncompositionupdate, "oncompositionupdate")
+GK_ATOM(onconnected, "onconnected")
+GK_ATOM(onconnecting, "onconnecting")
 GK_ATOM(oncontextmenu, "oncontextmenu")
 GK_ATOM(oncopy, "oncopy")
 GK_ATOM(oncut, "oncut")
+GK_ATOM(ondatachange, "ondatachange")
 GK_ATOM(ondblclick, "ondblclick")
+GK_ATOM(ondelivered, "ondelivered")
+GK_ATOM(ondevicedisappeared, "ondevicedisappeared")
+GK_ATOM(ondevicefound, "ondevicefound")
+GK_ATOM(ondialing, "ondialing")
+GK_ATOM(ondischargingtimechange, "ondischargingtimechange")
+GK_ATOM(ondisconnected, "ondisconnected")
+GK_ATOM(ondisconnecting, "ondisconnecting")
+GK_ATOM(ondownloading, "ondownloading")
 GK_ATOM(onDOMActivate, "onDOMActivate")
 GK_ATOM(onDOMAttrModified, "onDOMAttrModified")
 GK_ATOM(onDOMCharacterDataModified, "onDOMCharacterDataModified")
 GK_ATOM(onDOMFocusIn, "onDOMFocusIn")
 GK_ATOM(onDOMFocusOut, "onDOMFocusOut")
 GK_ATOM(onDOMMouseScroll, "onDOMMouseScroll")
 GK_ATOM(onDOMNodeInserted, "onDOMNodeInserted")
 GK_ATOM(onDOMNodeInsertedIntoDocument, "onDOMNodeInsertedIntoDocument")
@@ -657,25 +679,30 @@ GK_ATOM(ondragdrop, "ondragdrop")
 GK_ATOM(ondragend, "ondragend")
 GK_ATOM(ondragenter, "ondragenter")
 GK_ATOM(ondragexit, "ondragexit")
 GK_ATOM(ondraggesture, "ondraggesture")
 GK_ATOM(ondragleave, "ondragleave")
 GK_ATOM(ondragover, "ondragover")
 GK_ATOM(ondragstart, "ondragstart")
 GK_ATOM(ondrop, "ondrop")
+GK_ATOM(onenabled, "onenabled")
 GK_ATOM(onerror, "onerror")
 GK_ATOM(onfocus, "onfocus")
 GK_ATOM(onget, "onget")
 GK_ATOM(onhashchange, "onhashchange")
+GK_ATOM(onheld, "onheld")
+GK_ATOM(onholding, "onholding")
+GK_ATOM(onincoming, "onincoming")
 GK_ATOM(oninput, "oninput")
 GK_ATOM(oninvalid, "oninvalid")
 GK_ATOM(onkeydown, "onkeydown")
 GK_ATOM(onkeypress, "onkeypress")
 GK_ATOM(onkeyup, "onkeyup")
+GK_ATOM(onlevelchange, "onlevelchange")
 GK_ATOM(onLoad, "onLoad")
 GK_ATOM(onload, "onload")
 GK_ATOM(onpopstate, "onpopstate")
 GK_ATOM(only, "only")               // this one is not an event
 GK_ATOM(onmessage, "onmessage")
 GK_ATOM(onmousedown, "onmousedown")
 GK_ATOM(onmouseenter, "onmouseenter")
 GK_ATOM(onmouseleave, "onmouseleave")
@@ -686,50 +713,66 @@ GK_ATOM(onMozMouseHittest, "onMozMouseHi
 GK_ATOM(onmouseup, "onmouseup")
 GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
 GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
 GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
 GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange")
 GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
 GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
 GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
+GK_ATOM(onnoupdate, "onnoupdate")
+GK_ATOM(onobsolete, "onobsolete")
 GK_ATOM(ononline, "ononline")
 GK_ATOM(onoffline, "onoffline")
 GK_ATOM(onopen, "onopen")
 GK_ATOM(onoverflow, "onoverflow")
 GK_ATOM(onoverflowchanged, "onoverflowchanged")
 GK_ATOM(onpagehide, "onpagehide")
 GK_ATOM(onpageshow, "onpageshow")
 GK_ATOM(onpaint, "onpaint")
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpopuphidden, "onpopuphidden")
 GK_ATOM(onpopuphiding, "onpopuphiding")
 GK_ATOM(onpopupshowing, "onpopupshowing")
 GK_ATOM(onpopupshown, "onpopupshown")
+GK_ATOM(onpropertychanged, "onpropertychanged")
 GK_ATOM(onreadystatechange, "onreadystatechange")
+GK_ATOM(onreceived, "onreceived")
+GK_ATOM(onrequestconfirmation, "onrequestconfirmation")
+GK_ATOM(onrequestpasskey, "onrequestpasskey")
+GK_ATOM(onrequestpincode, "onrequestpincode")
 GK_ATOM(onRequest, "onRequest")
 GK_ATOM(onreset, "onreset")
+GK_ATOM(onresuming, "onresuming")
 GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
 GK_ATOM(onresize, "onresize")
 GK_ATOM(onscroll, "onscroll")
 GK_ATOM(onselect, "onselect")
+GK_ATOM(onsent, "onsent")
 GK_ATOM(onset, "onset")
 GK_ATOM(onshow, "onshow")
+GK_ATOM(onstatechange, "onstatechange")
+GK_ATOM(onstatuschanged, "onstatuschanged")
 GK_ATOM(onsubmit, "onsubmit")
+GK_ATOM(onsuccess, "onsuccess")
 GK_ATOM(ontext, "ontext")
 GK_ATOM(ontouchstart, "ontouchstart")
 GK_ATOM(ontouchend, "ontouchend")
 GK_ATOM(ontouchmove, "ontouchmove")
 GK_ATOM(ontouchenter, "ontouchenter")
 GK_ATOM(ontouchleave, "ontouchleave")
 GK_ATOM(ontouchcancel, "ontouchcancel")
 GK_ATOM(ontransitionend, "ontransitionend")
 GK_ATOM(onunderflow, "onunderflow")
 GK_ATOM(onunload, "onunload")
+GK_ATOM(onupdateready, "onupdateready")
 GK_ATOM(onupgradeneeded, "onupgradeneeded")
+GK_ATOM(onussdreceived, "onussdreceived")
+GK_ATOM(onversionchange, "onversionchange")
+GK_ATOM(onvoicechange, "onvoicechange")
 GK_ATOM(onwheel, "onwheel")
 GK_ATOM(open, "open")
 GK_ATOM(optgroup, "optgroup")
 GK_ATOM(optimum, "optimum")
 GK_ATOM(option, "option")
 GK_ATOM(_or, "or")
 GK_ATOM(order, "order")
 GK_ATOM(ordinal, "ordinal")
@@ -1662,16 +1705,17 @@ GK_ATOM(onMozEdgeUIGesture, "onMozEdgeUI
 GK_ATOM(onMozTouchDown, "onMozTouchDown")
 GK_ATOM(onMozTouchMove, "onMozTouchMove")
 GK_ATOM(onMozTouchUp, "onMozTouchUp")
 
 // orientation support
 GK_ATOM(ondevicemotion, "ondevicemotion")
 GK_ATOM(ondeviceorientation, "ondeviceorientation")
 GK_ATOM(ondeviceproximity, "ondeviceproximity")
+GK_ATOM(onmozorientationchange, "onmozorientationchange")
 GK_ATOM(onuserproximity, "onuserproximity")
 
 // light sensor support
 GK_ATOM(ondevicelight, "ondevicelight")
 
 //---------------------------------------------------------------------------
 // Special atoms
 //---------------------------------------------------------------------------
@@ -1766,31 +1810,33 @@ GK_ATOM(svgRadialGradientFrame, "SVGRadi
 GK_ATOM(svgStopFrame, "SVGStopFrame")
 GK_ATOM(svgSwitchFrame, "SVGSwitchFrame")
 GK_ATOM(svgTextFrame, "SVGTextFrame")
 GK_ATOM(svgTextFrame2, "SVGTextFrame2")
 GK_ATOM(svgTextPathFrame, "SVGTextPathFrame")
 GK_ATOM(svgTSpanFrame, "SVGTSpanFrame")
 GK_ATOM(svgUseFrame, "SVGUseFrame")
 GK_ATOM(HTMLVideoFrame, "VideoFrame")
+GK_ATOM(onloadend, "onloadend")
 GK_ATOM(onloadstart, "onloadstart")
 GK_ATOM(onprogress, "onprogress")
 GK_ATOM(onsuspend, "onsuspend")
 GK_ATOM(onemptied, "onemptied")
 GK_ATOM(onstalled, "onstalled")
 GK_ATOM(onplay, "onplay")
 GK_ATOM(onpause, "onpause")
 GK_ATOM(onloadedmetadata, "onloadedmetadata")
 GK_ATOM(onloadeddata, "onloadeddata")
 GK_ATOM(onwaiting, "onwaiting")
 GK_ATOM(onplaying, "onplaying")
 GK_ATOM(oncanplay, "oncanplay")
 GK_ATOM(oncanplaythrough, "oncanplaythrough")
 GK_ATOM(onseeking, "onseeking")
 GK_ATOM(onseeked, "onseeked")
+GK_ATOM(ontimeout, "ontimeout")
 GK_ATOM(ontimeupdate, "ontimeupdate")
 GK_ATOM(onended, "onended")
 GK_ATOM(onratechange, "onratechange")
 GK_ATOM(ondurationchange, "ondurationchange")
 GK_ATOM(onvolumechange, "onvolumechange")
 GK_ATOM(onMozAudioAvailable, "onMozAudioAvailable")
 GK_ATOM(loadstart, "loadstart")
 GK_ATOM(suspend, "suspend")
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -1979,17 +1979,18 @@ nsINode::SizeOfExcludingThis(nsMallocSiz
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     JSObject *obj = GetWrapper();                                            \
     if (!obj) {                                                              \
       /* Just silently do nothing */                                         \
       return NS_OK;                                                          \
     }                                                                        \
-    return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v);    \
+    return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v,     \
+                                       true);                                \
 }
 #define TOUCH_EVENT EVENT
 #define DOCUMENT_ONLY_EVENT EVENT
 #include "nsEventNameList.h"
 #undef DOCUMENT_ONLY_EVENT
 #undef TOUCH_EVENT
 #undef EVENT
 
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -498,20 +498,16 @@ nsWebSocket::~nsWebSocket()
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsWebSocket)
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsWebSocket)
   bool isBlack = tmp->IsBlack();
   if (isBlack|| tmp->mKeepingAlive) {
     if (tmp->mListenerManager) {
       tmp->mListenerManager->UnmarkGrayJSListeners();
-      NS_UNMARK_LISTENER_WRAPPER(Open)
-      NS_UNMARK_LISTENER_WRAPPER(Error)
-      NS_UNMARK_LISTENER_WRAPPER(Message)
-      NS_UNMARK_LISTENER_WRAPPER(Close)
     }
     if (!isBlack && tmp->PreservingWrapper()) {
       xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor());
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
@@ -524,32 +520,24 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_B
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsWebSocket,
                                                nsDOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsWebSocket,
                                                   nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnOpenListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnMessageListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCloseListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mURI)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsWebSocket,
                                                 nsDOMEventTargetHelper)
   tmp->Disconnect();
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnOpenListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnMessageListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCloseListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mURI)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(WebSocket, nsWebSocket)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsWebSocket)
@@ -561,24 +549,25 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebSocket)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsWebSocket, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsWebSocket, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsWebSocket, open)
+NS_IMPL_EVENT_HANDLER(nsWebSocket, error)
+NS_IMPL_EVENT_HANDLER(nsWebSocket, message)
+NS_IMPL_EVENT_HANDLER(nsWebSocket, close)
+
 void
 nsWebSocket::DisconnectFromOwner()
 {
   nsDOMEventTargetHelper::DisconnectFromOwner();
-  NS_DISCONNECT_EVENT_HANDLER(Open)
-  NS_DISCONNECT_EVENT_HANDLER(Message)
-  NS_DISCONNECT_EVENT_HANDLER(Close)
-  NS_DISCONNECT_EVENT_HANDLER(Error)
   CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
   DontKeepAliveAnyMore();
 }
 
 //-----------------------------------------------------------------------------
 // nsWebSocket::nsIJSNativeInitializer methods:
 //-----------------------------------------------------------------------------
 
@@ -1219,35 +1208,16 @@ nsWebSocket::SetBinaryType(const nsAStri
     mBinaryType = WS_BINARY_TYPE_BLOB;
   } else  {
     return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
-#define NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(_eventlistenername, _eventlistener) \
-  NS_IMETHODIMP                                                                \
-  nsWebSocket::GetOn##_eventlistenername(nsIDOMEventListener * *aEventListener)\
-  {                                                                            \
-    return GetInnerEventListener(_eventlistener, aEventListener);              \
-  }                                                                            \
-                                                                               \
-  NS_IMETHODIMP                                                                \
-  nsWebSocket::SetOn##_eventlistenername(nsIDOMEventListener * aEventListener) \
-  {                                                                            \
-    return RemoveAddEventListener(NS_LITERAL_STRING(#_eventlistenername),      \
-                                  _eventlistener, aEventListener);             \
-  }
-
-NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(open, mOnOpenListener)
-NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(error, mOnErrorListener)
-NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(message, mOnMessageListener)
-NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(close, mOnCloseListener)
-
 NS_IMETHODIMP
 nsWebSocket::Send(nsIVariant *aData, JSContext *aCx)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   if (mReadyState == nsIWebSocket::CONNECTING) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
--- a/content/base/src/nsWebSocket.h
+++ b/content/base/src/nsWebSocket.h
@@ -131,21 +131,16 @@ protected:
   // ATTENTION, when calling this method the object can be released
   // (and possibly collected).
   void DontKeepAliveAnyMore();
 
   nsresult UpdateURI();
 
   nsCOMPtr<nsIWebSocketChannel> mChannel;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnOpenListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnMessageListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnCloseListener;
-
   // related to the WebSocket constructor steps
   nsString mOriginalURL;
   nsString mEffectiveURL;   // after redirects
   bool mSecure; // if true it is using SSL and the wss scheme,
                         // otherwise it is using the ws scheme with no SSL
 
   bool mKeepingAlive;
   bool mCheckMustKeepAlive;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -282,145 +282,41 @@ nsMultipartProxyListener::OnDataAvailabl
 }
 
 /////////////////////////////////////////////
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXHREventTarget,
                                                   nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadStartListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadendListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnTimeoutListener)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXHREventTarget,
                                                 nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadStartListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadendListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnTimeoutListener)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXHREventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadstart)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, progress)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, abort)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, error)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, load)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, timeout)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadend)
+
 void
 nsXHREventTarget::DisconnectFromOwner()
 {
   nsDOMEventTargetHelper::DisconnectFromOwner();
-  NS_DISCONNECT_EVENT_HANDLER(Load)
-  NS_DISCONNECT_EVENT_HANDLER(Error)
-  NS_DISCONNECT_EVENT_HANDLER(Abort)
-  NS_DISCONNECT_EVENT_HANDLER(Load)
-  NS_DISCONNECT_EVENT_HANDLER(Progress)
-  NS_DISCONNECT_EVENT_HANDLER(Loadend)
-  NS_DISCONNECT_EVENT_HANDLER(Timeout)
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnload(nsIDOMEventListener** aOnLoad)
-{
-  return GetInnerEventListener(mOnLoadListener, aOnLoad);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnload(nsIDOMEventListener* aOnLoad)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(LOAD_STR),
-                                mOnLoadListener, aOnLoad);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnerror(nsIDOMEventListener** aOnerror)
-{
-  return GetInnerEventListener(mOnErrorListener, aOnerror);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnerror(nsIDOMEventListener* aOnerror)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_STR),
-                                mOnErrorListener, aOnerror);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnabort(nsIDOMEventListener** aOnabort)
-{
-  return GetInnerEventListener(mOnAbortListener, aOnabort);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnabort(nsIDOMEventListener* aOnabort)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_STR),
-                                mOnAbortListener, aOnabort);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnloadstart(nsIDOMEventListener** aOnloadstart)
-{
-  return GetInnerEventListener(mOnLoadStartListener, aOnloadstart);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnloadstart(nsIDOMEventListener* aOnloadstart)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(LOADSTART_STR),
-                                mOnLoadStartListener, aOnloadstart);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnprogress(nsIDOMEventListener** aOnprogress)
-{
-  return GetInnerEventListener(mOnProgressListener, aOnprogress);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnprogress(nsIDOMEventListener* aOnprogress)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(PROGRESS_STR),
-                                mOnProgressListener, aOnprogress);
-}
-
-/* attribute nsIDOMEventListener ontimeout; */
-NS_IMETHODIMP
-nsXHREventTarget::GetOntimeout(nsIDOMEventListener * *aOntimeout)
-{
-  return GetInnerEventListener(mOnTimeoutListener, aOntimeout);
-}
-NS_IMETHODIMP
-nsXHREventTarget::SetOntimeout(nsIDOMEventListener *aOntimeout)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(TIMEOUT_STR),
-                                mOnTimeoutListener, aOntimeout);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::GetOnloadend(nsIDOMEventListener** aOnLoadend)
-{
-  return GetInnerEventListener(mOnLoadendListener, aOnLoadend);
-}
-
-NS_IMETHODIMP
-nsXHREventTarget::SetOnloadend(nsIDOMEventListener* aOnLoadend)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(LOADEND_STR),
-                                mOnLoadendListener, aOnLoadend);
 }
 
 /////////////////////////////////////////////
 
 DOMCI_DATA(XMLHttpRequestUpload, nsXMLHttpRequestUpload)
 
 NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
@@ -615,23 +511,16 @@ nsXMLHttpRequest::SetRequestObserver(nsI
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequest)
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXMLHttpRequest)
   bool isBlack = tmp->IsBlack();
   if (isBlack || tmp->mWaitingForOnStopRequest) {
     if (tmp->mListenerManager) {
       tmp->mListenerManager->UnmarkGrayJSListeners();
-      NS_UNMARK_LISTENER_WRAPPER(Load)
-      NS_UNMARK_LISTENER_WRAPPER(Error)
-      NS_UNMARK_LISTENER_WRAPPER(Abort)
-      NS_UNMARK_LISTENER_WRAPPER(LoadStart)
-      NS_UNMARK_LISTENER_WRAPPER(Progress)
-      NS_UNMARK_LISTENER_WRAPPER(Loadend)
-      NS_UNMARK_LISTENER_WRAPPER(Readystatechange)
     }
     if (!isBlack && tmp->PreservingWrapper()) {
       xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor());
     }
     return true;
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
 
@@ -646,18 +535,16 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
                                                   nsXHREventTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReadRequest)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mResponseXML)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCORSPreflightChannel)
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnReadystatechangeListener)
-
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mXMLParserStreamListener)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mUpload,
                                                        nsIXMLHttpRequestUpload)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -667,18 +554,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   tmp->mResultArrayBuffer = nullptr;
   tmp->mResultJSON = JSVAL_VOID;
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResponseXML)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCORSPreflightChannel)
 
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
-
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXMLParserStreamListener)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
@@ -703,41 +588,25 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLHttpRequest)
 NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
 
 NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequest, nsXHREventTarget)
 NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequest, nsXHREventTarget)
 
+NS_IMPL_EVENT_HANDLER(nsXMLHttpRequest, readystatechange)
+
 void
 nsXMLHttpRequest::DisconnectFromOwner()
 {
   nsXHREventTarget::DisconnectFromOwner();
-  NS_DISCONNECT_EVENT_HANDLER(Readystatechange)
   Abort();
 }
 
-NS_IMETHODIMP
-nsXMLHttpRequest::GetOnreadystatechange(nsIDOMEventListener * *aOnreadystatechange)
-{
-  return
-    nsXHREventTarget::GetInnerEventListener(mOnReadystatechangeListener,
-                                            aOnreadystatechange);
-}
-
-NS_IMETHODIMP
-nsXMLHttpRequest::SetOnreadystatechange(nsIDOMEventListener * aOnreadystatechange)
-{
-  return
-    nsXHREventTarget::RemoveAddEventListener(NS_LITERAL_STRING(READYSTATE_STR),
-                                             mOnReadystatechangeListener,
-                                             aOnreadystatechange);
-}
-
 /* readonly attribute nsIChannel channel; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_IF_ADDREF(*aChannel = mChannel);
 
   return NS_OK;
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -41,88 +41,52 @@
 #include "mozilla/dom/XMLHttpRequestBinding.h"
 #include "mozilla/dom/XMLHttpRequestUploadBinding.h"
 
 class nsILoadGroup;
 class AsyncVerifyRedirectCallbackForwarder;
 class nsIUnicodeDecoder;
 class nsIDOMFormData;
 
-#define IMPL_EVENT_HANDLER(_lowercase, _capitalized)                    \
-  JSObject* GetOn##_lowercase(JSContext* /* unused */ )                 \
+#define IMPL_EVENT_HANDLER(_lowercase)                                  \
+  inline JSObject* GetOn##_lowercase(JSContext* aCx)                    \
   {                                                                     \
-    return GetListenerAsJSObject(mOn##_capitalized##Listener);          \
+    JS::Value val;                                                      \
+    nsresult rv = GetOn##_lowercase(aCx, &val);                         \
+    return NS_SUCCEEDED(rv) ? JSVAL_TO_OBJECT(val) : nullptr;           \
   }                                                                     \
-  void SetOn##_lowercase(JSContext* aCx, JSObject* aCallback, ErrorResult& aRv) \
+  void SetOn##_lowercase(JSContext* aCx, JSObject* aCallback,           \
+                         ErrorResult& aRv)                              \
   {                                                                     \
-    aRv = SetJSObjectListener(aCx, NS_LITERAL_STRING(#_lowercase),      \
-                              mOn##_capitalized##Listener,              \
-                              aCallback);                               \
+    aRv = SetOn##_lowercase(aCx, OBJECT_TO_JSVAL(aCallback));           \
   }
 
 class nsXHREventTarget : public nsDOMEventTargetHelper,
                          public nsIXMLHttpRequestEventTarget
 {
 public:
   typedef mozilla::dom::XMLHttpRequestResponseType
           XMLHttpRequestResponseType;
 
   virtual ~nsXHREventTarget() {}
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXHREventTarget,
                                            nsDOMEventTargetHelper)
   NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
-  IMPL_EVENT_HANDLER(loadstart, LoadStart)
-  IMPL_EVENT_HANDLER(progress, Progress)
-  IMPL_EVENT_HANDLER(abort, Abort)
-  IMPL_EVENT_HANDLER(error, Error)
-  IMPL_EVENT_HANDLER(load, Load)
-  IMPL_EVENT_HANDLER(timeout, Timeout)
-  IMPL_EVENT_HANDLER(loadend, Loadend)
+  IMPL_EVENT_HANDLER(loadstart)
+  IMPL_EVENT_HANDLER(progress)
+  IMPL_EVENT_HANDLER(abort)
+  IMPL_EVENT_HANDLER(error)
+  IMPL_EVENT_HANDLER(load)
+  IMPL_EVENT_HANDLER(timeout)
+  IMPL_EVENT_HANDLER(loadend)
   
   virtual void DisconnectFromOwner();
-protected:
-  static inline JSObject* GetListenerAsJSObject(nsDOMEventListenerWrapper* aWrapper)
-  {
-    if (!aWrapper) {
-      return nullptr;
-    }
-
-    nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
-        do_QueryInterface(aWrapper->GetInner());
-    JSObject* obj;
-    return holder && NS_SUCCEEDED(holder->GetJSObject(&obj)) ? obj : nullptr;
-  }
-  inline nsresult SetJSObjectListener(JSContext* aCx,
-                                      const nsAString& aType,
-                                      nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
-                                      JSObject* aCallback)
-  {
-    nsCOMPtr<nsIDOMEventListener> listener;
-    if (aCallback) {
-      nsresult rv =
-        nsContentUtils::XPConnect()->WrapJS(aCx,
-                                            aCallback,
-                                            NS_GET_IID(nsIDOMEventListener),
-                                            getter_AddRefs(listener));
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    return RemoveAddEventListener(aType, aWrapper, listener);
-  }
-
-  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadStartListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadendListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnTimeoutListener;
 };
 
 class nsXMLHttpRequestUpload : public nsXHREventTarget,
                                public nsIXMLHttpRequestUpload
 {
 public:
   nsXMLHttpRequestUpload(nsDOMEventTargetHelper* aOwner)
   {
@@ -242,17 +206,17 @@ public:
 
   NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
 
 #ifdef DEBUG
   void StaticAssertions();
 #endif
 
   // event handler
-  IMPL_EVENT_HANDLER(readystatechange, Readystatechange)
+  IMPL_EVENT_HANDLER(readystatechange)
 
   // states
   uint16_t GetReadyState();
 
   // request
   void Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync,
             const mozilla::dom::Optional<nsAString>& aUser,
             const mozilla::dom::Optional<nsAString>& aPassword,
@@ -510,23 +474,16 @@ protected:
   nsresult CreatePartialBlob(void);
   bool CreateDOMFile(nsIRequest *request);
   // Change the state of the object with this. The broadcast argument
   // determines if the onreadystatechange listener should be called.
   nsresult ChangeState(uint32_t aState, bool aBroadcast = true);
   already_AddRefed<nsILoadGroup> GetLoadGroup() const;
   nsIURI *GetBaseURI();
 
-  nsresult RemoveAddEventListener(const nsAString& aType,
-                                  nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
-                                  nsIDOMEventListener* aNew);
-
-  nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
-                                 nsIDOMEventListener** aListener);
-
   already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
 
   bool IsSystemXHR();
 
   void ChangeStateToDone();
 
   /**
    * Check if aChannel is ok for a cross-site request by making sure no
@@ -549,18 +506,16 @@ protected:
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<nsIChannel> mChannel;
   // mReadRequest is different from mChannel for multipart requests
   nsCOMPtr<nsIRequest> mReadRequest;
   nsCOMPtr<nsIDocument> mResponseXML;
   nsCOMPtr<nsIChannel> mCORSPreflightChannel;
   nsTArray<nsCString> mCORSUnsafeHeaders;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnReadystatechangeListener;
-
   nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
 
   // used to implement getAllResponseHeaders()
   class nsHeaderVisitor : public nsIHttpHeaderVisitor {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPHEADERVISITOR
     nsHeaderVisitor() { }
--- a/content/base/test/test_XHR.html
+++ b/content/base/test/test_XHR.html
@@ -230,18 +230,18 @@ function checkXHRStatus() {
     is(xhr.status, 200, "should be 200 when we have data");
     is(xhr.statusText, "OK", "should be OK when we have data");
   }
 }
 checkXHRStatus();
 xhr.open("GET", 'file_XHR_binary1.bin'); 
 checkXHRStatus();
 xhr.responseType = 'arraybuffer';
+xhr.send(null);
 xhr.onreadystatechange = continueTest;
-xhr.send(null);
 while (xhr.readyState != 4) {
   checkXHRStatus();
   yield;
 }
 checkXHRStatus();
 
 // test response (responseType='blob')
 var responseTypes = ['blob', 'moz-blob'];
@@ -266,19 +266,19 @@ for (var i = 0; i < responseTypes.length
   var fr = new FileReader();
   fr.onload = continueTest;
   fr.readAsBinaryString(b);
   yield;
   ok(fr.result, "hello pass\n", "wrong values");
 
   // with a binary file
   xhr = new XMLHttpRequest();
-  xhr.onreadystatechange = continueTest;
   xhr.open("GET", 'file_XHR_binary1.bin', true);
   xhr.send(null);
+  xhr.onreadystatechange = continueTest;
   while(xhr.readyState != 2)
     yield;
 
   is(xhr.status, 200, "wrong status");
   xhr.responseType = t;
 
   while(xhr.readyState != 4)
     yield;
@@ -295,20 +295,20 @@ for (var i = 0; i < responseTypes.length
   b = null;
   SpecialPowers.gc();
   fr.onload = continueTest;
   yield;
   is(fr.result, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb", "wrong values");
 
   // with a larger binary file
   xhr = new XMLHttpRequest();
-  xhr.onreadystatechange = continueTest;
   xhr.open("GET", 'file_XHR_binary2.bin', true);
   xhr.responseType = t;
   xhr.send(null);
+  xhr.onreadystatechange = continueTest;
 
   while (xhr.readyState != 4)
     yield;
 
   xhr.onreadystatechange = null;
 
   var b = xhr.response;
   ok(b != null, "should have a non-null blob");
@@ -327,33 +327,33 @@ for (var i = 0; i < responseTypes.length
     if (u8[i] !== (i & 255)) {
       break;
     }
   }
   is(i, 65536, "wrong value at offset " + i);
 }
 
 var client = new XMLHttpRequest();
+client.open("GET", "file_XHR_pass1.xml", true);
+client.send();
 client.onreadystatechange = function() {
   if(client.readyState == 4) {
     try {
       is(client.responseXML, null, "responseXML should be null.");
       is(client.responseText, "", "responseText should be empty string.");
       is(client.response, "", "response should be empty string.");
       is(client.status, 0, "status should be 0.");
       is(client.statusText, "", "statusText should be empty string.");
       is(client.getAllResponseHeaders(), "",
          "getAllResponseHeaders() should return empty string.");
     } catch(ex) {
       ok(false, "Shouldn't throw! [" + ex + "]");
     }
   }
 }
-client.open("GET", "file_XHR_pass1.xml", true);
-client.send();
 client.abort();
 
 SimpleTest.finish();
 yield;
 
 } /* runTests */
 </script>
 </pre>
--- a/content/base/test/test_xhr_abort_after_load.html
+++ b/content/base/test/test_xhr_abort_after_load.html
@@ -20,16 +20,17 @@ function runTest() {
     startTest1,
     startTest2,
     startTest3,
   ];
 
   function nextTest() {
     if (testFunctions.length == 0) {
       SimpleTest.finish();
+      return;
     }
     (testFunctions.shift())();
   }
 
   nextTest();
 
   var xhr;
   function startTest1() {
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -8,38 +8,16 @@
 #include "nsEventDispatcher.h"
 #include "nsGUIEvent.h"
 #include "nsIDocument.h"
 #include "nsIJSContextStack.h"
 #include "nsDOMJSUtils.h"
 #include "prprf.h"
 #include "nsGlobalWindow.h"
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventListenerWrapper)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventListenerWrapper)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
-NS_INTERFACE_MAP_END_AGGREGATED(mListener)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEventListenerWrapper)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEventListenerWrapper)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEventListenerWrapper)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListener)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEventListenerWrapper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListener)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMETHODIMP
-nsDOMEventListenerWrapper::HandleEvent(nsIDOMEvent* aEvent)
-{
-  return mListener->HandleEvent(aEvent);
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventTargetHelper)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDOMEventTargetHelper)
   if (NS_UNLIKELY(cb.WantDebugInfo())) {
@@ -205,46 +183,44 @@ nsDOMEventTargetHelper::DispatchEvent(ns
   nsresult rv =
     nsEventDispatcher::DispatchDOMEvent(this, nullptr, aEvent, nullptr, &status);
 
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return rv;
 }
 
 nsresult
-nsDOMEventTargetHelper::RemoveAddEventListener(const nsAString& aType,
-                                               nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
-                                               nsIDOMEventListener* aNew)
+nsDOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
+                                        JSContext* aCx,
+                                        const JS::Value& aValue)
 {
-  if (aCurrent) {
-    RemoveEventListener(aType, aCurrent, false);
-    aCurrent = nullptr;
+  nsEventListenerManager* elm = GetListenerManager(true);
+
+  JSObject* obj = GetWrapper();
+  if (!obj) {
+    return NS_OK;
   }
-  if (aNew) {
-    aCurrent = new nsDOMEventListenerWrapper(aNew);
-    NS_ENSURE_TRUE(aCurrent, NS_ERROR_OUT_OF_MEMORY);
-    nsIDOMEventTarget::AddEventListener(aType, aCurrent, false);
-  }
-  return NS_OK;
+  
+  return elm->SetEventHandlerToJsval(aType, aCx, obj, aValue,
+                                     HasOrHasHadOwner());
 }
 
-nsresult
-nsDOMEventTargetHelper::GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
-                                              nsIDOMEventListener** aListener)
+void
+nsDOMEventTargetHelper::GetEventHandler(nsIAtom* aType,
+                                        JSContext* aCx,
+                                        JS::Value* aValue)
 {
-  NS_ENSURE_ARG_POINTER(aListener);
-  if (aWrapper) {
-    NS_IF_ADDREF(*aListener = aWrapper->GetInner());
-  } else {
-    *aListener = nullptr;
+  *aValue = JSVAL_NULL;
+
+  nsEventListenerManager* elm = GetListenerManager(false);
+  if (elm) {
+    elm->GetEventHandler(aType, aValue);
   }
-  return NS_OK;
 }
 
-
 nsresult
 nsDOMEventTargetHelper::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = nullptr;
   return NS_OK;
 }
 
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -2,45 +2,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDOMEventTargetHelper_h_
 #define nsDOMEventTargetHelper_h_
 
 #include "nsCOMPtr.h"
-#include "nsAutoPtr.h"
+#include "nsGkAtoms.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMEventListener.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsPIDOMWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsEventListenerManager.h"
 #include "nsIScriptContext.h"
 #include "nsWrapperCache.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/Attributes.h"
 
-class nsDOMEventListenerWrapper MOZ_FINAL : public nsIDOMEventListener
-{
-public:
-  nsDOMEventListenerWrapper(nsIDOMEventListener* aListener)
-  : mListener(aListener) {}
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMEventListenerWrapper)
-
-  NS_DECL_NSIDOMEVENTLISTENER
-
-  nsIDOMEventListener* GetInner() { return mListener; }
-  void Disconnect() { mListener = nullptr; }
-protected:
-  nsCOMPtr<nsIDOMEventListener> mListener;
-};
-
 class nsDOMEventTargetHelper : public nsIDOMEventTarget,
                                public nsWrapperCache
 {
 public:
   nsDOMEventTargetHelper() : mOwner(nullptr), mHasOrHasHadOwner(false) {}
   virtual ~nsDOMEventTargetHelper();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMEventTargetHelper)
@@ -98,22 +81,23 @@ public:
   }
 
   void Init(JSContext* aCx = nullptr);
 
   bool HasListenersFor(const nsAString& aType)
   {
     return mListenerManager && mListenerManager->HasListenersFor(aType);
   }
-  nsresult RemoveAddEventListener(const nsAString& aType,
-                                  nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
-                                  nsIDOMEventListener* aNew);
 
-  nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
-                                 nsIDOMEventListener** aListener);
+  nsresult SetEventHandler(nsIAtom* aType,
+                           JSContext* aCx,
+                           const JS::Value& aValue);
+  void GetEventHandler(nsIAtom* aType,
+                       JSContext* aCx,
+                       JS::Value* aValue);
 
   nsresult CheckInnerWindowCorrectness()
   {
     NS_ENSURE_STATE(!mHasOrHasHadOwner || mOwner);
     if (mOwner) {
       NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
       nsPIDOMWindow* outer = mOwner->GetOuterWindow();
       if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
@@ -131,74 +115,39 @@ public:
 protected:
   nsRefPtr<nsEventListenerManager> mListenerManager;
 private:
   // These may be null (native callers or xpcshell).
   nsPIDOMWindow*             mOwner; // Inner window.
   bool                       mHasOrHasHadOwner;
 };
 
-#define NS_DECL_EVENT_HANDLER(_event)                                         \
-  protected:                                                                  \
-    nsRefPtr<nsDOMEventListenerWrapper> mOn##_event##Listener;                \
-  public:
-
-#define NS_DECL_AND_IMPL_EVENT_HANDLER(_event)                                \
-  protected:                                                                  \
-    nsRefPtr<nsDOMEventListenerWrapper> mOn##_event##Listener;                \
-  public:                                                                     \
-    NS_IMETHOD GetOn##_event(nsIDOMEventListener** a##_event)                 \
+#define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
     {                                                                         \
-      return GetInnerEventListener(mOn##_event##Listener, a##_event);         \
+      GetEventHandler(nsGkAtoms::on##_event, aCx, aValue);                    \
+      return NS_OK;                                                           \
     }                                                                         \
-    NS_IMETHOD SetOn##_event(nsIDOMEventListener* a##_event)                  \
+    NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
+                                        const JS::Value& aValue)              \
     {                                                                         \
-      return RemoveAddEventListener(NS_LITERAL_STRING(#_event),               \
-                                    mOn##_event##Listener, a##_event);        \
+      return SetEventHandler(nsGkAtoms::on##_event, aCx, aValue);             \
     }
 
-#define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
-  NS_IMETHODIMP                                                               \
-  _class::GetOn##_event(nsIDOMEventListener** a##_event)                      \
-  {                                                                           \
-    return GetInnerEventListener(mOn##_event##Listener, a##_event);           \
-  }                                                                           \
-  NS_IMETHODIMP                                                               \
-  _class::SetOn##_event(nsIDOMEventListener* a##_event)                       \
-  {                                                                           \
-    return RemoveAddEventListener(NS_LITERAL_STRING(#_event),                 \
-                                  mOn##_event##Listener, a##_event);          \
-  }
-
 #define NS_IMPL_FORWARD_EVENT_HANDLER(_class, _event, _baseclass)             \
-    NS_IMETHODIMP                                                             \
-    _class::GetOn##_event(nsIDOMEventListener** a##_event)                    \
+    NS_IMETHODIMP _class::GetOn##_event(JSContext* aCx, JS::Value* aValue)    \
     {                                                                         \
-      return _baseclass::GetOn##_event(a##_event);                           \
+      return _baseclass::GetOn##_event(aCx, aValue);                          \
     }                                                                         \
-    NS_IMETHODIMP                                                             \
-    _class::SetOn##_event(nsIDOMEventListener* a##_event)                     \
+    NS_IMETHODIMP _class::SetOn##_event(JSContext* aCx,                       \
+                                        const JS::Value& aValue)              \
     {                                                                         \
-      return _baseclass::SetOn##_event(a##_event);                            \
+      return _baseclass::SetOn##_event(aCx, aValue);                          \
     }
 
-#define NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(_event)                    \
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOn##_event##Listener)
-
-#define NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(_event)                      \
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOn##_event##Listener)
-
-#define NS_DISCONNECT_EVENT_HANDLER(_event)                                   \
-  if (mOn##_event##Listener) { mOn##_event##Listener->Disconnect(); }
-
-#define NS_UNMARK_LISTENER_WRAPPER(_event)                                    \
-  if (tmp->mOn##_event##Listener) {                                           \
-    xpc_TryUnmarkWrappedGrayObject(tmp->mOn##_event##Listener->GetInner());   \
-  }
-
 /* Use this macro to declare functions that forward the behavior of this
  * interface to another object.
  * This macro doesn't forward PreHandleEvent because sometimes subclasses
  * want to override it.
  */
 #define NS_FORWARD_NSIDOMEVENTTARGET_NOPREHANDLEEVENT(_to) \
   NS_IMETHOD AddEventListener(const nsAString & type, nsIDOMEventListener *listener, bool useCapture, bool wantsUntrusted, uint8_t _argc) { \
     return _to AddEventListener(type, listener, useCapture, wantsUntrusted, _argc); \
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -473,40 +473,77 @@ nsEventListenerManager::FindEventHandler
       return ls;
     }
   }
   return nullptr;
 }
 
 nsresult
 nsEventListenerManager::SetEventHandlerInternal(nsIScriptContext *aContext,
+                                                JSContext* aCx,
                                                 JSObject* aScopeObject,
                                                 nsIAtom* aName,
                                                 JSObject *aHandler,
                                                 bool aPermitUntrustedEvents,
                                                 nsListenerStruct **aListenerStruct)
 {
+  NS_ASSERTION(aContext || aCx, "Must have one or the other!");
+
   nsresult rv = NS_OK;
   uint32_t eventType = nsContentUtils::GetEventId(aName);
   nsListenerStruct* ls = FindEventHandler(eventType, aName);
 
   if (!ls) {
     // If we didn't find a script listener or no listeners existed
     // create and add a new one.
-    nsCOMPtr<nsIJSEventListener> scriptListener;
-    rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
-                               aHandler, getter_AddRefs(scriptListener));
+    const uint32_t flags = NS_EVENT_FLAG_BUBBLE |
+                           (aContext ? NS_PRIV_EVENT_FLAG_SCRIPT : 0);
+    nsCOMPtr<nsIDOMEventListener> listener;
+
+    if (aContext) {
+      nsCOMPtr<nsIJSEventListener> scriptListener;
+      rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
+                                 aHandler, getter_AddRefs(scriptListener));
+      listener = scriptListener.forget();
+    } else {
+      // If we don't have a script context, we're setting an event handler from
+      // a component or other odd scope.  Ask XPConnect if it can make us an
+      // nsIDOMEventListener.
+      rv = nsContentUtils::XPConnect()->WrapJS(aCx,
+                                               aHandler,
+                                               NS_GET_IID(nsIDOMEventListener),
+                                               getter_AddRefs(listener));
+    }
+
     if (NS_SUCCEEDED(rv)) {
-      AddEventListener(scriptListener, eventType, aName,
-                       NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT, true);
+      AddEventListener(listener, eventType, aName, flags, true);
 
       ls = FindEventHandler(eventType, aName);
     }
   } else {
-    ls->GetJSListener()->SetHandler(aHandler);
+    // Don't mix 'real' JS event handlers and 'fake' JS event handlers.
+    nsIJSEventListener* scriptListener = ls->GetJSListener();
+
+    if ((!aContext && scriptListener) ||
+        (aContext && !scriptListener)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    if (scriptListener) {
+      scriptListener->SetHandler(aHandler);
+    } else {
+      nsCOMPtr<nsIDOMEventListener> listener;
+      rv = nsContentUtils::XPConnect()->WrapJS(aCx,
+                                               aHandler,
+                                               NS_GET_IID(nsIDOMEventListener),
+                                               getter_AddRefs(listener));
+      if (NS_SUCCEEDED(rv)) {
+        ls->mListener = listener.forget();
+      }
+    }
   }
 
   if (NS_SUCCEEDED(rv) && ls) {
     // Set flag to indicate possible need for compilation later
     ls->mHandlerIsString = !aHandler;
     if (aPermitUntrustedEvents) {
       ls->mFlags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
     }
@@ -625,17 +662,17 @@ nsEventListenerManager::SetEventHandler(
   }
 
   nsIScriptContext* context = global->GetScriptContext();
   NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
 
   JSObject* scope = global->GetGlobalJSObject();
 
   nsListenerStruct *ls;
-  rv = SetEventHandlerInternal(context, scope, aName, nullptr,
+  rv = SetEventHandlerInternal(context, nullptr, scope, aName, nullptr,
                                aPermitUntrustedEvents, &ls);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aDeferCompilation) {
     return CompileEventHandlerInternal(ls, true, &aBody);
   }
 
   return NS_OK;
@@ -1027,17 +1064,18 @@ nsEventListenerManager::HasUnloadListene
   }
   return false;
 }
 
 nsresult
 nsEventListenerManager::SetEventHandlerToJsval(nsIAtom *aEventName,
                                                JSContext *cx,
                                                JSObject* aScope,
-                                               const jsval & v)
+                                               const jsval& v,
+                                               bool aExpectScriptContext)
 {
   JSObject *handler;
   if (JSVAL_IS_PRIMITIVE(v) ||
       !JS_ObjectIsCallable(cx, handler = JSVAL_TO_OBJECT(v))) {
     RemoveEventHandler(aEventName);
     return NS_OK;
   }
 
@@ -1049,23 +1087,23 @@ nsEventListenerManager::SetEventHandlerT
   if (!JS_WrapValue(cx, &tempVal)) {
     return NS_ERROR_UNEXPECTED;
   }
   handler = &tempVal.toObject();
 
   // We might not have a script context, e.g. if we're setting a listener
   // on a dead Window.
   nsIScriptContext *context = nsJSUtils::GetStaticScriptContext(cx, aScope);
-  NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(context || !aExpectScriptContext, NS_ERROR_FAILURE);
 
   JSObject *scope = ::JS_GetGlobalForObject(cx, aScope);
   // Untrusted events are always permitted for non-chrome script
   // handlers.
   nsListenerStruct *ignored;
-  return SetEventHandlerInternal(context, scope, aEventName, handler,
+  return SetEventHandlerInternal(context, cx, scope, aEventName, handler,
                                  !nsContentUtils::IsCallerChrome(), &ignored);
 }
 
 void
 nsEventListenerManager::GetEventHandler(nsIAtom *aEventName, jsval *vp)
 {
   uint32_t eventType = nsContentUtils::GetEventId(aEventName);
   nsListenerStruct* ls = FindEventHandler(eventType, aEventName);
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -247,36 +247,39 @@ protected:
 
   /**
    * Set the "inline" event listener for aName to aHandler.  aHandler
    * may be null to indicate that we should lazily get and compile the
    * string for this listener.  The nsListenerStruct that results, if
    * any, is returned in aListenerStruct.
    */
   nsresult SetEventHandlerInternal(nsIScriptContext *aContext,
+                                   JSContext* aCx,
                                    JSObject* aScopeGlobal,
                                    nsIAtom* aName,
                                    JSObject *aHandler,
                                    bool aPermitUntrustedEvents,
                                    nsListenerStruct **aListenerStruct);
 
   bool IsDeviceType(uint32_t aType);
   void EnableDevice(uint32_t aType);
   void DisableDevice(uint32_t aType);
 
 public:
   /**
    * Set the "inline" event listener for aEventName to |v|.  This
    * might actually remove the event listener, depending on the value
    * of |v|.  Note that on entry to this function cx and aScope might
    * not be in the same compartment, though cx and v are guaranteed to
-   * be in the same compartment.
+   * be in the same compartment.  If aExpectScriptContext is false,
+   * not finding an nsIScriptContext does not cause failure.
    */
   nsresult SetEventHandlerToJsval(nsIAtom *aEventName, JSContext *cx,
-                                  JSObject *aScope, const jsval &v);
+                                  JSObject *aScope, const jsval &v,
+                                  bool aExpectScriptContext);
   /**
    * Get the value of the "inline" event listener for aEventName.
    * This may cause lazy compilation if the listener is uncompiled.
    */
   void GetEventHandler(nsIAtom *aEventName, jsval *vp);
 
 protected:
   void AddEventListener(nsIDOMEventListener *aListener, 
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -42,29 +42,25 @@ DOMRequest::Init(nsIDOMWindow* aWindow)
 }
 
 DOMCI_DATA(DOMRequest, DOMRequest)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMRequest,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mError)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
                                                 nsDOMEventTargetHelper)
   if (tmp->mRooted) {
     tmp->mResult = JSVAL_VOID;
     tmp->UnrootResultVal();
   }
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMRequest,
                                                nsDOMEventTargetHelper)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
   // nsDOMEventTargetHelper does it for us.
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResult)
@@ -73,18 +69,18 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMRequest)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMRequest)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(DOMRequest, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(DOMRequest, nsDOMEventTargetHelper)
 
-NS_IMPL_EVENT_HANDLER(DOMRequest, success);
-NS_IMPL_EVENT_HANDLER(DOMRequest, error);
+NS_IMPL_EVENT_HANDLER(DOMRequest, success)
+NS_IMPL_EVENT_HANDLER(DOMRequest, error)
 
 NS_IMETHODIMP
 DOMRequest::GetReadyState(nsAString& aReadyState)
 {
   mDone ? aReadyState.AssignLiteral("done") :
           aReadyState.AssignLiteral("pending");
 
   return NS_OK;
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -21,19 +21,16 @@ class DOMRequest : public nsDOMEventTarg
                    public nsIDOMDOMRequest
 {
 protected:
   jsval mResult;
   nsCOMPtr<nsIDOMDOMError> mError;
   bool mDone;
   bool mRooted;
 
-  NS_DECL_EVENT_HANDLER(success)
-  NS_DECL_EVENT_HANDLER(error)
-
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMREQUEST
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(DOMRequest,
                                                          nsDOMEventTargetHelper)
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11090,17 +11090,18 @@ nsGlobalWindow::SetHasAudioAvailableEven
     if (!elm) {                                                              \
       return NS_ERROR_OUT_OF_MEMORY;                                         \
     }                                                                        \
                                                                              \
     JSObject *obj = mJSObject;                                               \
     if (!obj) {                                                              \
       return NS_ERROR_UNEXPECTED;                                            \
     }                                                                        \
-    return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v);    \
+    return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v,     \
+                                       true);                                \
   }
 #define WINDOW_ONLY_EVENT EVENT
 #define TOUCH_EVENT EVENT
 #include "nsEventNameList.h"
 #undef TOUCH_EVENT
 #undef WINDOW_ONLY_EVENT
 #undef EVENT
 
--- a/dom/base/nsIDOMDOMRequest.idl
+++ b/dom/base/nsIDOMDOMRequest.idl
@@ -4,26 +4,26 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMDOMError;
 interface nsIDOMWindow;
 
-[scriptable, builtinclass, uuid(a3ad2846-ffb2-48d7-a786-2254cb82560d)]
+[scriptable, builtinclass, uuid(d88998b7-ee30-4ae5-bbed-58f5711929de)]
 interface nsIDOMDOMRequest : nsIDOMEventTarget
 {
   readonly attribute DOMString readyState; // "pending" or "done"
 
   readonly attribute jsval result;
   readonly attribute nsIDOMDOMError error;
 
-  attribute nsIDOMEventListener onsuccess;
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onsuccess;
+  [implicit_jscontext] attribute jsval onerror;
 };
 
 [scriptable, builtinclass, uuid(eebcdf29-f8fa-4c36-bbc7-2146b1cbaf7b)]
 interface nsIDOMRequestService : nsISupports
 {
   nsIDOMDOMRequest createRequest(in nsIDOMWindow window);
 
   void fireSuccess(in nsIDOMDOMRequest request, in jsval result);
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -87,22 +87,20 @@ nsScreen::~nsScreen()
 
 
 DOMCI_DATA(Screen, nsScreen)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsScreen)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsScreen,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(mozorientationchange)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsScreen,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(mozorientationchange)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 // QueryInterface implementation for nsScreen
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsScreen)
   NS_INTERFACE_MAP_ENTRY(nsIDOMScreen)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMScreen)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Screen)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
--- a/dom/base/nsScreen.h
+++ b/dom/base/nsScreen.h
@@ -53,13 +53,11 @@ private:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIDOMEVENTLISTENER
   };
 
   nsScreen();
   virtual ~nsScreen();
 
   nsRefPtr<FullScreenEventListener> mEventListener;
-
-  NS_DECL_EVENT_HANDLER(mozorientationchange)
 };
 
 #endif /* nsScreen_h___ */
--- a/dom/battery/BatteryManager.cpp
+++ b/dom/battery/BatteryManager.cpp
@@ -26,38 +26,35 @@ DOMCI_DATA(BatteryManager, mozilla::dom:
 namespace mozilla {
 namespace dom {
 namespace battery {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BatteryManager)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BatteryManager,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(levelchange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(chargingchange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(chargingtimechange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(dischargingtimechange)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BatteryManager,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(levelchange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(chargingchange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(chargingtimechange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(dischargingtimechange)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BatteryManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBatteryManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BatteryManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BatteryManager, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(BatteryManager, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(BatteryManager, levelchange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, chargingchange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, chargingtimechange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, dischargingtimechange)
+
 BatteryManager::BatteryManager()
   : mLevel(kDefaultLevel)
   , mCharging(kDefaultCharging)
   , mRemainingTime(kDefaultRemainingTime)
 {
 }
 
 void
@@ -116,21 +113,16 @@ BatteryManager::GetChargingTime(double* 
     return NS_OK;
   }
 
   *aChargingTime = mRemainingTime;
 
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(BatteryManager, levelchange)
-NS_IMPL_EVENT_HANDLER(BatteryManager, chargingchange)
-NS_IMPL_EVENT_HANDLER(BatteryManager, chargingtimechange)
-NS_IMPL_EVENT_HANDLER(BatteryManager, dischargingtimechange)
-
 nsresult
 BatteryManager::DispatchTrustedEventToSelf(const nsAString& aEventName)
 {
   nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
   nsresult rv = event->InitEvent(aEventName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = event->SetTrusted(true);
--- a/dom/battery/BatteryManager.h
+++ b/dom/battery/BatteryManager.h
@@ -66,20 +66,15 @@ private:
 
   double mLevel;
   bool   mCharging;
   /**
    * Represents the discharging time or the charging time, dpending on the
    * current battery status (charging or not).
    */
   double mRemainingTime;
-
-  NS_DECL_EVENT_HANDLER(levelchange)
-  NS_DECL_EVENT_HANDLER(chargingchange)
-  NS_DECL_EVENT_HANDLER(chargingtimechange)
-  NS_DECL_EVENT_HANDLER(dischargingtimechange)
 };
 
 } // namespace battery
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_battery_BatteryManager_h
--- a/dom/battery/nsIDOMBatteryManager.idl
+++ b/dom/battery/nsIDOMBatteryManager.idl
@@ -1,21 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, builtinclass, uuid(03c6dd20-7efd-4640-b958-c0ce11b9aadf)]
+[scriptable, builtinclass, uuid(3d95d773-3c19-4944-8152-ec6ca01a8bde)]
 interface nsIDOMBatteryManager : nsIDOMEventTarget
 {
   readonly attribute double     level;
   readonly attribute boolean    charging;
   readonly attribute double     dischargingTime;
   readonly attribute double     chargingTime;
 
-  attribute nsIDOMEventListener onlevelchange;
-  attribute nsIDOMEventListener onchargingchange;
-  attribute nsIDOMEventListener ondischargingtimechange;
-  attribute nsIDOMEventListener onchargingtimechange;
+  [implicit_jscontext] attribute jsval onlevelchange;
+  [implicit_jscontext] attribute jsval onchargingchange;
+  [implicit_jscontext] attribute jsval ondischargingtimechange;
+  [implicit_jscontext] attribute jsval onchargingtimechange;
 };
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -40,37 +40,21 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
                                                nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter, 
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicefound)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicedisappeared)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestconfirmation)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestpincode)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestpasskey)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(authorize)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(cancel)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter, 
                                                 nsDOMEventTargetHelper)
   tmp->Unroot();
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicefound)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicedisappeared)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(propertychanged)  
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestconfirmation)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestpincode)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestpasskey)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(authorize)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(cancel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -77,22 +77,13 @@ private:
   uint32_t mPairableTimeout;
   uint32_t mDiscoverableTimeout;
   uint32_t mClass;
   nsTArray<nsString> mDeviceAddresses;
   nsTArray<nsString> mUuids;
   JSObject* mJsUuids;
   JSObject* mJsDeviceAddresses;
   bool mIsRooted;
-  
-  NS_DECL_EVENT_HANDLER(propertychanged)
-  NS_DECL_EVENT_HANDLER(devicefound)
-  NS_DECL_EVENT_HANDLER(devicedisappeared)
-  NS_DECL_EVENT_HANDLER(requestconfirmation)
-  NS_DECL_EVENT_HANDLER(requestpincode)
-  NS_DECL_EVENT_HANDLER(requestpasskey)
-  NS_DECL_EVENT_HANDLER(authorize)
-  NS_DECL_EVENT_HANDLER(cancel)
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/BluetoothDevice.cpp
+++ b/dom/bluetooth/BluetoothDevice.cpp
@@ -25,27 +25,21 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Bluetooth
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
                                                nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice, 
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(connected)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(disconnected)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothDevice, 
                                                 nsDOMEventTargetHelper)
   tmp->Unroot();
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(propertychanged)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(connected)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(disconnected)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothDevice)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothDevice)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothDevice)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BluetoothDevice, nsDOMEventTargetHelper)
--- a/dom/bluetooth/BluetoothDevice.h
+++ b/dom/bluetooth/BluetoothDevice.h
@@ -69,17 +69,13 @@ private:
   nsString mAddress;
   nsString mName;
   nsString mIcon;
   uint32_t mClass;
   bool mConnected;
   bool mPaired;
   bool mIsRooted;
   nsTArray<nsString> mUuids;
-
-  NS_DECL_EVENT_HANDLER(propertychanged)
-  NS_DECL_EVENT_HANDLER(connected)
-  NS_DECL_EVENT_HANDLER(disconnected)
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/BluetoothManager.cpp
+++ b/dom/bluetooth/BluetoothManager.cpp
@@ -32,24 +32,20 @@ using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 DOMCI_DATA(BluetoothManager, BluetoothManager)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothManager)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothManager,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(enabled)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(disabled)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothManager,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(enabled)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(disabled)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BluetoothManager, nsDOMEventTargetHelper)
--- a/dom/bluetooth/BluetoothManager.h
+++ b/dom/bluetooth/BluetoothManager.h
@@ -45,19 +45,16 @@ public:
   nsresult FireEnabledDisabledEvent();
 private:
   BluetoothManager(nsPIDOMWindow* aWindow);
   ~BluetoothManager();
 
   nsresult HandleMozsettingChanged(const PRUnichar* aData);
 
   bool mEnabled;
-
-  NS_DECL_EVENT_HANDLER(enabled)
-  NS_DECL_EVENT_HANDLER(disabled)
 };
 
 END_BLUETOOTH_NAMESPACE
 
 nsresult NS_NewBluetoothManager(nsPIDOMWindow* aWindow,
                                 nsIDOMBluetoothManager** aBluetoothManager);
 
 #endif
--- a/dom/bluetooth/nsIDOMBluetoothAdapter.idl
+++ b/dom/bluetooth/nsIDOMBluetoothAdapter.idl
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMDOMRequest;
 interface nsIDOMBluetoothDevice;
 
-[scriptable, builtinclass, uuid(db6b4dd6-64f1-415d-ac51-ae0fa0fe05ed)]
+[scriptable, builtinclass, uuid(4ea7d312-f37c-4777-8114-fc7312890199)]
 interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
 {
   readonly attribute DOMString address;
   [binaryname(AdapterClass)] readonly attribute unsigned long class;
   readonly attribute bool enabled;
   readonly attribute bool discovering;
 
   [implicit_jscontext]
@@ -37,20 +37,20 @@ interface nsIDOMBluetoothAdapter : nsIDO
   nsIDOMDOMRequest unpair(in nsIDOMBluetoothDevice aDevice);
   nsIDOMDOMRequest getPairedDevices();
   void setPinCode(in DOMString aDeviceAddress, in DOMString aPinCode);
   void setPasskey(in DOMString aDeviceAddress, in unsigned long aPasskey);
   void setPairingConfirmation(in DOMString aDeviceAddress, in bool aConfirmation);
   void setAuthorization(in DOMString aDeviceAddress, in bool aAllow);
 
   // Fired when discoverying and any device is discovered.
-  attribute nsIDOMEventListener ondevicefound;
+  [implicit_jscontext] attribute jsval ondevicefound;
   // Fired when any device is out of discoverable range.
-  attribute nsIDOMEventListener ondevicedisappeared;
+  [implicit_jscontext] attribute jsval ondevicedisappeared;
   // Fired when a property of the adapter is changed
-  attribute nsIDOMEventListener onpropertychanged;
+  [implicit_jscontext] attribute jsval onpropertychanged;
   // Pairing related events
-  attribute nsIDOMEventListener onrequestconfirmation;
-  attribute nsIDOMEventListener onrequestpincode;
-  attribute nsIDOMEventListener onrequestpasskey;
-  attribute nsIDOMEventListener onauthorize;
-  attribute nsIDOMEventListener oncancel;
+  [implicit_jscontext] attribute jsval onrequestconfirmation;
+  [implicit_jscontext] attribute jsval onrequestpincode;
+  [implicit_jscontext] attribute jsval onrequestpasskey;
+  [implicit_jscontext] attribute jsval onauthorize;
+  [implicit_jscontext] attribute jsval oncancel;
 };
--- a/dom/bluetooth/nsIDOMBluetoothDevice.idl
+++ b/dom/bluetooth/nsIDOMBluetoothDevice.idl
@@ -1,22 +1,22 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
-[scriptable, builtinclass, uuid(4a271533-6a09-4a65-ae2b-086794c7852c)]
+[scriptable, builtinclass, uuid(4a679fc6-572a-4ddc-8e93-cfbddb9f2d6a)]
 interface nsIDOMBluetoothDevice : nsIDOMEventTarget
 {
   readonly attribute DOMString address;
   readonly attribute DOMString name;
   readonly attribute DOMString icon;
   [binaryname(DeviceClass)] readonly attribute unsigned long class;
   [implicit_jscontext] readonly attribute jsval uuids;
   readonly attribute bool connected;
   readonly attribute bool paired;
-  attribute nsIDOMEventListener onpropertychanged;
-  attribute nsIDOMEventListener onconnected;
-  attribute nsIDOMEventListener ondisconnected;
+  [implicit_jscontext] attribute jsval onpropertychanged;
+  [implicit_jscontext] attribute jsval onconnected;
+  [implicit_jscontext] attribute jsval ondisconnected;
 };
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -18,17 +18,16 @@ class nsDOMDeviceStorage MOZ_FINAL
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMDEVICESTORAGE
 
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIDOMEVENTTARGET
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
-  NS_DECL_EVENT_HANDLER(change)
 
   nsDOMDeviceStorage();
 
   nsresult Init(nsPIDOMWindow* aWindow, const nsAString &aType);
 
   void SetRootFileForType(const nsAString& aType);
 
   static void CreateDeviceStoragesFor(nsPIDOMWindow* aWin,
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -1421,21 +1421,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMP
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mBlob, nsIDOMBlob)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDeviceStorage, nsIDOMDeviceStorage)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mListener, nsIDOMEventListener)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDeviceStorage)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(change)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(change)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(DeviceStorage, nsDOMDeviceStorage)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDeviceStorage)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceStorage)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceStorage)
@@ -2054,9 +2052,9 @@ nsDOMDeviceStorage::GetContextForEventHa
 }
 
 JSContext *
 nsDOMDeviceStorage::GetJSContextForEventHandlers()
 {
   return nsDOMEventTargetHelper::GetJSContextForEventHandlers();
 }
 
-NS_IMPL_EVENT_HANDLER(nsDOMDeviceStorage, change)
+NS_IMPL_EVENT_HANDLER(nsDOMDeviceStorage, change)
\ No newline at end of file
--- a/dom/file/FileHandle.cpp
+++ b/dom/file/FileHandle.cpp
@@ -49,25 +49,21 @@ private:
 
 } // anonymous namespace
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(FileHandle)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileHandle,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFileStorage)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileHandle,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFileStorage)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileHandle)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileHandle)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(FileHandle, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(FileHandle, nsDOMEventTargetHelper)
--- a/dom/file/FileHandle.h
+++ b/dom/file/FileHandle.h
@@ -72,16 +72,13 @@ protected:
 
   nsCOMPtr<nsIFileStorage> mFileStorage;
 
   nsString mName;
   nsString mType;
 
   nsCOMPtr<nsIFile> mFile;
   nsString mFileName;
-
-  NS_DECL_EVENT_HANDLER(abort)
-  NS_DECL_EVENT_HANDLER(error)
 };
 
 END_FILE_NAMESPACE
 
 #endif // mozilla_dom_file_filehandle_h__
--- a/dom/file/FileRequest.cpp
+++ b/dom/file/FileRequest.cpp
@@ -105,25 +105,21 @@ FileRequest::GetLockedFile(nsIDOMLockedF
   nsCOMPtr<nsIDOMLockedFile> lockedFile(mLockedFile);
   lockedFile.forget(aLockedFile);
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(FileRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileRequest, DOMRequest)
-  // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
-  // nsDOMEventTargetHelper does it for us.
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mLockedFile,
                                                        nsIDOMLockedFile)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileRequest, DOMRequest)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLockedFile)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileRequest)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFileRequest, mIsFileRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(FileRequest, mIsFileRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(DOMRequest, !mIsFileRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
--- a/dom/file/FileRequest.h
+++ b/dom/file/FileRequest.h
@@ -48,15 +48,13 @@ private:
   FileRequest(nsIDOMWindow* aWindow);
   ~FileRequest();
 
   void
   FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
 
   nsRefPtr<LockedFile> mLockedFile;
   bool mIsFileRequest;
-
-  NS_DECL_EVENT_HANDLER(progress)
 };
 
 END_FILE_NAMESPACE
 
 #endif // mozilla_dom_file_filerequest_h__
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -322,27 +322,21 @@ LockedFile::~LockedFile()
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(LockedFile)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(LockedFile,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mFileHandle,
                                                        nsIDOMEventTarget)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(LockedFile,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFileHandle)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(LockedFile)
   NS_INTERFACE_MAP_ENTRY(nsIDOMLockedFile)
   NS_INTERFACE_MAP_ENTRY(nsIRunnable)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(LockedFile)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
--- a/dom/file/LockedFile.h
+++ b/dom/file/LockedFile.h
@@ -114,20 +114,16 @@ private:
 
   nsRefPtr<FileHandle> mFileHandle;
   ReadyState mReadyState;
   Mode mMode;
   RequestMode mRequestMode;
   uint64_t mLocation;
   uint32_t mPendingRequests;
 
-  NS_DECL_EVENT_HANDLER(complete)
-  NS_DECL_EVENT_HANDLER(abort)
-  NS_DECL_EVENT_HANDLER(error)
-
   nsTArray<nsCOMPtr<nsISupports> > mParallelStreams;
   nsCOMPtr<nsISupports> mStream;
 
   bool mAborted;
   bool mCreating;
 };
 
 class FinishHelper MOZ_FINAL : public nsIRunnable
--- a/dom/file/nsIDOMFileHandle.idl
+++ b/dom/file/nsIDOMFileHandle.idl
@@ -17,17 +17,17 @@ class FileInfo;
 %}
 
 [ptr] native FileInfo(mozilla::dom::indexedDB::FileInfo);
 
 interface nsIDOMDOMRequest;
 interface nsIDOMEventListener;
 interface nsIDOMLockedFile;
 
-[scriptable, builtinclass, uuid(882ad3d0-6fb1-4841-8e17-0ba17b11edc8)]
+[scriptable, builtinclass, uuid(47438729-7f3f-4a66-b6d4-d1297c593d46)]
 interface nsIDOMFileHandle : nsISupports
 {
   readonly attribute DOMString name;
 
   readonly attribute DOMString type;
 
   // mode can be either "readonly" or "readwrite"
   [optional_argc]
@@ -40,12 +40,12 @@ interface nsIDOMFileHandle : nsISupports
   [notxpcom]
   long long
   getFileId();
 
   [notxpcom]
   FileInfo
   getFileInfo();
 
-  attribute nsIDOMEventListener onabort;
+  [implicit_jscontext] attribute jsval onabort;
 
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onerror;
 };
--- a/dom/file/nsIDOMFileRequest.idl
+++ b/dom/file/nsIDOMFileRequest.idl
@@ -4,15 +4,15 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMDOMRequest.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMLockedFile;
 
-[scriptable, builtinclass, uuid(fe06b66e-fede-4d44-ab3a-403f60d6b593)]
+[scriptable, builtinclass, uuid(6733d649-0acb-487d-8a7d-f102ac4419e9)]
 interface nsIDOMFileRequest : nsIDOMDOMRequest
 {
   readonly attribute nsIDOMLockedFile lockedFile;
 
-  attribute nsIDOMEventListener onprogress;
+  [implicit_jscontext] attribute jsval onprogress;
 };
--- a/dom/file/nsIDOMLockedFile.idl
+++ b/dom/file/nsIDOMLockedFile.idl
@@ -11,17 +11,17 @@ interface nsIDOMFileHandle;
 interface nsIDOMFileRequest;
 
 dictionary DOMFileMetadataParameters
 {
   boolean size;
   boolean lastModified;
 };
 
-[scriptable, builtinclass, uuid(696a4cbf-603d-40e1-840a-e468ee363871)]
+[scriptable, builtinclass, uuid(589e0d26-20b5-4355-ac1e-9c6fd0dd83f2)]
 interface nsIDOMLockedFile : nsISupports
 {
   readonly attribute nsIDOMFileHandle fileHandle;
 
   // "readonly" or "readwrite"
   readonly attribute DOMString mode;
 
   readonly attribute boolean active;
@@ -55,14 +55,14 @@ interface nsIDOMLockedFile : nsISupports
   truncate([optional] in unsigned long long size);
 
   nsIDOMFileRequest
   flush();
 
   void
   abort();
 
-  attribute nsIDOMEventListener oncomplete;
+  [implicit_jscontext] attribute jsval oncomplete;
 
-  attribute nsIDOMEventListener onabort;
+  [implicit_jscontext] attribute jsval onabort;
 
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onerror;
 };
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -402,27 +402,21 @@ IDBDatabase::CreateObjectStoreInternal(I
   objectStore.forget(_retval);
 
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(versionchange)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFactory)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
   // Don't unlink mFactory!
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(versionchange)
 
   // Do some cleanup.
   tmp->OnUnlink();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
   NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase)
   NS_INTERFACE_MAP_ENTRY(nsIFileStorage)
--- a/dom/indexedDB/IDBDatabase.h
+++ b/dom/indexedDB/IDBDatabase.h
@@ -173,21 +173,16 @@ private:
   nsRefPtr<DatabaseInfo> mPreviousDatabaseInfo;
   nsCOMPtr<nsIAtom> mDatabaseId;
   nsString mName;
   nsString mFilePath;
   nsCString mASCIIOrigin;
 
   nsRefPtr<FileManager> mFileManager;
 
-  // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(abort)
-  NS_DECL_EVENT_HANDLER(error)
-  NS_DECL_EVENT_HANDLER(versionchange)
-
   IndexedDBDatabaseChild* mActorChild;
   IndexedDBDatabaseParent* mActorParent;
 
   mozilla::dom::ContentParent* mContentParent;
 
   int32_t mInvalidated;
   bool mRegistered;
   bool mClosed;
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -289,27 +289,23 @@ IDBRequest::GetError(nsIDOMDOMError** aE
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
   // nsDOMEventTargetHelper does it for us.
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
                                                        nsPIDOMEventTarget)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
   tmp->mResultVal = JSVAL_VOID;
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
   // nsDOMEventTargetHelper does it for us.
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResultVal)
@@ -320,18 +316,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
 NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache)
 NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
 
 DOMCI_DATA(IDBRequest, IDBRequest)
 
-NS_IMPL_EVENT_HANDLER(IDBRequest, success);
-NS_IMPL_EVENT_HANDLER(IDBRequest, error);
+NS_IMPL_EVENT_HANDLER(IDBRequest, success)
+NS_IMPL_EVENT_HANDLER(IDBRequest, error)
 
 nsresult
 IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = mTransaction;
@@ -376,38 +372,34 @@ IDBOpenDBRequest::SetTransaction(IDBTran
 
   mTransaction = aTransaction;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
                                                   IDBRequest)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(upgradeneeded)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(blocked)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFactory)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
                                                 IDBRequest)
   // Don't unlink mFactory!
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(upgradeneeded)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(blocked)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
   NS_INTERFACE_MAP_ENTRY(nsIIDBOpenDBRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBOpenDBRequest)
 NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
 
 NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
 NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
 
 DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
 
-NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked);
-NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded);
+NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked)
+NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded)
 
 nsresult
 IDBOpenDBRequest::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor);
 }
--- a/dom/indexedDB/IDBRequest.h
+++ b/dom/indexedDB/IDBRequest.h
@@ -86,19 +86,16 @@ public:
 
 protected:
   IDBRequest();
   ~IDBRequest();
 
   nsCOMPtr<nsISupports> mSource;
   nsRefPtr<IDBTransaction> mTransaction;
 
-  NS_DECL_EVENT_HANDLER(success)
-  NS_DECL_EVENT_HANDLER(error)
-
   jsval mResultVal;
 
   nsCOMPtr<nsIDOMDOMError> mError;
 
   IndexedDBRequestParentBase* mActorParent;
 
   nsresult mErrorCode;
   bool mHaveResultOrErrorCode;
@@ -133,17 +130,14 @@ public:
   {
     return mFactory;
   }
 
 protected:
   ~IDBOpenDBRequest();
 
   // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(blocked)
-  NS_DECL_EVENT_HANDLER(upgradeneeded)
-
   nsRefPtr<IDBFactory> mFactory;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbrequest_h__
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -586,38 +586,32 @@ IDBTransaction::Abort(nsresult aErrorCod
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
                                                   IDBWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDatabase,
                                                        nsIDOMEventTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mError);
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
 
   for (uint32_t i = 0; i < tmp->mCreatedObjectStores.Length(); i++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedObjectStores[i]");
     cb.NoteXPCOMChild(static_cast<nsIIDBObjectStore*>(
                       tmp->mCreatedObjectStores[i].get()));
   }
   for (uint32_t i = 0; i < tmp->mDeletedObjectStores.Length(); i++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDeletedObjectStores[i]");
     cb.NoteXPCOMChild(static_cast<nsIIDBObjectStore*>(
                       tmp->mDeletedObjectStores[i].get()));
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
   // Don't unlink mDatabase!
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError);
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
 
   tmp->mCreatedObjectStores.Clear();
   tmp->mDeletedObjectStores.Clear();
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
   NS_INTERFACE_MAP_ENTRY(nsIIDBTransaction)
@@ -625,19 +619,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBTransaction)
 NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache)
 NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache)
 
 DOMCI_DATA(IDBTransaction, IDBTransaction)
 
-NS_IMPL_EVENT_HANDLER(IDBTransaction, error);
-NS_IMPL_EVENT_HANDLER(IDBTransaction, complete);
-NS_IMPL_EVENT_HANDLER(IDBTransaction, abort);
+NS_IMPL_EVENT_HANDLER(IDBTransaction, error)
+NS_IMPL_EVENT_HANDLER(IDBTransaction, complete)
+NS_IMPL_EVENT_HANDLER(IDBTransaction, abort)
 
 NS_IMETHODIMP
 IDBTransaction::GetDb(nsIIDBDatabase** aDB)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   NS_ADDREF(*aDB = mDatabase);
   return NS_OK;
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -224,21 +224,16 @@ private:
   nsRefPtr<IDBDatabase> mDatabase;
   nsRefPtr<DatabaseInfo> mDatabaseInfo;
   nsCOMPtr<nsIDOMDOMError> mError;
   nsTArray<nsString> mObjectStoreNames;
   ReadyState mReadyState;
   Mode mMode;
   uint32_t mPendingRequests;
 
-  // Only touched on the main thread.
-  NS_DECL_EVENT_HANDLER(error)
-  NS_DECL_EVENT_HANDLER(complete)
-  NS_DECL_EVENT_HANDLER(abort)
-
   nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
     mCachedStatements;
 
   nsRefPtr<IDBTransactionListener> mListener;
 
   // Only touched on the database thread.
   nsCOMPtr<mozIStorageConnection> mConnection;
 
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ b/dom/indexedDB/nsIIDBDatabase.idl
@@ -18,17 +18,17 @@ dictionary IDBObjectStoreParameters
   boolean autoIncrement;
 };
 
 /**
  * IDBDatabase interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
  * for more information.
  */
-[scriptable, builtinclass, uuid(601a43a0-dce2-402f-8ba5-238fe5d5f8d2)]
+[scriptable, builtinclass, uuid(89299bf8-e078-4ebc-abda-d97fe5618602)]
 interface nsIIDBDatabase : nsISupports
 {
   readonly attribute DOMString name;
 
   readonly attribute unsigned long long version;
 
   readonly attribute nsIDOMDOMStringList objectStoreNames;
 
@@ -50,14 +50,14 @@ interface nsIIDBDatabase : nsISupports
   [implicit_jscontext]
   nsIIDBRequest
   mozCreateFileHandle(in DOMString name,
                       [optional] in DOMString type);
 
   void
   close();
 
-  attribute nsIDOMEventListener onabort;
+  [implicit_jscontext] attribute jsval onabort;
 
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onerror;
 
-  attribute nsIDOMEventListener onversionchange;
+  [implicit_jscontext] attribute jsval onversionchange;
 };
--- a/dom/indexedDB/nsIIDBOpenDBRequest.idl
+++ b/dom/indexedDB/nsIIDBOpenDBRequest.idl
@@ -8,14 +8,14 @@
 
 interface nsIDOMEventListener;
 
 /**
  * IDBOpenDBRequest interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest
  * for more information.
  */
-[scriptable, builtinclass, uuid(91010fbe-1dfb-435d-852e-288d2804c0a7)]
+[scriptable, builtinclass, uuid(2d6c5ef4-b84a-45ae-9030-eb6cfc65bb26)]
 interface nsIIDBOpenDBRequest : nsISupports
 {
-  attribute nsIDOMEventListener onblocked;
-  attribute nsIDOMEventListener onupgradeneeded;
+  [implicit_jscontext] attribute jsval onblocked;
+  [implicit_jscontext] attribute jsval onupgradeneeded;
 };
--- a/dom/indexedDB/nsIIDBRequest.idl
+++ b/dom/indexedDB/nsIIDBRequest.idl
@@ -10,25 +10,25 @@ interface nsIDOMDOMError;
 interface nsIDOMEventListener;
 interface nsIIDBTransaction;
 
 /**
  * IDBRequest interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
  * information.
  */
-[scriptable, builtinclass, uuid(4b9d901b-14a4-430c-b41b-5ecb238f4184)]
+[scriptable, builtinclass, uuid(006f39d6-342e-4935-a438-365611fd9491)]
 interface nsIIDBRequest : nsISupports
 {
   readonly attribute jsval result;
 
   readonly attribute nsIDOMDOMError error;
 
   readonly attribute nsISupports source;
 
   readonly attribute nsIIDBTransaction transaction;
 
   // "pending" or "done"
   readonly attribute DOMString readyState;
 
-  attribute nsIDOMEventListener onsuccess;
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onsuccess;
+  [implicit_jscontext] attribute jsval onerror;
 };
--- a/dom/indexedDB/nsIIDBTransaction.idl
+++ b/dom/indexedDB/nsIIDBTransaction.idl
@@ -13,17 +13,17 @@ interface nsIIDBDatabase;
 interface nsIDOMDOMStringList;
 interface nsIDOMDOMError;
 
 /**
  * IDBDTransaction interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBTransaction
  * for more information.
  */
-[scriptable, builtinclass, uuid(79f73099-02ff-416d-9754-5a315e29ee4f)]
+[scriptable, builtinclass, uuid(3197172b-2f56-4837-9427-5e5d4b20a363)]
 interface nsIIDBTransaction : nsISupports
 {
   readonly attribute nsIIDBDatabase db;
 
   // "readonly", "readwrite" or "versionchange"
   readonly attribute DOMString mode;
 
   readonly attribute nsIDOMDOMError error;
@@ -31,18 +31,18 @@ interface nsIIDBTransaction : nsISupport
   readonly attribute nsIDOMDOMStringList objectStoreNames;
 
   nsIIDBObjectStore
   objectStore([Null(Stringify)] in DOMString name);
 
   // Don't commit the transaction.
   void abort();
 
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onerror;
 
   // Event listener that fires when the transaction is completed
   // successfully. Receives an Event.
-  attribute nsIDOMEventListener oncomplete;
+  [implicit_jscontext] attribute jsval oncomplete;
 
   // Event listener that fires when the transaction is aborted.
   // Receives an Event.
-  attribute nsIDOMEventListener onabort;
+  [implicit_jscontext] attribute jsval onabort;
 };
--- a/dom/indexedDB/test/test_autoIncrement.html
+++ b/dom/indexedDB/test/test_autoIncrement.html
@@ -219,37 +219,37 @@
       yield; yield;
 
       // Test that error inserts doesn't increase generator
       test = " for test error inserts";
       trans = db.transaction(["store1", "store2"], RW);
       trans.objectStore("store1").add({ unique: 1 }, -1);
       trans.objectStore("store2").add({ unique: 1, id: "unique" });
 
-      trans.objectStore("store1").add({ error: 1, unique: 1 }).onerror =
-        new ExpectError("ConstraintError", true);
+      trans.objectStore("store1").add({ error: 1, unique: 1 }).
+        addEventListener("error", new ExpectError("ConstraintError", true));
       trans.objectStore("store1").add({ error: 2 }).onsuccess =
         genCheck(c1++, { error: 2 }, "first" + test);
       yield; yield;
 
-      trans.objectStore("store2").add({ error: 3, unique: 1 }).onerror =
-        new ExpectError("ConstraintError", true);
+      trans.objectStore("store2").add({ error: 3, unique: 1 }).
+        addEventListener("error", new ExpectError("ConstraintError", true));
       trans.objectStore("store2").add({ error: 4 }).onsuccess =
         genCheck(c2, { error: 4, id: c2 }, "second" + test);
       c2++;
       yield; yield;
 
-      trans.objectStore("store1").add({ error: 5, unique: 1 }, 100000).onerror =
-        new ExpectError("ConstraintError", true);
+      trans.objectStore("store1").add({ error: 5, unique: 1 }, 100000).
+        addEventListener("error", new ExpectError("ConstraintError", true));
       trans.objectStore("store1").add({ error: 6 }).onsuccess =
         genCheck(c1++, { error: 6 }, "third" + test);
       yield; yield;
 
-      trans.objectStore("store2").add({ error: 7, unique: 1, id: 100000 }).onerror =
-        new ExpectError("ConstraintError", true);
+      trans.objectStore("store2").add({ error: 7, unique: 1, id: 100000 }).
+        addEventListener("error", new ExpectError("ConstraintError", true));
       trans.objectStore("store2").add({ error: 8 }).onsuccess =
         genCheck(c2, { error: 8, id: c2 }, "fourth" + test);
       c2++;
       yield; yield;
 
       // Test that aborts doesn't increase generator
       test = " for test aborted transaction";
       trans = db.transaction(["store1", "store2"], RW);
--- a/dom/indexedDB/test/test_file_quota.html
+++ b/dom/indexedDB/test/test_file_quota.html
@@ -41,17 +41,17 @@
     event = yield;
 
     is(event.type, "success", "Got correct event type");
 
     trans = db.transaction([objectStoreName], READ_WRITE);
     objectStore = trans.objectStore(objectStoreName);
 
     request = objectStore.add(fileData.file, fileData.key);
-    request.onerror = new ExpectError("UnknownError");
+    request.addEventListener("error", new ExpectError("UnknownError"));
     request.onsuccess = unexpectedSuccessHandler;
     event = yield;
 
     trans.oncomplete = grabEventAndContinueHandler;
     event = yield;
 
     is(event.type, "complete", "Got correct event type");
 
--- a/dom/indexedDB/test/test_filehandle_quota.html
+++ b/dom/indexedDB/test/test_filehandle_quota.html
@@ -37,17 +37,17 @@
     let fileHandle = event.target.result;
     fileHandle.onerror = errorHandler;
 
     let lockedFile = fileHandle.open("readwrite");
 
     let blob = getNullBlob((50 + 1) * 1024 * 1024 - getUsageSync());
 
     request = lockedFile.write(blob);
-    request.onerror = new ExpectError("UnknownError");
+    request.addEventListener("error", new ExpectError("UnknownError"));
     request.onsuccess = unexpectedSuccessHandler;
     event = yield;
 
     lockedFile.oncomplete = grabEventAndContinueHandler;
     event = yield;
 
     is(event.type, "complete", "Got correct event type");
 
--- a/dom/indexedDB/test/test_unique_index_update.html
+++ b/dom/indexedDB/test/test_unique_index_update.html
@@ -36,34 +36,34 @@
       is(event.type, "success", "expect a success event");
 
       for each (let autoIncrement in [false, true]) {
         objectStore = db.transaction(autoIncrement, IDBTransaction.READ_WRITE)
                         .objectStore(autoIncrement);
 
         request = objectStore.put({ id: 5, index: 6 });
         request.onsuccess = unexpectedSuccessHandler;
-        request.onerror = new ExpectError("ConstraintError", true);
+        request.addEventListener("error", new ExpectError("ConstraintError", true));
         event = yield;
 
         event.preventDefault();
 
         let keyRange = IDBKeyRange.only(5);
 
         objectStore.index("").openCursor(keyRange).onsuccess = function(event) {
           let cursor = event.target.result;
           ok(cursor, "Must have a cursor here");
 
           is(cursor.value.index, 5, "Still have the right index value");
 
           cursor.value.index = 6;
 
           request = cursor.update(cursor.value);
           request.onsuccess = unexpectedSuccessHandler;
-          request.onerror = new ExpectError("ConstraintError", true);
+          request.addEventListener("error", new ExpectError("ConstraintError", true));
         };
 
         yield;
       }
 
       finishTest();
       yield;
     }
--- a/dom/indexedDB/test/unit/test_add_twice_failure.js
+++ b/dom/indexedDB/test/unit/test_add_twice_failure.js
@@ -24,16 +24,16 @@ function testSteps()
   request = objectStore.add({}, key);
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(request.result, key, "Correct key");
 
   request = objectStore.add({}, key);
-  request.onerror = new ExpectError("ConstraintError", true);
+  request.addEventListener("error", new ExpectError("ConstraintError", true));
   request.onsuccess = unexpectedSuccessHandler;
   yield;
 
   finishTest();
   yield;
 }
 
--- a/dom/indexedDB/test/unit/test_index_empty_keyPath.js
+++ b/dom/indexedDB/test/unit/test_index_empty_keyPath.js
@@ -65,17 +65,17 @@ function testSteps()
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   
   let event = yield;
 
   is(event.target.result, "foopy", "Got correct result");
 
   let request = objectStore.add("foopy", 5);
-  request.onerror = new ExpectError("ConstraintError", true);
+  request.addEventListener("error", new ExpectError("ConstraintError", true));
   request.onsuccess = unexpectedSuccessHandler;
 
   trans.oncomplete = grabEventAndContinueHandler;
 
   yield;
   yield;
 
   finishTest();
--- a/dom/indexedDB/test/unit/test_indexes.js
+++ b/dom/indexedDB/test/unit/test_indexes.js
@@ -183,17 +183,17 @@ function testSteps()
 
   is(keyIndex, objectStoreData.length - 1, "Saw all the expected keys");
 
   // Check that the name index enforces its unique constraint.
   objectStore = db.transaction(objectStoreName, "readwrite")
                   .objectStore(objectStoreName);
   request = objectStore.add({ name: "Bob", height: 62, weight: 170 },
                             "237-23-7738");
-  request.onerror = new ExpectError("ConstraintError", true);
+  request.addEventListener("error", new ExpectError("ConstraintError", true));
   request.onsuccess = unexpectedSuccessHandler;
   event = yield;
 
   ok(true, "Test group 3");
 
   keyIndex = objectStoreDataNameSort.length - 1;
 
   request = objectStore.index("name").openKeyCursor(null, "prev");
--- a/dom/indexedDB/test/unit/test_key_requirements.js
+++ b/dom/indexedDB/test/unit/test_key_requirements.js
@@ -172,17 +172,17 @@ function testSteps()
   request = objectStore.put({id:10});
   request.onerror = errorHandler;
   request.onsuccess = grabEventAndContinueHandler;
   event = yield;
 
   is(event.target.result, key1, "put gave back the same key");
 
   request = objectStore.add({id:10});
-  request.onerror = new ExpectError("ConstraintError", true);
+  request.addEventListener("error", new ExpectError("ConstraintError", true));
   request.onsuccess = unexpectedSuccessHandler;
   event = yield;
 
   try {
     objectStore.add({}, null);
     ok(false, "add with null key should throw!");
   }
   catch (e) {
--- a/dom/indexedDB/test/unit/test_keys.js
+++ b/dom/indexedDB/test/unit/test_keys.js
@@ -171,24 +171,24 @@ function testSteps()
       ok(compareKeys(e.target.result, keyI),
          "Returned key should actually be equal");
     };
     
     // Test that -0 compares the same as 0
     if (keyI === 0) {
       doCompare(-0);
       let req = store.add(i, -0);
-      req.onerror = new ExpectError("ConstraintError", true);
+      req.addEventListener("error", new ExpectError("ConstraintError", true));
       req.onsuccess = unexpectedSuccessHandler;
       yield;
     }
     else if (Array.isArray(keyI) && keyI.length === 1 && keyI[0] === 0) {
       doCompare([-0]);
       let req = store.add(i, [-0]);
-      req.onerror = new ExpectError("ConstraintError", true);
+      req.addEventListener("error", new ExpectError("ConstraintError", true));
       req.onsuccess = unexpectedSuccessHandler;
       yield;
     }
   }
 
   store.openCursor().onsuccess = grabEventAndContinueHandler;
   for (i = 0; i < keys.length; ++i) {
     event = yield;
--- a/dom/indexedDB/test/unit/test_traffic_jam.js
+++ b/dom/indexedDB/test/unit/test_traffic_jam.js
@@ -64,17 +64,18 @@ function testSteps()
 
   requests[2].onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   is(event.type, "success", "expect a success event");
   is(event.target, requests[2], "fired at the right request");
   event.target.result.close();
 
-  requests[3].onerror = new ExpectError("VersionError", true);
+  requests[3].onerror = null;
+  requests[3].addEventListener("error", new ExpectError("VersionError", true));
 
   event = yield;
 
   requests[4].onsuccess = grabEventAndContinueHandler;
 
   event = yield;
   is(event.type, "success", "expect a success event");
   is(event.target, requests[4], "fired at the right request");
--- a/dom/interfaces/base/nsIDOMScreen.idl
+++ b/dom/interfaces/base/nsIDOMScreen.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
-[scriptable, builtinclass, uuid(9b978f58-5bfe-409d-aa3f-946ca934e51d)]
+[scriptable, builtinclass, uuid(5a8294df-ffe4-48e5-803f-f57bebc29289)]
 interface nsIDOMScreen : nsIDOMEventTarget
 {
   readonly attribute long             top;
   readonly attribute long             left;
   readonly attribute long             width;
   readonly attribute long             height;
   readonly attribute long             pixelDepth;
   readonly attribute long             colorDepth;
@@ -21,17 +21,17 @@ interface nsIDOMScreen : nsIDOMEventTarg
 
   /**
    * Returns the current screen orientation.
    * Can be: landscape-primary, landscape-secondary,
    *         portrait-primary or portrait-secondary.
    */
   readonly attribute DOMString       mozOrientation;
 
-  attribute nsIDOMEventListener      onmozorientationchange;
+  [implicit_jscontext] attribute jsval      onmozorientationchange;
 
   /**
    * Lock screen orientation to the specified type.
    */
   boolean mozLockOrientation(in DOMString orientation);
 
   /**
    * Unlock the screen orientation.
--- a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
+++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
@@ -10,20 +10,20 @@ interface nsIDOMDeviceStorageCursor;
 interface nsIDOMDeviceStorageChangeEvent;
 interface nsIDOMEventListener;
 
 dictionary DeviceStorageEnumerationParameters
 {
   jsval since;
 };
 
-[scriptable, uuid(36f3b16b-a398-4b19-944e-ce299b714725), builtinclass]
+[scriptable, uuid(7efbe025-3a8a-4151-9257-3e8c941dc099), builtinclass]
 interface nsIDOMDeviceStorage : nsIDOMEventTarget
 {
-    attribute nsIDOMEventListener onchange;
+    [implicit_jscontext] attribute jsval onchange;
     nsIDOMDOMRequest add(in nsIDOMBlob aBlob);
     nsIDOMDOMRequest addNamed(in nsIDOMBlob aBlob, in DOMString aName);
 
     [implicit_jscontext]
     nsIDOMDOMRequest get(in jsval aName);
 
     [implicit_jscontext]
     nsIDOMDOMRequest getEditable(in jsval aName);
--- a/dom/interfaces/notification/nsIDOMDesktopNotification.idl
+++ b/dom/interfaces/notification/nsIDOMDesktopNotification.idl
@@ -12,16 +12,16 @@ interface nsIDOMDesktopNotification;
 interface nsIDOMDesktopNotificationCenter : nsISupports
 {
   nsIDOMDesktopNotification createNotification(in DOMString title,
                                                in DOMString description,
                                                [optional] in DOMString iconURL);
 };
 
 
-[scriptable, uuid(9131FD07-A7DB-4B3A-A98B-6D9F3746682F)]
+[scriptable, uuid(77bc6adc-77d6-4b29-9844-7eaac25e995d)]
 interface nsIDOMDesktopNotification : nsISupports
 {
   void show();
 
-  attribute nsIDOMEventListener onclick;
-  attribute nsIDOMEventListener onclose;
+  [implicit_jscontext] attribute jsval onclick;
+  [implicit_jscontext] attribute jsval onclose;
 };
--- a/dom/interfaces/offline/nsIDOMOfflineResourceList.idl
+++ b/dom/interfaces/offline/nsIDOMOfflineResourceList.idl
@@ -2,17 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIDOMDOMStringList;
 
-[scriptable, uuid(f394a721-66e9-46fc-bb24-b980bb732dd0)]
+[scriptable, uuid(c105fe6f-5603-40b2-b3d0-84cb51fab9f4)]
 interface nsIDOMOfflineResourceList : nsISupports
 {
   /**
    * Get the list of dynamically-managed entries.
    */
   readonly attribute nsIDOMDOMStringList mozItems;
 
   /**
@@ -87,17 +87,17 @@ interface nsIDOMOfflineResourceList : ns
 
   /**
    * Swap in the newest version of the application cache, or disassociate
    * from the cache if the cache group is obsolete.
    */
   void swapCache();
 
   /* Events */
-  attribute nsIDOMEventListener onchecking;
-  attribute nsIDOMEventListener onerror;
-  attribute nsIDOMEventListener onnoupdate;
-  attribute nsIDOMEventListener ondownloading;
-  attribute nsIDOMEventListener onprogress;
-  attribute nsIDOMEventListener onupdateready;
-  attribute nsIDOMEventListener oncached;
-  attribute nsIDOMEventListener onobsolete;
+  [implicit_jscontext] attribute jsval onchecking;
+  [implicit_jscontext] attribute jsval onerror;
+  [implicit_jscontext] attribute jsval onnoupdate;
+  [implicit_jscontext] attribute jsval ondownloading;
+  [implicit_jscontext] attribute jsval onprogress;
+  [implicit_jscontext] attribute jsval onupdateready;
+  [implicit_jscontext] attribute jsval oncached;
+  [implicit_jscontext] attribute jsval onobsolete;
 };
--- a/dom/network/interfaces/nsIDOMConnection.idl
+++ b/dom/network/interfaces/nsIDOMConnection.idl
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, uuid(8c6b574d-1135-4387-a6e3-6d8ba38d79a1)]
+[scriptable, uuid(a0eb16f3-5fa2-4cbd-bf7a-4ce7704b13ea)]
 interface nsIDOMMozConnection : nsISupports
 {
   readonly attribute double  bandwidth;
   readonly attribute boolean metered;
 
-           attribute nsIDOMEventListener onchange;
+  [implicit_jscontext] attribute jsval onchange;
 };
--- a/dom/network/interfaces/nsIDOMMobileConnection.idl
+++ b/dom/network/interfaces/nsIDOMMobileConnection.idl
@@ -6,17 +6,17 @@
 
 interface nsIDOMEventListener;
 interface nsIDOMDOMRequest;
 interface nsIDOMMozMobileConnectionInfo;
 interface nsIDOMMozMobileNetworkInfo;
 interface nsIDOMMozMobileCellInfo;
 interface nsIDOMMozIccManager;
 
-[scriptable, builtinclass, uuid(46fa4f72-9c81-4b7f-b395-87202966e526)]
+[scriptable, builtinclass, uuid(fda3bb30-3259-4ba7-8cff-c486c30821a4)]
 interface nsIDOMMozMobileConnection : nsIDOMEventTarget
 {
   /**
    * Indicates the state of the device's ICC card.
    *
    * Possible values: null, 'absent', 'pinRequired', 'pukRequired',
    * 'networkLocked', 'ready'.
    */
@@ -203,35 +203,35 @@ interface nsIDOMMozMobileConnection : ns
    * Cancel the current USSD session if one exists.
    */
   nsIDOMDOMRequest cancelUSSD();
 
   /**
    * The 'cardstatechange' event is notified when the 'cardState' attribute
    * changes value.
    */
-  attribute nsIDOMEventListener oncardstatechange;
+  [implicit_jscontext] attribute jsval oncardstatechange;
 
   /**
    * The 'voicechange' event is notified whenever the voice connection object
    * changes.
    */
-  attribute nsIDOMEventListener onvoicechange;
+  [implicit_jscontext] attribute jsval onvoicechange;
 
   /**
    * The 'datachange' event is notified whenever the data connection object
    * changes values.
    */
-  attribute nsIDOMEventListener ondatachange;
+  [implicit_jscontext] attribute jsval ondatachange;
 
   /**
    * The 'ussdreceived' event is notified whenever a new USSD message is
    * received.
    */
-  attribute nsIDOMEventListener onussdreceived;
+  [implicit_jscontext] attribute jsval onussdreceived;
 };
 
 [scriptable, uuid(5ea0e4a9-4684-40da-9930-8ebb61d187f3)]
 interface nsIDOMMozMobileConnectionInfo : nsISupports
 {
   /**
    * State of the connection.
    *
--- a/dom/network/src/Connection.cpp
+++ b/dom/network/src/Connection.cpp
@@ -25,33 +25,33 @@ namespace network {
 
 const char* Connection::sMeteredPrefName     = "dom.network.metered";
 const bool  Connection::sMeteredDefaultValue = false;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Connection)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Connection,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(change)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Connection,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(change)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Connection)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozConnection)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozConnection)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozConnection)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(Connection, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(Connection, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(Connection, change)
+
 Connection::Connection()
   : mCanBeMetered(kDefaultCanBeMetered)
   , mBandwidth(kDefaultBandwidth)
 {
 }
 
 void
 Connection::Init(nsPIDOMWindow* aWindow)
@@ -92,18 +92,16 @@ Connection::GetMetered(bool* aMetered)
     return NS_OK;
   }
 
   *aMetered = Preferences::GetBool(sMeteredPrefName,
                                    sMeteredDefaultValue);
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(Connection, change)
-
 nsresult
 Connection::DispatchTrustedEventToSelf(const nsAString& aEventName)
 {
   nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
   nsresult rv = event->InitEvent(aEventName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = event->SetTrusted(true);
--- a/dom/network/src/Connection.h
+++ b/dom/network/src/Connection.h
@@ -59,18 +59,16 @@ private:
    */
   bool mCanBeMetered;
 
   /**
    * The connection bandwidth.
    */
   double mBandwidth;
 
-  NS_DECL_EVENT_HANDLER(change)
-
   static const char* sMeteredPrefName;
   static const bool  sMeteredDefaultValue;
 };
 
 } // namespace network
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -28,41 +28,38 @@ const char* kVoiceChangedTopic     = "mo
 const char* kDataChangedTopic      = "mobile-connection-data-changed";
 const char* kCardStateChangedTopic = "mobile-connection-cardstate-changed";
 const char* kUssdReceivedTopic     = "mobile-connection-ussd-received";
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(cardstatechange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(voicechange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(datachange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(ussdreceived)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(cardstatechange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(voicechange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(datachange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(ussdreceived)
   tmp->mProvider = nullptr;
   tmp->mIccManager = nullptr;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozMobileConnection)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(MobileConnection, cardstatechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
+NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
+
 MobileConnection::MobileConnection()
 {
   mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
 
   // Not being able to acquire the provider isn't fatal since we check
   // for it explicitly below.
   if (!mProvider) {
     NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
@@ -302,16 +299,11 @@ MobileConnection::InternalDispatchEvent(
 
   bool dummy;
   rv = DispatchEvent(event, &dummy);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(MobileConnection, cardstatechange)
-NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
-NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
-NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
-
 } // namespace network
 } // namespace dom
 } // namespace mozilla
--- a/dom/network/src/MobileConnection.h
+++ b/dom/network/src/MobileConnection.h
@@ -47,20 +47,15 @@ private:
   nsIDOMEventTarget*
   ToIDOMEventTarget() const
   {
     return static_cast<nsDOMEventTargetHelper*>(
            const_cast<MobileConnection*>(this));
   }
 
   nsresult InternalDispatchEvent(const nsAString& aType);
-
-  NS_DECL_EVENT_HANDLER(cardstatechange)
-  NS_DECL_EVENT_HANDLER(voicechange)
-  NS_DECL_EVENT_HANDLER(datachange)
-  NS_DECL_EVENT_HANDLER(ussdreceived)
 };
 
 } // namespace network
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_network_MobileConnection_h
--- a/dom/sms/interfaces/nsIDOMSmsManager.idl
+++ b/dom/sms/interfaces/nsIDOMSmsManager.idl
@@ -3,17 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMMozSmsRequest;
 interface nsIDOMMozSmsFilter;
 
-[scriptable, builtinclass, uuid(6363c0ff-b58f-4fb3-9707-0ba27f120b2c)]
+[scriptable, builtinclass, uuid(be78baf4-20ba-4ceb-be40-d9774a9388c4)]
 interface nsIDOMMozSmsManager : nsIDOMEventTarget
 {
   unsigned short      getNumberOfMessagesForText(in DOMString text);
 
   // The first parameter can be either a DOMString (only one number) or an array
   // of DOMStrings.
   // The method returns a SmsRequest object if one number has been passed.
   // An array of SmsRequest objects otherwise.
@@ -23,12 +23,12 @@ interface nsIDOMMozSmsManager : nsIDOMEv
 
   // The parameter can be either a message id or a SmsMessage.
   nsIDOMMozSmsRequest delete(in jsval param);
 
   nsIDOMMozSmsRequest getMessages(in nsIDOMMozSmsFilter filter, in boolean reverse);
 
   nsIDOMMozSmsRequest markMessageRead(in long id, in boolean aValue);
 
-  attribute nsIDOMEventListener onreceived;
-  attribute nsIDOMEventListener onsent;
-  attribute nsIDOMEventListener ondelivered;
+  [implicit_jscontext] attribute jsval onreceived;
+  [implicit_jscontext] attribute jsval onsent;
+  [implicit_jscontext] attribute jsval ondelivered;
 };
--- a/dom/sms/interfaces/nsIDOMSmsRequest.idl
+++ b/dom/sms/interfaces/nsIDOMSmsRequest.idl
@@ -1,10 +1,10 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMDOMRequest.idl"
 
-[scriptable, builtinclass, uuid(f77caa0f-d957-40b4-b1c6-195ebaace60c)]
+[scriptable, builtinclass, uuid(ae6acad4-3174-44d6-a491-9ff94ab847c2)]
 interface nsIDOMMozSmsRequest : nsIDOMDOMRequest
 {
 };
--- a/dom/sms/src/SmsManager.cpp
+++ b/dom/sms/src/SmsManager.cpp
@@ -34,38 +34,36 @@ DOMCI_DATA(MozSmsManager, mozilla::dom::
 namespace mozilla {
 namespace dom {
 namespace sms {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(SmsManager)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SmsManager,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(received)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(sent)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(delivered)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SmsManager,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(received)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(sent)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(delivered)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SmsManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozSmsManager)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozSmsManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(SmsManager, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(SmsManager, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(SmsManager, received)
+NS_IMPL_EVENT_HANDLER(SmsManager, sent)
+NS_IMPL_EVENT_HANDLER(SmsManager, delivered)
+
 /* static */already_AddRefed<SmsManager>
 SmsManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
 {
   NS_ASSERTION(aWindow, "Null pointer!");
 
   // First of all, the general pref has to be turned on.
   bool enabled = false;
   Preferences::GetBool("dom.sms.enabled", &enabled);
@@ -339,20 +337,16 @@ SmsManager::MarkMessageRead(int32_t aId,
     do_GetService(SMS_DATABASE_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsDBService, NS_ERROR_FAILURE);
 
   smsDBService->MarkMessageRead(aId, aValue, requestId, 0);
 
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(SmsManager, received)
-NS_IMPL_EVENT_HANDLER(SmsManager, sent)
-NS_IMPL_EVENT_HANDLER(SmsManager, delivered)
-
 nsresult
 SmsManager::DispatchTrustedSmsEventToSelf(const nsAString& aEventName, nsIDOMMozSmsMessage* aMessage)
 {
   nsRefPtr<nsDOMEvent> event = new SmsEvent(nullptr, nullptr);
   nsresult rv = static_cast<SmsEvent*>(event.get())->Init(aEventName, false,
                                                           false, aMessage);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/sms/src/SmsManager.h
+++ b/dom/sms/src/SmsManager.h
@@ -45,18 +45,15 @@ private:
 
   /**
    * Internal Delete() method used to delete a message.
    */
   nsresult Delete(int32_t aId, nsIDOMMozSmsRequest** aRequest);
 
   nsresult DispatchTrustedSmsEventToSelf(const nsAString& aEventName,
                                          nsIDOMMozSmsMessage* aMessage);
-  NS_DECL_EVENT_HANDLER(received)
-  NS_DECL_EVENT_HANDLER(sent)
-  NS_DECL_EVENT_HANDLER(delivered)
 };
 
 } // namespace sms
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_sms_SmsManager_h
--- a/dom/sms/src/SmsRequest.cpp
+++ b/dom/sms/src/SmsRequest.cpp
@@ -19,30 +19,26 @@ namespace mozilla {
 namespace dom {
 namespace sms {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(SmsRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SmsRequest,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCursor)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mError)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SmsRequest,
                                                 nsDOMEventTargetHelper)
   if (tmp->mResultRooted) {
     tmp->mResult = JSVAL_VOID;
     tmp->UnrootResult();
   }
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCursor)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(SmsRequest,
                                                nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResult)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
--- a/dom/sms/src/SmsRequest.h
+++ b/dom/sms/src/SmsRequest.h
@@ -84,19 +84,16 @@ private:
    */
   nsIDOMMozSmsCursor* GetCursor();
 
   jsval     mResult;
   bool      mResultRooted;
   bool      mDone;
   nsCOMPtr<nsIDOMDOMError> mError;
   nsCOMPtr<nsIDOMMozSmsCursor> mCursor;
-
-  NS_DECL_EVENT_HANDLER(success)
-  NS_DECL_EVENT_HANDLER(error)
 };
 
 inline nsIDOMMozSmsCursor*
 SmsRequest::GetCursor()
 {
   return mCursor;
 }
 
--- a/dom/src/notification/nsDesktopNotification.cpp
+++ b/dom/src/notification/nsDesktopNotification.cpp
@@ -41,33 +41,32 @@ nsDOMDesktopNotification::PostDesktopNot
                                        EmptyString());
 }
 
 DOMCI_DATA(DesktopNotification, nsDOMDesktopNotification)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDesktopNotification)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnClickCallback)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCloseCallback)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnClickCallback)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCloseCallback)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDesktopNotification)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDesktopNotification)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDesktopNotification)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DesktopNotification)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsDOMDesktopNotification, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsDOMDesktopNotification, click)
+NS_IMPL_EVENT_HANDLER(nsDOMDesktopNotification, close)
+
 nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
                                                    const nsAString & description,
                                                    const nsAString & iconURL,
                                                    nsPIDOMWindow *aWindow,
                                                    nsIPrincipal* principal)
   : mTitle(title)
   , mDescription(description)
   , mIconURL(iconURL)
@@ -176,42 +175,16 @@ nsDOMDesktopNotification::Show()
   mShowHasBeenCalled = true;
 
   if (!mAllow)
     return NS_OK;
 
   return PostDesktopNotification();
 }
 
-NS_IMETHODIMP
-nsDOMDesktopNotification::GetOnclick(nsIDOMEventListener * *aOnclick)
-{
-  return GetInnerEventListener(mOnClickCallback, aOnclick);
-}
-
-NS_IMETHODIMP nsDOMDesktopNotification::SetOnclick(nsIDOMEventListener * aOnclick)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING("click"),
-                                mOnClickCallback,
-                                aOnclick);
-}
-
-NS_IMETHODIMP
-nsDOMDesktopNotification::GetOnclose(nsIDOMEventListener * *aOnclose)
-{
-  return GetInnerEventListener(mOnCloseCallback, aOnclose);
-}
-
-NS_IMETHODIMP nsDOMDesktopNotification::SetOnclose(nsIDOMEventListener * aOnclose)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING("close"),
-                                mOnCloseCallback,
-                                aOnclose);
-}
-
 /* ------------------------------------------------------------------------ */
 /* nsDesktopNotificationCenter                                              */
 /* ------------------------------------------------------------------------ */
 
 DOMCI_DATA(DesktopNotificationCenter, nsDesktopNotificationCenter)
 
 NS_INTERFACE_MAP_BEGIN(nsDesktopNotificationCenter)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDesktopNotificationCenter)
--- a/dom/src/notification/nsDesktopNotification.h
+++ b/dom/src/notification/nsDesktopNotification.h
@@ -99,19 +99,16 @@ public:
   void HandleAlertServiceNotification(const char *aTopic);
 
 protected:
 
   nsString mTitle;
   nsString mDescription;
   nsString mIconURL;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnClickCallback;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnCloseCallback;
-
   nsRefPtr<AlertServiceObserver> mObserver;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   bool mAllow;
   bool mShowHasBeenCalled;
 };
 
 /*
  * Simple Request
--- a/dom/src/offline/nsDOMOfflineResourceList.cpp
+++ b/dom/src/offline/nsDOMOfflineResourceList.cpp
@@ -54,42 +54,24 @@ static const char kMaxEntriesPref[] =  "
 //
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMOfflineResourceList)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMOfflineResourceList,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCacheUpdate)
 
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCheckingListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnNoUpdateListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnDownloadingListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCachedListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnUpdateReadyListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnObsoleteListener)
-
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPendingEvents);
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMOfflineResourceList,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCacheUpdate)
 
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCheckingListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnNoUpdateListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnDownloadingListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCachedListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUpdateReadyListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnObsoleteListener)
-
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPendingEvents)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(OfflineResourceList, nsDOMOfflineResourceList)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMOfflineResourceList)
   NS_INTERFACE_MAP_ENTRY(nsIDOMOfflineResourceList)
@@ -97,16 +79,25 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(OfflineResourceList)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsDOMOfflineResourceList, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsDOMOfflineResourceList, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, checking)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, error)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, noupdate)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, downloading)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, progress)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, cached)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, updateready)
+NS_IMPL_EVENT_HANDLER(nsDOMOfflineResourceList, obsolete)
+
 nsDOMOfflineResourceList::nsDOMOfflineResourceList(nsIURI *aManifestURI,
                                                    nsIURI *aDocumentURI,
                                                    nsPIDOMWindow *aWindow)
   : mInitialized(false)
   , mManifestURI(aManifestURI)
   , mDocumentURI(aDocumentURI)
   , mExposeCacheUpdateStatus(true)
   , mStatus(nsIDOMOfflineResourceList::IDLE)
@@ -183,25 +174,16 @@ nsDOMOfflineResourceList::Init()
   mInitialized = true;
 
   return NS_OK;
 }
 
 void
 nsDOMOfflineResourceList::Disconnect()
 {
-  mOnCheckingListener = nullptr;
-  mOnErrorListener = nullptr;
-  mOnNoUpdateListener = nullptr;
-  mOnDownloadingListener = nullptr;
-  mOnProgressListener = nullptr;
-  mOnCachedListener = nullptr;
-  mOnUpdateReadyListener = nullptr;
-  mOnObsoleteListener = nullptr;
-
   mPendingEvents.Clear();
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nullptr;
   }
 }
 
@@ -529,121 +511,16 @@ nsDOMOfflineResourceList::SwapCache()
 
   return NS_OK;
 }
 
 //
 // nsDOMOfflineResourceList::nsIDOMEventTarget
 //
 
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnchecking(nsIDOMEventListener **aOnchecking)
-{
-  return GetInnerEventListener(mOnCheckingListener, aOnchecking);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnchecking(nsIDOMEventListener *aOnchecking)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(CHECKING_STR),
-                                mOnCheckingListener, aOnchecking);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnerror(nsIDOMEventListener **aOnerror)
-{
-  return GetInnerEventListener(mOnErrorListener, aOnerror);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnerror(nsIDOMEventListener *aOnerror)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_STR), mOnErrorListener,
-                                aOnerror);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnnoupdate(nsIDOMEventListener **aOnnoupdate)
-{
-  return GetInnerEventListener(mOnNoUpdateListener, aOnnoupdate);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnnoupdate(nsIDOMEventListener *aOnnoupdate)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(NOUPDATE_STR),
-                                mOnNoUpdateListener, aOnnoupdate);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOndownloading(nsIDOMEventListener **aOndownloading)
-{
-  return GetInnerEventListener(mOnDownloadingListener, aOndownloading);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOndownloading(nsIDOMEventListener *aOndownloading)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(DOWNLOADING_STR),
-                                mOnDownloadingListener, aOndownloading);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnprogress(nsIDOMEventListener **aOnprogress)
-{
-  return GetInnerEventListener(mOnProgressListener, aOnprogress);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnprogress(nsIDOMEventListener *aOnprogress)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(PROGRESS_STR),
-                                mOnProgressListener, aOnprogress);
-}
-
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnupdateready(nsIDOMEventListener **aOnupdateready)
-{
-  return GetInnerEventListener(mOnUpdateReadyListener, aOnupdateready);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOncached(nsIDOMEventListener *aOncached)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(CACHED_STR),
-                                mOnCachedListener, aOncached);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOncached(nsIDOMEventListener **aOncached)
-{
-  return GetInnerEventListener(mOnCachedListener, aOncached);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnupdateready(nsIDOMEventListener *aOnupdateready)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(UPDATEREADY_STR),
-                                mOnUpdateReadyListener, aOnupdateready);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::GetOnobsolete(nsIDOMEventListener **aOnobsolete)
-{
-  return GetInnerEventListener(mOnObsoleteListener, aOnobsolete);
-}
-
-NS_IMETHODIMP
-nsDOMOfflineResourceList::SetOnobsolete(nsIDOMEventListener *aOnobsolete)
-{
-  return RemoveAddEventListener(NS_LITERAL_STRING(OBSOLETE_STR),
-                                mOnObsoleteListener, aOnobsolete);
-}
-
 void
 nsDOMOfflineResourceList::FirePendingEvents()
 {
   for (int32_t i = 0; i < mPendingEvents.Count(); ++i) {
     bool dummy;
     nsCOMPtr<nsIDOMEvent> event = mPendingEvents[i];
     DispatchEvent(event, &dummy);
   }
--- a/dom/src/offline/nsDOMOfflineResourceList.h
+++ b/dom/src/offline/nsDOMOfflineResourceList.h
@@ -80,21 +80,12 @@ private:
   nsCOMPtr<nsIOfflineCacheUpdate> mCacheUpdate;
   bool mExposeCacheUpdateStatus;
   uint16_t mStatus;
 
   // The set of dynamic keys for this application cache object.
   char **mCachedKeys;
   uint32_t mCachedKeysCount;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnCheckingListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnNoUpdateListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnDownloadingListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnCachedListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnUpdateReadyListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnObsoleteListener;
-
   nsCOMArray<nsIDOMEvent> mPendingEvents;
 };
 
 #endif
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -217,33 +217,29 @@ Telephony::DialInternal(bool isEmergency
   return NS_OK;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Telephony)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(incoming)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(callschanged)
   for (uint32_t index = 0; index < tmp->mCalls.Length(); index++) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCalls[i]");
     cb.NoteXPCOMChild(tmp->mCalls[index]->ToISupports());
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(Telephony,
                                                nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallsArray)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(incoming)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(callschanged)
   tmp->mCalls.Clear();
   tmp->mActiveCall = nullptr;
   tmp->mCallsArray = nullptr;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Telephony)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTelephony)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Telephony)
--- a/dom/telephony/Telephony.h
+++ b/dom/telephony/Telephony.h
@@ -19,19 +19,16 @@ class nsPIDOMWindow;
 BEGIN_TELEPHONY_NAMESPACE
 
 class Telephony : public nsDOMEventTargetHelper,
                   public nsIDOMTelephony
 {
   nsCOMPtr<nsIRILContentHelper> mRIL;
   nsCOMPtr<nsIRILTelephonyCallback> mRILTelephonyCallback;
 
-  NS_DECL_EVENT_HANDLER(incoming)
-  NS_DECL_EVENT_HANDLER(callschanged)
-
   TelephonyCall* mActiveCall;
   nsTArray<nsRefPtr<TelephonyCall> > mCalls;
 
   // Cached calls array object. Cleared whenever mCalls changes and then rebuilt
   // once a page looks for the liveCalls attribute.
   JSObject* mCallsArray;
 
   bool mRooted;
--- a/dom/telephony/TelephonyCall.cpp
+++ b/dom/telephony/TelephonyCall.cpp
@@ -141,45 +141,21 @@ TelephonyCall::NotifyError(const nsAStri
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(TelephonyCall)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCall,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mTelephony->ToISupports(),
                                                Telephony, "mTelephony")
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(statechange)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(dialing)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(alerting)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(busy)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(connecting)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(connected)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(disconnecting)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(disconnected)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(holding)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(held)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(resuming)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCall,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTelephony)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(statechange)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(dialing)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(alerting)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(busy)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(connecting)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(connected)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(disconnecting)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(disconnected)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(holding)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(held)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(resuming)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTelephonyCall)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TelephonyCall)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(TelephonyCall, nsDOMEventTargetHelper)
--- a/dom/telephony/TelephonyCall.h
+++ b/dom/telephony/TelephonyCall.h
@@ -14,29 +14,16 @@
 
 class nsPIDOMWindow;
 
 BEGIN_TELEPHONY_NAMESPACE
 
 class TelephonyCall : public nsDOMEventTargetHelper,
                       public nsIDOMTelephonyCall
 {
-  NS_DECL_EVENT_HANDLER(statechange)
-  NS_DECL_EVENT_HANDLER(dialing)
-  NS_DECL_EVENT_HANDLER(alerting)
-  NS_DECL_EVENT_HANDLER(busy)
-  NS_DECL_EVENT_HANDLER(connecting)
-  NS_DECL_EVENT_HANDLER(connected)
-  NS_DECL_EVENT_HANDLER(disconnecting)
-  NS_DECL_EVENT_HANDLER(disconnected)
-  NS_DECL_EVENT_HANDLER(holding)
-  NS_DECL_EVENT_HANDLER(held)
-  NS_DECL_EVENT_HANDLER(resuming)
-  NS_DECL_EVENT_HANDLER(error)
-
   nsRefPtr<Telephony> mTelephony;
 
   nsString mNumber;
   nsString mState;
   nsCOMPtr<nsIDOMDOMError> mError;
 
   uint32_t mCallIndex;
   uint16_t mCallState;
--- a/dom/telephony/Voicemail.cpp
+++ b/dom/telephony/Voicemail.cpp
@@ -18,22 +18,20 @@
 DOMCI_DATA(MozVoicemail, mozilla::dom::telephony::Voicemail)
 
 USING_TELEPHONY_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(Voicemail)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Voicemail,
                                                   nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(statuschanged)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Voicemail,
                                                 nsDOMEventTargetHelper)
-  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(statuschanged)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Voicemail)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozVoicemail)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozVoicemail)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(Voicemail, nsDOMEventTargetHelper)
--- a/dom/telephony/Voicemail.h
+++ b/dom/telephony/Voicemail.h
@@ -33,18 +33,16 @@ public:
 
   Voicemail(nsPIDOMWindow* aWindow, nsIRILContentHelper* aRIL);
   virtual ~Voicemail();
 
 private:
   nsCOMPtr<nsIRILContentHelper> mRIL;
   nsCOMPtr<nsIRILVoicemailCallback> mRILVoicemailCallback;
 
-  NS_DECL_EVENT_HANDLER(statuschanged)
-
   class RILVoicemailCallback : public nsIRILVoicemailCallback
   {
     Voicemail* mVoicemail;
 
   public:
     NS_DECL_ISUPPORTS
     NS_FORWARD_NSIRILVOICEMAILCALLBACK(mVoicemail->)
 
--- a/dom/telephony/nsIDOMTelephony.idl
+++ b/dom/telephony/nsIDOMTelephony.idl
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMTelephonyCall;
 
-[scriptable, builtinclass, uuid(b3875982-7327-478f-98a2-54cc2de36d7d)]
+[scriptable, builtinclass, uuid(ec253100-630d-4366-ac77-b67525167960)]
 interface nsIDOMTelephony : nsIDOMEventTarget
 {
   nsIDOMTelephonyCall dial(in DOMString number);
   nsIDOMTelephonyCall dialEmergency(in DOMString number);
 
   attribute boolean muted;
   attribute boolean speakerEnabled;
 
@@ -23,11 +23,11 @@ interface nsIDOMTelephony : nsIDOMEventT
   readonly attribute jsval active;
 
   // Array of all calls that are currently connected.
   readonly attribute jsval calls;
 
   void startTone(in DOMString tone);
   void stopTone();
 
-  attribute nsIDOMEventListener onincoming;
-  attribute nsIDOMEventListener oncallschanged;
+  [implicit_jscontext] attribute jsval onincoming;
+  [implicit_jscontext] attribute jsval oncallschanged;
 };
--- a/dom/telephony/nsIDOMTelephonyCall.idl
+++ b/dom/telephony/nsIDOMTelephonyCall.idl
@@ -4,37 +4,37 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 #include "nsIDOMDOMError.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, builtinclass, uuid(d902afb1-2e1d-412e-bfa3-cb6a9453a4db)]
+[scriptable, builtinclass, uuid(0662d161-6df7-41fc-a044-0ab0c668680c)]
 interface nsIDOMTelephonyCall : nsIDOMEventTarget
 {
   readonly attribute DOMString number;
 
   readonly attribute DOMString state;
 
   readonly attribute nsIDOMDOMError error;
 
   void answer();
   void hangUp();
   void hold();
   void resume();
 
-  attribute nsIDOMEventListener onstatechange;
+  [implicit_jscontext] attribute jsval onstatechange;
 
-  attribute nsIDOMEventListener ondialing;
-  attribute nsIDOMEventListener onalerting;
-  attribute nsIDOMEventListener onbusy;
-  attribute nsIDOMEventListener onconnecting;
-  attribute nsIDOMEventListener onconnected;
-  attribute nsIDOMEventListener ondisconnecting;
-  attribute nsIDOMEventListener ondisconnected;
-  attribute nsIDOMEventListener onholding;
-  attribute nsIDOMEventListener onheld;
-  attribute nsIDOMEventListener onresuming;
+  [implicit_jscontext] attribute jsval ondialing;
+  [implicit_jscontext] attribute jsval onalerting;
+  [implicit_jscontext] attribute jsval onbusy;
+  [implicit_jscontext] attribute jsval onconnecting;
+  [implicit_jscontext] attribute jsval onconnected;
+  [implicit_jscontext] attribute jsval ondisconnecting;
+  [implicit_jscontext] attribute jsval ondisconnected;
+  [implicit_jscontext] attribute jsval onholding;
+  [implicit_jscontext] attribute jsval onheld;
+  [implicit_jscontext] attribute jsval onresuming;
 
-  attribute nsIDOMEventListener onerror;
+  [implicit_jscontext] attribute jsval onerror;
 };
--- a/dom/telephony/nsIDOMVoicemail.idl
+++ b/dom/telephony/nsIDOMVoicemail.idl
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMMozVoicemailStatus;
 
-[scriptable, builtinclass, uuid(d9042fb9-a4a6-4133-b2de-8f7aa08595d9)]
+[scriptable, builtinclass, uuid(c343eb25-9dc8-49a8-a70f-58a0337b3f6e)]
 interface nsIDOMMozVoicemail : nsIDOMEventTarget
 {
   /**
    * The current voicemail status, or null when the status is unknown
    */
   readonly attribute nsIDOMMozVoicemailStatus status;
 
   /**
@@ -25,10 +25,10 @@ interface nsIDOMMozVoicemail : nsIDOMEve
    * The display name of the voicemail box dialing number, or null if one
    * wasn't found
    */
   readonly attribute DOMString displayName;
 
   /**
    * The current voicemail status has changed
    */
-  attribute nsIDOMEventListener onstatuschanged;
+  [implicit_jscontext] attribute jsval onstatuschanged;
 };
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -1423,16 +1423,20 @@ nsXPConnect::GetNativeOfWrapper(JSContex
         // FIXME: Provide a fast non-refcounting way to get the canonical
         //        nsISupports from the proxy.
         nsISupports *supports =
             static_cast<nsISupports*>(js::GetProxyPrivate(aJSObj).toPrivate());
         nsCOMPtr<nsISupports> canonical = do_QueryInterface(supports);
         return canonical.get();
     }
 
+    nsISupports* supports = nullptr;
+    if (mozilla::dom::UnwrapDOMObjectToISupports(aJSObj, supports))
+        return supports;
+
     return nullptr;
 }
 
 /* JSObjectPtr getJSObjectOfWrapper (in JSContextPtr aJSContext, in JSObjectPtr aJSObj); */
 NS_IMETHODIMP
 nsXPConnect::GetJSObjectOfWrapper(JSContext * aJSContext,
                                   JSObject * aJSObj,
                                   JSObject **_retval)