Bug 792808 - Migrate nsXMLParseEndListener away from nsIXMLHttpRequest interfaces; r?baku
MozReview-Commit-ID: 14Lxuj37GdJ
--- 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