Merge m-c to m-i.
authorKyle Huey <khuey@kylehuey.com>
Thu, 29 Sep 2011 17:20:21 -0400
changeset 77882 fa844d57e842993c8d3fb94837bcdcc89d254cc8
parent 77881 ba2d3e4cd88a56d679be1577ab907e15cdb6f2d1 (current diff)
parent 77824 60e86b84775943c1a8b473f0138c5fc062d51427 (diff)
child 77883 ce204f8626bcf47e07f9efb47b476f3460bee786
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone10.0a1
Merge m-c to m-i.
--- a/content/base/public/nsDOMEventTargetWrapperCache.h
+++ b/content/base/public/nsDOMEventTargetWrapperCache.h
@@ -89,57 +89,59 @@ public:
   void Init(JSContext* aCx = nsnull);
 
 protected:
   nsDOMEventTargetWrapperCache() : nsDOMEventTargetHelper(), nsWrapperCache() {}
   virtual ~nsDOMEventTargetWrapperCache();
 };
 
 #define NS_DECL_EVENT_HANDLER(_event)                                         \
-  public:                                                                     \
-    NS_IMETHOD GetOn##_event(JSContext *cx, jsval *vp);                       \
-    NS_IMETHOD SetOn##_event(JSContext *cx, const jsval &vp);
+  protected:                                                                  \
+    nsRefPtr<nsDOMEventListenerWrapper> mOn##_event##Listener;                \
+  public:
 
 #define NS_DECL_AND_IMPL_EVENT_HANDLER(_event)                                \
+  protected:                                                                  \
+    nsRefPtr<nsDOMEventListenerWrapper> mOn##_event##Listener;                \
   public:                                                                     \
-    NS_IMPL_EVENT_HANDLER(_class, _event)
+    NS_IMETHOD GetOn##_event(nsIDOMEventListener** a##_event)                 \
+    {                                                                         \
+      return GetInnerEventListener(mOn##_event##Listener, a##_event);         \
+    }                                                                         \
+    NS_IMETHOD SetOn##_event(nsIDOMEventListener* a##_event)                  \
+    {                                                                         \
+      return RemoveAddEventListener(NS_LITERAL_STRING(#_event),               \
+                                    mOn##_event##Listener, a##_event);        \
+    }
 
 #define NS_IMPL_EVENT_HANDLER(_class, _event)                                 \
   NS_IMETHODIMP                                                               \
-  _class::GetOn##_event(JSContext *cx, jsval *vp)                             \
+  _class::GetOn##_event(nsIDOMEventListener** a##_event)                      \
   {                                                                           \
-    nsEventListenerManager* elm = GetListenerManager(PR_FALSE);               \
-    if (elm) {                                                                \
-      elm->GetJSEventListener(nsGkAtoms::on##_event, vp);                     \
-    } else {                                                                  \
-      *vp = JSVAL_NULL;                                                       \
-    }                                                                         \
-    return NS_OK;                                                             \
+    return GetInnerEventListener(mOn##_event##Listener, a##_event);           \
   }                                                                           \
   NS_IMETHODIMP                                                               \
-  _class::SetOn##_event(JSContext *cx, const jsval &vp)                       \
+  _class::SetOn##_event(nsIDOMEventListener* a##_event)                       \
   {                                                                           \
-    nsEventListenerManager* elm = GetListenerManager(PR_TRUE);                \
-    if (!elm) {                                                               \
-      return NS_ERROR_OUT_OF_MEMORY;                                          \
-    }                                                                         \
-                                                                              \
-    JSObject *obj = GetWrapper();                                             \
-    if (!obj) {                                                               \
-      /* Just silently do nothing */                                          \
-      return NS_OK;                                                           \
-    }                                                                         \
-    return elm->SetJSEventListenerToJsval(nsGkAtoms::on##_event, cx, obj, vp);\
+    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(JSContext *cx, jsval *vp)                           \
+    _class::GetOn##_event(nsIDOMEventListener** a##_event)                    \
     {                                                                         \
-      return _baseclass::GetOn##_event(cx, vp);                               \
+      return _baseclass::GetOn##_event(a##_event);                            \
     }                                                                         \
     NS_IMETHODIMP                                                             \
-    _class::SetOn##_event(JSContext *cx, const jsval &vp)                     \
+    _class::SetOn##_event(nsIDOMEventListener* a##_event)                     \
     {                                                                         \
-      return _baseclass::SetOn##_event(cx, vp);                               \
+      return _baseclass::SetOn##_event(a##_event);                            \
     }
 
+#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)
+                                    
+
 #endif  // nsDOMEventTargetWrapperCache_h__
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -36,17 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
 interface nsIDOMFileError;
 
-[scriptable, builtinclass, uuid(57d68e17-85fa-4509-bf71-ffac1b22a174)]
+[scriptable, builtinclass, uuid(fc316500-87c4-411e-ab75-dd62468f4174)]
 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);
 
@@ -56,22 +56,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 nsIDOMFileError error;
 
-  [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;
+  attribute nsIDOMEventListener onloadstart;
+  attribute nsIDOMEventListener onprogress;
+  attribute nsIDOMEventListener onload;
+  attribute nsIDOMEventListener onabort;
+  attribute nsIDOMEventListener onerror;
+  attribute nsIDOMEventListener 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
@@ -46,31 +46,31 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMEventListener;
 interface nsIPrincipal;
 interface nsIScriptContext;
 interface nsPIDOMWindow;
 
-[scriptable, uuid(741374e9-39ed-4712-a380-93e023b271f8)]
+[scriptable, uuid(755e2d2d-a836-4539-83f4-16b51156341f)]
 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;
 
   // event handler attributes
-  [implicit_jscontext] attribute jsval onopen;
-  [implicit_jscontext] attribute jsval onmessage;
-  [implicit_jscontext] attribute jsval onerror;
+  attribute nsIDOMEventListener onopen;
+  attribute nsIDOMEventListener onmessage;
+  attribute nsIDOMEventListener 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/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -48,28 +48,28 @@ interface nsPIDOMWindow;
 interface nsIInputStream;
 interface nsIDOMBlob;
 
 %{C++
 // for jsval
 #include "jsapi.h"
 %}
 
-[scriptable, builtinclass, uuid(8bc1357c-fe70-4741-a170-8fa50b6d23be)]
+[scriptable, builtinclass, uuid(dea238a1-240f-45f4-9f07-7769bc69eb76)]
 interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
   // event handler attributes
-  [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 onloadend;
+  attribute nsIDOMEventListener onabort;
+  attribute nsIDOMEventListener onerror;
+  attribute nsIDOMEventListener onload;
+  attribute nsIDOMEventListener onloadstart;
+  attribute nsIDOMEventListener onprogress;
+  attribute nsIDOMEventListener onloadend;
 };
 
-[scriptable, builtinclass, uuid(cfa2d9fc-1871-444c-aaf9-8fc7fc7261d8)]
+[scriptable, builtinclass, uuid(09ff3682-7759-4441-a765-f70e1a1fabcf)]
 interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
   // for future use
 };
 
 /**
  * Mozilla's XMLHttpRequest is modelled after Microsoft's IXMLHttpRequest
  * object. The goal has been to make Mozilla's version match Microsoft's
  * version as closely as possible, but there are bound to be some differences.
@@ -105,17 +105,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(10d4701f-6351-4e9b-addd-ffdba05bd425)]
+[scriptable, uuid(5cf8d518-51d0-4cd6-a69a-c3674c2de599)]
 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.
    *
@@ -369,45 +369,45 @@ 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.
    */
-  [implicit_jscontext] attribute jsval onreadystatechange;
+  attribute nsIDOMEventListener onreadystatechange;
 };
 
 [scriptable, uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
 interface nsIXHRSendable : nsISupports {
   void getSendInfo(out nsIInputStream body,
                    out ACString contentType,
                    out ACString charset);
 };
 
 /**
  * @deprecated
  */
-[deprecated, scriptable, uuid(58d2c633-2efd-45be-80ed-511dcd0407cc)]
+[deprecated, scriptable, uuid(423fdd3d-41c9-4149-8fe5-b14a1d3912a0)]
 interface nsIJSXMLHttpRequest : nsISupports {
   /**
    * Meant to be a script-only mechanism for setting an upload progress event
    * listener.
    * This attribute should not be used from native code!!
    * This event listener may be called multiple times during the upload..
    *
    * After the initial response, all event listeners will be cleared.
    * // XXXbz what does that mean, exactly?
    *
    * This event listener must be set BEFORE calling open().
    *
    * Mozilla only.
    */
-  [implicit_jscontext] attribute jsval onuploadprogress;
+  attribute nsIDOMEventListener onuploadprogress;
 };
 
 %{ C++
 #define NS_XMLHTTPREQUEST_CID                       \
  { /* d164e770-4157-11d4-9a42-000064657374 */       \
   0xd164e770, 0x4157, 0x11d4,                       \
  {0x9a, 0x42, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} }
 #define NS_XMLHTTPREQUEST_CONTRACTID \
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -38,17 +38,16 @@
 #include "FileIOObject.h"
 #include "nsDOMFile.h"
 #include "nsDOMError.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsComponentManagerUtils.h"
 #include "nsEventDispatcher.h"
-#include "nsGkAtoms.h"
 #include "xpcprivate.h"
 
 #define ERROR_STR "error"
 #define ABORT_STR "abort"
 #define PROGRESS_STR "progress"
 
 namespace mozilla {
 namespace dom {
@@ -64,27 +63,29 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
                                                   nsDOMEventTargetWrapperCache)
   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_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
                                                 nsDOMEventTargetWrapperCache)
   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_END
 
-NS_IMPL_EVENT_HANDLER(FileIOObject, abort)
-NS_IMPL_EVENT_HANDLER(FileIOObject, error)
-NS_IMPL_EVENT_HANDLER(FileIOObject, progress)
-
 FileIOObject::FileIOObject()
   : mProgressEventWasDelayed(PR_FALSE),
     mTimerIsActive(PR_FALSE),
     mReadyState(0),
     mTotal(0), mTransferred(0)
 {}
 
 FileIOObject::~FileIOObject()
--- a/content/base/src/FileIOObject.h
+++ b/content/base/src/FileIOObject.h
@@ -67,19 +67,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Common methods
   NS_METHOD Abort();
   NS_METHOD GetReadyState(PRUint16* aReadyState);
   NS_METHOD GetError(nsIDOMFileError** aError);
 
-  NS_DECL_EVENT_HANDLER(abort);
-  NS_DECL_EVENT_HANDLER(error);
-  NS_DECL_EVENT_HANDLER(progress);
+  NS_DECL_AND_IMPL_EVENT_HANDLER(abort);
+  NS_DECL_AND_IMPL_EVENT_HANDLER(error);
+  NS_DECL_AND_IMPL_EVENT_HANDLER(progress);
 
   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
@@ -92,23 +92,29 @@ 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_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
+  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 = nsnull;
   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,
                                                nsDOMEventTargetWrapperCache)
   if(tmp->mResultArrayBuffer) {
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mResultArrayBuffer,
                                                "mResultArrayBuffer")
--- a/content/base/src/nsDOMFileReader.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -78,16 +78,20 @@ 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, 
                         PRUint32 argc, jsval* argv);
 
   // nsICharsetDetectionObserver
   NS_IMETHOD Notify(const char *aCharset, nsDetectionConfident aConf);
 
   // FileIOObject overrides
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -109,21 +109,27 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsEventSo
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsEventSource,
                                                   nsDOMEventTargetWrapperCache)
   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, nsDOMEventTargetWrapperCache)
   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)
@@ -152,19 +158,33 @@ nsEventSource::GetUrl(nsAString& aURL)
 NS_IMETHODIMP
 nsEventSource::GetReadyState(PRInt32 *aReadyState)
 {
   NS_ENSURE_ARG_POINTER(aReadyState);
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
-NS_IMPL_EVENT_HANDLER(nsEventSource, open)
-NS_IMPL_EVENT_HANDLER(nsEventSource, error)
-NS_IMPL_EVENT_HANDLER(nsEventSource, message)
+#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;
   }
 
--- a/content/base/src/nsEventSource.h
+++ b/content/base/src/nsEventSource.h
@@ -217,16 +217,20 @@ protected:
   bool mGoingToDispatchAllMessages;
 
   // 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
@@ -1785,19 +1785,17 @@ GK_ATOM(svgRadialGradientFrame, "SVGRadi
 GK_ATOM(svgStopFrame, "SVGStopFrame")
 GK_ATOM(svgSwitchFrame, "SVGSwitchFrame")
 GK_ATOM(svgTextFrame, "SVGTextFrame")
 GK_ATOM(svgTextPathFrame, "SVGTextPathFrame")
 GK_ATOM(svgTSpanFrame, "SVGTSpanFrame")
 GK_ATOM(svgUseFrame, "SVGUseFrame")
 GK_ATOM(HTMLVideoFrame, "VideoFrame")
 GK_ATOM(onloadstart, "onloadstart")
-GK_ATOM(onloadend, "onloadend")
 GK_ATOM(onprogress, "onprogress")
-GK_ATOM(onuploadprogress, "onuploadprogress")
 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")
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -283,40 +283,120 @@ nsMultipartProxyListener::OnDataAvailabl
   return mDestListener->OnDataAvailable(aRequest, ctxt, inStr, sourceOffset,
                                         count);
 }
 
 /////////////////////////////////////////////
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
 
-// nsXHREventTarget's CC participant doesn't actually do anything anymore
-// but these are left here as placeholders in case it needs to do something
-// in the future.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXHREventTarget,
                                                   nsDOMEventTargetWrapperCache)
+  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_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXHREventTarget,
                                                 nsDOMEventTargetWrapperCache)
+  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_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXHREventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(nsXHREventTarget, nsDOMEventTargetWrapperCache)
 NS_IMPL_RELEASE_INHERITED(nsXHREventTarget, nsDOMEventTargetWrapperCache)
 
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, load)
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, error)
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, abort)
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadstart)
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, progress)
-NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadend)
+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);
+}
+
+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);
+}
 
 /////////////////////////////////////////////
 
 nsXMLHttpRequestUpload::~nsXMLHttpRequestUpload()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
@@ -500,16 +580,19 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttp
 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(mOnUploadProgressListener)
+  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
@@ -519,16 +602,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   tmp->mResultArrayBuffer = nsnull;
   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(mOnUploadProgressListener)
+  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
 
@@ -559,18 +645,49 @@ 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)
-NS_IMPL_EVENT_HANDLER(nsXMLHttpRequest, uploadprogress)
+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);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequest::GetOnuploadprogress(nsIDOMEventListener * *aOnuploadprogress)
+{
+  return
+    nsXHREventTarget::GetInnerEventListener(mOnUploadProgressListener,
+                                            aOnuploadprogress);
+}
+
+NS_IMETHODIMP
+nsXMLHttpRequest::SetOnuploadprogress(nsIDOMEventListener * aOnuploadprogress)
+{
+  return
+    nsXHREventTarget::RemoveAddEventListener(NS_LITERAL_STRING(UPLOADPROGRESS_STR),
+                                             mOnUploadProgressListener,
+                                             aOnuploadprogress);
+}
 
 /* readonly attribute nsIChannel channel; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_IF_ADDREF(*aChannel = mChannel);
 
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -75,16 +75,24 @@ class nsXHREventTarget : public nsDOMEve
 {
 public:
   virtual ~nsXHREventTarget() {}
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXHREventTarget,
                                            nsDOMEventTargetWrapperCache)
   NS_DECL_NSIXMLHTTPREQUESTEVENTTARGET
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
+
+protected:
+  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadStartListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnLoadendListener;
 };
 
 class nsXMLHttpRequestUpload : public nsXHREventTarget,
                                public nsIXMLHttpRequestUpload
 {
 public:
   nsXMLHttpRequestUpload(nsPIDOMWindow* aOwner,
                          nsIScriptContext* aScriptContext)
@@ -120,17 +128,18 @@ public:
   virtual ~nsXMLHttpRequest();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIXMLHttpRequest
   NS_DECL_NSIXMLHTTPREQUEST
 
   // nsIJSXMLHttpRequest
-  NS_DECL_NSIJSXMLHTTPREQUEST
+  NS_IMETHOD GetOnuploadprogress(nsIDOMEventListener** aOnuploadprogress);
+  NS_IMETHOD SetOnuploadprogress(nsIDOMEventListener* aOnuploadprogress);
 
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
 
   // nsIStreamListener
   NS_DECL_NSISTREAMLISTENER
 
   // nsIRequestObserver
   NS_DECL_NSIREQUESTOBSERVER
@@ -243,16 +252,19 @@ protected:
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<nsIChannel> mChannel;
   // mReadRequest is different from mChannel for multipart requests
   nsCOMPtr<nsIRequest> mReadRequest;
   nsCOMPtr<nsIDOMDocument> mResponseXML;
   nsCOMPtr<nsIChannel> mCORSPreflightChannel;
   nsTArray<nsCString> mCORSUnsafeHeaders;
 
+  nsRefPtr<nsDOMEventListenerWrapper> mOnUploadProgressListener;
+  nsRefPtr<nsDOMEventListenerWrapper> mOnReadystatechangeListener;
+
   nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
 
   // used to implement getAllResponseHeaders()
   class nsHeaderVisitor : public nsIHttpHeaderVisitor {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIHTTPHEADERVISITOR
     nsHeaderVisitor() { }