зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1370819 - Postpone the dispatching of XHR events with opened synchronously, r=smaug
This commit is contained in:
Родитель
c4243d211b
Коммит
9e04e35075
|
@ -201,7 +201,8 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread()
|
|||
mResultJSON(JS::UndefinedValue()),
|
||||
mResultArrayBuffer(nullptr),
|
||||
mIsMappedArrayBuffer(false),
|
||||
mXPCOMifier(nullptr)
|
||||
mXPCOMifier(nullptr),
|
||||
mEventDispatchingSuspended(false)
|
||||
{
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
@ -1368,7 +1369,7 @@ XMLHttpRequestMainThread::FireReadystatechangeEvent()
|
|||
event->InitEvent(kLiteralString_readystatechange, false, false);
|
||||
// We assume anyone who managed to call CreateReadystatechangeEvent is trusted
|
||||
event->SetTrusted(true);
|
||||
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
DispatchOrStoreEvent(this, event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1411,7 +1412,7 @@ XMLHttpRequestMainThread::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
|
|||
ProgressEvent::Constructor(aTarget, typeString, init);
|
||||
event->SetTrusted(true);
|
||||
|
||||
aTarget->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
||||
DispatchOrStoreEvent(aTarget, event);
|
||||
|
||||
if (aType == ProgressEventType::progress) {
|
||||
mInLoadProgressEvent = false;
|
||||
|
@ -1434,6 +1435,45 @@ XMLHttpRequestMainThread::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
XMLHttpRequestMainThread::DispatchOrStoreEvent(DOMEventTargetHelper* aTarget,
|
||||
Event* aEvent)
|
||||
{
|
||||
MOZ_ASSERT(aTarget);
|
||||
MOZ_ASSERT(aEvent);
|
||||
|
||||
if (mEventDispatchingSuspended) {
|
||||
PendingEvent* event = mPendingEvents.AppendElement();
|
||||
event->mTarget = aTarget;
|
||||
event->mEvent = aEvent;
|
||||
return;
|
||||
}
|
||||
|
||||
aTarget->DispatchDOMEvent(nullptr, aEvent, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
XMLHttpRequestMainThread::SuspendEventDispatching()
|
||||
{
|
||||
MOZ_ASSERT(!mEventDispatchingSuspended);
|
||||
mEventDispatchingSuspended = true;
|
||||
}
|
||||
|
||||
void
|
||||
XMLHttpRequestMainThread::ResumeEventDispatching()
|
||||
{
|
||||
MOZ_ASSERT(mEventDispatchingSuspended);
|
||||
mEventDispatchingSuspended = false;
|
||||
|
||||
nsTArray<PendingEvent> pendingEvents;
|
||||
pendingEvents.SwapElements(mPendingEvents);
|
||||
|
||||
for (uint32_t i = 0; i < pendingEvents.Length(); ++i) {
|
||||
pendingEvents[i].mTarget->
|
||||
DispatchDOMEvent(nullptr, pendingEvents[i].mEvent, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIHttpChannel>
|
||||
XMLHttpRequestMainThread::GetCurrentHttpChannel()
|
||||
{
|
||||
|
@ -2409,10 +2449,6 @@ XMLHttpRequestMainThread::ChangeStateToDone()
|
|||
mTimeoutTimer->Cancel();
|
||||
}
|
||||
|
||||
if (mFlagSynchronous) {
|
||||
UnsuppressEventHandlingAndResume();
|
||||
}
|
||||
|
||||
// Per spec, fire the last download progress event, if any,
|
||||
// before readystatechange=4/done. (Note that 0-sized responses
|
||||
// will have not sent a progress event yet, so one must be sent here).
|
||||
|
@ -3033,6 +3069,7 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
|
|||
}
|
||||
}
|
||||
|
||||
SuspendEventDispatching();
|
||||
StopProgressEventTimer();
|
||||
|
||||
SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
|
||||
|
@ -3056,6 +3093,7 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
|
|||
}
|
||||
|
||||
UnsuppressEventHandlingAndResume();
|
||||
ResumeEventDispatching();
|
||||
} else {
|
||||
// Now that we've successfully opened the channel, we can change state. Note
|
||||
// that this needs to come after the AsyncOpen() and rv check, because this
|
||||
|
|
|
@ -401,7 +401,8 @@ public:
|
|||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
Abort() {
|
||||
Abort()
|
||||
{
|
||||
ErrorResult rv;
|
||||
Abort(rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
@ -607,8 +608,21 @@ protected:
|
|||
|
||||
nsresult DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable);
|
||||
|
||||
void DispatchOrStoreEvent(DOMEventTargetHelper* aTarget, Event* aEvent);
|
||||
|
||||
already_AddRefed<nsXMLHttpRequestXPCOMifier> EnsureXPCOMifier();
|
||||
|
||||
void SuspendEventDispatching();
|
||||
void ResumeEventDispatching();
|
||||
|
||||
struct PendingEvent
|
||||
{
|
||||
RefPtr<DOMEventTargetHelper> mTarget;
|
||||
RefPtr<Event> mEvent;
|
||||
};
|
||||
|
||||
nsTArray<PendingEvent> mPendingEvents;
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -837,6 +851,10 @@ 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;
|
||||
|
||||
static bool sDontWarnAboutSyncXHR;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче