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 110823 0a1f4d81635adf13c29c71aa80d4e44198125119
parent 110822 9baa8a16f944ba4b8bfa4656cf645819e87fc7b3
child 110824 e3f700f4d0cb300c911ace391bf73454491887b6
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, bz
bugs687332
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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)