зеркало из 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()),
|
mResultJSON(JS::UndefinedValue()),
|
||||||
mResultArrayBuffer(nullptr),
|
mResultArrayBuffer(nullptr),
|
||||||
mIsMappedArrayBuffer(false),
|
mIsMappedArrayBuffer(false),
|
||||||
mXPCOMifier(nullptr)
|
mXPCOMifier(nullptr),
|
||||||
|
mEventDispatchingSuspended(false)
|
||||||
{
|
{
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
@ -1368,7 +1369,7 @@ XMLHttpRequestMainThread::FireReadystatechangeEvent()
|
||||||
event->InitEvent(kLiteralString_readystatechange, false, false);
|
event->InitEvent(kLiteralString_readystatechange, false, false);
|
||||||
// We assume anyone who managed to call CreateReadystatechangeEvent is trusted
|
// We assume anyone who managed to call CreateReadystatechangeEvent is trusted
|
||||||
event->SetTrusted(true);
|
event->SetTrusted(true);
|
||||||
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
DispatchOrStoreEvent(this, event);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1411,7 +1412,7 @@ XMLHttpRequestMainThread::DispatchProgressEvent(DOMEventTargetHelper* aTarget,
|
||||||
ProgressEvent::Constructor(aTarget, typeString, init);
|
ProgressEvent::Constructor(aTarget, typeString, init);
|
||||||
event->SetTrusted(true);
|
event->SetTrusted(true);
|
||||||
|
|
||||||
aTarget->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
|
DispatchOrStoreEvent(aTarget, event);
|
||||||
|
|
||||||
if (aType == ProgressEventType::progress) {
|
if (aType == ProgressEventType::progress) {
|
||||||
mInLoadProgressEvent = false;
|
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>
|
already_AddRefed<nsIHttpChannel>
|
||||||
XMLHttpRequestMainThread::GetCurrentHttpChannel()
|
XMLHttpRequestMainThread::GetCurrentHttpChannel()
|
||||||
{
|
{
|
||||||
|
@ -2409,10 +2449,6 @@ XMLHttpRequestMainThread::ChangeStateToDone()
|
||||||
mTimeoutTimer->Cancel();
|
mTimeoutTimer->Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFlagSynchronous) {
|
|
||||||
UnsuppressEventHandlingAndResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Per spec, fire the last download progress event, if any,
|
// Per spec, fire the last download progress event, if any,
|
||||||
// before readystatechange=4/done. (Note that 0-sized responses
|
// before readystatechange=4/done. (Note that 0-sized responses
|
||||||
// will have not sent a progress event yet, so one must be sent here).
|
// 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();
|
StopProgressEventTimer();
|
||||||
|
|
||||||
SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
|
SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
|
||||||
|
@ -3056,6 +3093,7 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
UnsuppressEventHandlingAndResume();
|
UnsuppressEventHandlingAndResume();
|
||||||
|
ResumeEventDispatching();
|
||||||
} else {
|
} else {
|
||||||
// Now that we've successfully opened the channel, we can change state. Note
|
// 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
|
// that this needs to come after the AsyncOpen() and rv check, because this
|
||||||
|
|
|
@ -401,7 +401,8 @@ public:
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
void
|
void
|
||||||
Abort() {
|
Abort()
|
||||||
|
{
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
Abort(rv);
|
Abort(rv);
|
||||||
MOZ_ASSERT(!rv.Failed());
|
MOZ_ASSERT(!rv.Failed());
|
||||||
|
@ -607,8 +608,21 @@ protected:
|
||||||
|
|
||||||
nsresult DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable);
|
nsresult DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable);
|
||||||
|
|
||||||
|
void DispatchOrStoreEvent(DOMEventTargetHelper* aTarget, Event* aEvent);
|
||||||
|
|
||||||
already_AddRefed<nsXMLHttpRequestXPCOMifier> EnsureXPCOMifier();
|
already_AddRefed<nsXMLHttpRequestXPCOMifier> EnsureXPCOMifier();
|
||||||
|
|
||||||
|
void SuspendEventDispatching();
|
||||||
|
void ResumeEventDispatching();
|
||||||
|
|
||||||
|
struct PendingEvent
|
||||||
|
{
|
||||||
|
RefPtr<DOMEventTargetHelper> mTarget;
|
||||||
|
RefPtr<Event> mEvent;
|
||||||
|
};
|
||||||
|
|
||||||
|
nsTArray<PendingEvent> mPendingEvents;
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> mContext;
|
nsCOMPtr<nsISupports> mContext;
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
nsCOMPtr<nsIChannel> mChannel;
|
nsCOMPtr<nsIChannel> mChannel;
|
||||||
|
@ -837,6 +851,10 @@ protected:
|
||||||
// Helper object to manage our XPCOM scriptability bits
|
// Helper object to manage our XPCOM scriptability bits
|
||||||
nsXMLHttpRequestXPCOMifier* mXPCOMifier;
|
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;
|
static bool sDontWarnAboutSyncXHR;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче