Bug 792808 - Migrate nsXMLParseEndListener away from nsIXMLHttpRequest interfaces; r?baku draft
authorThomas Wisniewski <wisniewskit@gmail.com>
Mon, 25 Sep 2017 22:20:26 -0400
changeset 756155 10fcf1fad7be452131464889200b2f02234c7ecf
parent 756154 ee31f87578ac8b1dc65ac3479a1ed70471095b2b
child 756156 6fb735da6d0786248f76a2e23299fe3e80f79156
push id99394
push userwisniewskit@gmail.com
push dateFri, 16 Feb 2018 14:37:01 +0000
reviewersbaku
bugs792808
milestone60.0a1
Bug 792808 - Migrate nsXMLParseEndListener away from nsIXMLHttpRequest interfaces; r?baku MozReview-Commit-ID: 14Lxuj37GdJ
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -230,16 +230,18 @@ XMLHttpRequestMainThread::~XMLHttpReques
 {
   mFlagDeleted = true;
 
   if ((mState == State::opened && mFlagSend) ||
       mState == State::loading) {
     Abort();
   }
 
+  mParseEndListener = nullptr;
+
   MOZ_ASSERT(!mFlagSyncLooping, "we rather crash than hang");
   mFlagSyncLooping = false;
 
   mResultJSON.setUndefined();
   mResultArrayBuffer = nullptr;
   mozilla::DropJSObjects(this);
 }
 
@@ -402,17 +404,16 @@ XMLHttpRequestMainThread::IsCertainlyAli
 // QueryInterface implementation for XMLHttpRequestMainThread
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XMLHttpRequestMainThread)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
   NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
-  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsINamed)
   NS_INTERFACE_MAP_ENTRY(nsISizeOfEventTarget)
 NS_INTERFACE_MAP_END_INHERITING(XMLHttpRequestEventTarget)
 
 NS_IMPL_ADDREF_INHERITED(XMLHttpRequestMainThread, XMLHttpRequestEventTarget)
 NS_IMPL_RELEASE_INHERITED(XMLHttpRequestMainThread, XMLHttpRequestEventTarget)
 
@@ -2367,20 +2368,21 @@ XMLHttpRequestMainThread::OnStopRequest(
     }
 
     return NS_OK;
   }
 
   if (mIsHtml) {
     NS_ASSERTION(!mFlagSyncLooping,
       "We weren't supposed to support HTML parsing with XHR!");
+    mParseEndListener = new nsXHRParseEndListener(this);
     nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(mResponseXML);
     EventListenerManager* manager =
       eventTarget->GetOrCreateListenerManager();
-    manager->AddEventListenerByType(new nsXHRParseEndListener(this),
+    manager->AddEventListenerByType(mParseEndListener,
                                     kLiteralString_DOMContentLoaded,
                                     TrustedEventsAtSystemGroupBubble());
     return NS_OK;
   } else {
     mFlagParseBody = false;
   }
 
   // We might have been sent non-XML data. If that was the case,
@@ -2394,16 +2396,17 @@ XMLHttpRequestMainThread::OnStopRequest(
   ChangeStateToDone();
   return NS_OK;
 }
 
 void
 XMLHttpRequestMainThread::OnBodyParseEnd()
 {
   mFlagParseBody = false;
+  mParseEndListener = nullptr;
   ChangeStateToDone();
 }
 
 void
 XMLHttpRequestMainThread::MatchCharsetAndDecoderToResponseDocument()
 {
   if (mResponseXML && mResponseCharset != mResponseXML->GetDocumentCharacterSet()) {
     mResponseCharset = mResponseXML->GetDocumentCharacterSet();
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -10,17 +10,16 @@
 #include <bitset>
 #include "nsAutoPtr.h"
 #include "nsIXMLHttpRequest.h"
 #include "nsISupportsUtils.h"
 #include "nsIURI.h"
 #include "nsIHttpChannel.h"
 #include "nsIDocument.h"
 #include "nsIStreamListener.h"
-#include "nsWeakReference.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsIProgressEventSink.h"
 #include "nsJSUtils.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
@@ -153,25 +152,26 @@ public:
   void Set(const nsACString& aName, const nsACString& aValue);
   void MergeOrSet(const char* aName, const nsACString& aValue);
   void MergeOrSet(const nsACString& aName, const nsACString& aValue);
   void Clear();
   void ApplyToChannel(nsIHttpChannel* aChannel) const;
   void GetCORSUnsafeHeaders(nsTArray<nsCString>& aArray) const;
 };
 
+class nsXHRParseEndListener;
+
 // Make sure that any non-DOM interfaces added here are also added to
 // nsXMLHttpRequestXPCOMifier.
 class XMLHttpRequestMainThread final : public XMLHttpRequest,
                                        public nsIXMLHttpRequest,
                                        public nsIStreamListener,
                                        public nsIChannelEventSink,
                                        public nsIProgressEventSink,
                                        public nsIInterfaceRequestor,
-                                       public nsSupportsWeakReference,
                                        public nsITimerCallback,
                                        public nsISizeOfEventTarget,
                                        public nsINamed,
                                        public MutableBlobStorageCallback
 {
   friend class nsXHRParseEndListener;
   friend class nsXMLHttpRequestXPCOMifier;
 
@@ -812,16 +812,19 @@ protected:
 
   // Helper object to manage our XPCOM scriptability bits
   nsXMLHttpRequestXPCOMifier* mXPCOMifier;
 
   // When this is set to true, the event dispatching is suspended. This is
   // useful to change the correct state when XHR is working sync.
   bool mEventDispatchingSuspended;
 
+  // Our parse-end listener, if we are parsing.
+  RefPtr<nsXHRParseEndListener> mParseEndListener;
+
   static bool sDontWarnAboutSyncXHR;
 };
 
 class MOZ_STACK_CLASS AutoDontWarnAboutSyncXHR
 {
 public:
   AutoDontWarnAboutSyncXHR() : mOldVal(XMLHttpRequestMainThread::DontWarnAboutSyncXHR())
   {
@@ -879,27 +882,26 @@ private:
 };
 
 class nsXHRParseEndListener : public nsIDOMEventListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_IMETHOD HandleEvent(nsIDOMEvent *event) override
   {
-    nsCOMPtr<nsIXMLHttpRequest> xhr = do_QueryReferent(mXHR);
-    if (xhr) {
-      static_cast<XMLHttpRequestMainThread*>(xhr.get())->OnBodyParseEnd();
+    if (mXHR) {
+      mXHR->OnBodyParseEnd();
     }
     mXHR = nullptr;
     return NS_OK;
   }
-  explicit nsXHRParseEndListener(nsIXMLHttpRequest* aXHR)
-    : mXHR(do_GetWeakReference(aXHR)) {}
+  explicit nsXHRParseEndListener(XMLHttpRequestMainThread* aXHR)
+    : mXHR(aXHR) {}
 private:
   virtual ~nsXHRParseEndListener() {}
 
-  nsWeakPtr mXHR;
+  XMLHttpRequestMainThread* mXHR;
 };
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_XMLHttpRequestMainThread_h