Bug 687332: Move inline event listeners on XHR to the event listener manager. r=smaug
authorKyle Huey <khuey@kylehuey.com>
Thu, 29 Sep 2011 12:06:35 -0400
changeset 78450 26f22c7666b3e15a8fb5ba54c96092d3b03c6b19
parent 78449 34b49c378a6baeb5e49fdf5f12a592e241e6280f
child 78451 aa0657195eff0538714357502a8b0cf00c42d668
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs687332
milestone10.0a1
Bug 687332: Move inline event listeners on XHR to the event listener manager. r=smaug
content/base/public/nsIXMLHttpRequest.idl
content/base/src/nsGkAtomList.h
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
--- 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(dea238a1-240f-45f4-9f07-7769bc69eb76)]
+[scriptable, builtinclass, uuid(8bc1357c-fe70-4741-a170-8fa50b6d23be)]
 interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
   // event handler attributes
-  attribute nsIDOMEventListener onabort;
-  attribute nsIDOMEventListener onerror;
-  attribute nsIDOMEventListener onload;
-  attribute nsIDOMEventListener onloadstart;
-  attribute nsIDOMEventListener onprogress;
-  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 onloadend;
 };
 
-[scriptable, builtinclass, uuid(09ff3682-7759-4441-a765-f70e1a1fabcf)]
+[scriptable, builtinclass, uuid(cfa2d9fc-1871-444c-aaf9-8fc7fc7261d8)]
 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(5cf8d518-51d0-4cd6-a69a-c3674c2de599)]
+[scriptable, uuid(10d4701f-6351-4e9b-addd-ffdba05bd425)]
 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.
    */
-  attribute nsIDOMEventListener onreadystatechange;
+  [implicit_jscontext] attribute jsval 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(423fdd3d-41c9-4149-8fe5-b14a1d3912a0)]
+[deprecated, scriptable, uuid(58d2c633-2efd-45be-80ed-511dcd0407cc)]
 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.
    */
-  attribute nsIDOMEventListener onuploadprogress;
+  [implicit_jscontext] attribute jsval 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/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1787,16 +1787,17 @@ 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,120 +283,40 @@ 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_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);
-}
+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)
 
 /////////////////////////////////////////////
 
 nsXMLHttpRequestUpload::~nsXMLHttpRequestUpload()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
@@ -580,19 +500,16 @@ 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
@@ -602,19 +519,16 @@ 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
 
@@ -645,49 +559,18 @@ 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_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);
-}
+NS_IMPL_EVENT_HANDLER(nsXMLHttpRequest, readystatechange)
+NS_IMPL_EVENT_HANDLER(nsXMLHttpRequest, uploadprogress)
 
 /* 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,24 +75,16 @@ 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)
@@ -128,18 +120,17 @@ public:
   virtual ~nsXMLHttpRequest();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIXMLHttpRequest
   NS_DECL_NSIXMLHTTPREQUEST
 
   // nsIJSXMLHttpRequest
-  NS_IMETHOD GetOnuploadprogress(nsIDOMEventListener** aOnuploadprogress);
-  NS_IMETHOD SetOnuploadprogress(nsIDOMEventListener* aOnuploadprogress);
+  NS_DECL_NSIJSXMLHTTPREQUEST
 
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
 
   // nsIStreamListener
   NS_DECL_NSISTREAMLISTENER
 
   // nsIRequestObserver
   NS_DECL_NSIREQUESTOBSERVER
@@ -252,19 +243,16 @@ 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() { }