зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1558215 - Refactor nsPIDOMWindowInner::AddAfterLoadRunner to be easier to use, r=baku
Differential Revision: https://phabricator.services.mozilla.com/D34366 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
15529ee673
Коммит
34a4375fd1
|
@ -1052,6 +1052,8 @@ nsGlobalWindowInner::~nsGlobalWindowInner() {
|
|||
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
|
||||
if (ac) ac->RemoveWindowAsListener(this);
|
||||
|
||||
mDeprioritizedLoadRunner.clear();
|
||||
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
|
@ -2546,7 +2548,7 @@ void nsPIDOMWindowInner::SetAudioCapture(bool aCapture) {
|
|||
}
|
||||
}
|
||||
|
||||
void nsPIDOMWindowInner::SetActiveLoadingState(bool aIsLoading) {
|
||||
void nsGlobalWindowInner::SetActiveLoadingState(bool aIsLoading) {
|
||||
if (StaticPrefs::dom_separate_event_queue_for_post_message_enabled()) {
|
||||
if (!aIsLoading) {
|
||||
Document* doc = GetExtantDoc();
|
||||
|
@ -2564,15 +2566,33 @@ void nsPIDOMWindowInner::SetActiveLoadingState(bool aIsLoading) {
|
|||
}
|
||||
|
||||
if (!aIsLoading) {
|
||||
for (uint32_t i = 0; i < mAfterLoadRunners.Length(); ++i) {
|
||||
NS_DispatchToCurrentThread(mAfterLoadRunners[i].forget());
|
||||
while (!mDeprioritizedLoadRunner.isEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> runner = mDeprioritizedLoadRunner.popFirst();
|
||||
NS_DispatchToCurrentThread(runner.forget());
|
||||
}
|
||||
mAfterLoadRunners.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void nsPIDOMWindowInner::AddAfterLoadRunner(nsIRunnable* aRunner) {
|
||||
mAfterLoadRunners.AppendElement(aRunner);
|
||||
nsPIDOMWindowInner* nsPIDOMWindowInner::GetWindowForDeprioritizedLoadRunner() {
|
||||
Document* doc = GetExtantDoc();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
doc = doc->GetTopLevelContentDocument();
|
||||
if (!doc || (doc->GetReadyStateEnum() <= Document::READYSTATE_UNINITIALIZED ||
|
||||
doc->GetReadyStateEnum() >= Document::READYSTATE_COMPLETE)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return doc->GetInnerWindow();
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::AddDeprioritizedLoadRunner(nsIRunnable* aRunner) {
|
||||
MOZ_ASSERT(GetWindowForDeprioritizedLoadRunner() == this);
|
||||
RefPtr<DeprioritizedLoadRunner> runner = new DeprioritizedLoadRunner(aRunner);
|
||||
mDeprioritizedLoadRunner.insertBack(runner);
|
||||
NS_DispatchToCurrentThreadQueue(runner.forget(), 5000,
|
||||
EventQueuePriority::Idle);
|
||||
}
|
||||
|
||||
// nsISpeechSynthesisGetter
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "mozilla/dom/ImageBitmapSource.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsIArray;
|
||||
class nsIBaseWindow;
|
||||
|
@ -1226,6 +1227,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
typedef mozilla::LinkedList<RefPtr<mozilla::dom::IdleRequest>> IdleRequests;
|
||||
void RemoveIdleCallback(mozilla::dom::IdleRequest* aRequest);
|
||||
|
||||
void SetActiveLoadingState(bool aIsLoading) override;
|
||||
void AddDeprioritizedLoadRunner(nsIRunnable* aRunner) override;
|
||||
|
||||
protected:
|
||||
// Window offline status. Checked to see if we need to fire offline event
|
||||
bool mWasOffline : 1;
|
||||
|
@ -1397,6 +1401,28 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
nsTArray<mozilla::UniquePtr<PromiseDocumentFlushedResolver>>
|
||||
mDocumentFlushedResolvers;
|
||||
|
||||
class DeprioritizedLoadRunner
|
||||
: public mozilla::Runnable,
|
||||
public mozilla::LinkedListElement<DeprioritizedLoadRunner> {
|
||||
public:
|
||||
explicit DeprioritizedLoadRunner(nsIRunnable* aInner)
|
||||
: Runnable("DeprioritizedLoadRunner"), mInner(aInner) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
if (mInner) {;
|
||||
RefPtr<nsIRunnable> inner = std::move(mInner);
|
||||
inner->Run();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<nsIRunnable> mInner;
|
||||
};
|
||||
|
||||
mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
|
||||
|
||||
static InnerWindowByIdTable* sInnerWindowsById;
|
||||
|
||||
// Members in the mChromeFields member should only be used in chrome windows.
|
||||
|
|
|
@ -175,8 +175,17 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||
inline bool IsHandlingResizeEvent() const;
|
||||
|
||||
// Note: not related to IsLoading. Set to false if there's an error, etc.
|
||||
void SetActiveLoadingState(bool aIsActiveLoading);
|
||||
void AddAfterLoadRunner(nsIRunnable* aRunner);
|
||||
virtual void SetActiveLoadingState(bool aIsActiveLoading) = 0;
|
||||
|
||||
nsPIDOMWindowInner* GetWindowForDeprioritizedLoadRunner();
|
||||
|
||||
/**
|
||||
* The runnable will be called once there is idle time, or the top level
|
||||
* page has been loaded or if a timeout has fired.
|
||||
* Must be called only on the top level window, the one
|
||||
* GetWindowForDeprioritizedLoadRunner returns.
|
||||
*/
|
||||
virtual void AddDeprioritizedLoadRunner(nsIRunnable* aRunner) = 0;
|
||||
|
||||
bool AddAudioContext(mozilla::dom::AudioContext* aAudioContext);
|
||||
void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext);
|
||||
|
@ -677,8 +686,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||
// This will be non-null during the full lifetime of the window, initialized
|
||||
// during SetNewDocument, and cleared during FreeInnerObjects.
|
||||
RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
|
||||
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mAfterLoadRunners;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
|
||||
|
|
|
@ -2255,22 +2255,15 @@ void XMLHttpRequestMainThread::ChangeStateToDone(bool aWasSync) {
|
|||
mChannel->GetLoadFlags(&loadFlags);
|
||||
if (loadFlags & nsIRequest::LOAD_BACKGROUND) {
|
||||
nsPIDOMWindowInner* owner = GetOwner();
|
||||
Document* doc = owner ? owner->GetExtantDoc() : nullptr;
|
||||
doc = doc ? doc->GetTopLevelContentDocument() : nullptr;
|
||||
if (doc &&
|
||||
(doc->GetReadyStateEnum() > Document::READYSTATE_UNINITIALIZED &&
|
||||
doc->GetReadyStateEnum() < Document::READYSTATE_COMPLETE)) {
|
||||
nsPIDOMWindowInner* topWin = doc->GetInnerWindow();
|
||||
if (topWin) {
|
||||
MOZ_ASSERT(!mDelayedDoneNotifier);
|
||||
RefPtr<XMLHttpRequestDoneNotifier> notifier =
|
||||
new XMLHttpRequestDoneNotifier(this);
|
||||
mDelayedDoneNotifier = notifier;
|
||||
topWin->AddAfterLoadRunner(notifier);
|
||||
NS_DispatchToCurrentThreadQueue(notifier.forget(), 5000,
|
||||
EventQueuePriority::Idle);
|
||||
return;
|
||||
}
|
||||
nsPIDOMWindowInner* topWin =
|
||||
owner ? owner->GetWindowForDeprioritizedLoadRunner() : nullptr;
|
||||
if (topWin) {
|
||||
MOZ_ASSERT(!mDelayedDoneNotifier);
|
||||
RefPtr<XMLHttpRequestDoneNotifier> notifier =
|
||||
new XMLHttpRequestDoneNotifier(this);
|
||||
mDelayedDoneNotifier = notifier;
|
||||
topWin->AddDeprioritizedLoadRunner(notifier);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче