From d8c3aca81cfa512bcd6e0482ce02770c93599dc7 Mon Sep 17 00:00:00 2001 From: Bogdan Tara Date: Tue, 26 Jan 2021 22:40:15 +0200 Subject: [PATCH] Backed out changeset a911e7cbb478 (bug 1646498) for open-features-negative-innerwidth-innerheight.html failures CLOSED TREE --- .../AutoSuppressEventHandlingAndSuspend.h | 24 ++++---- dom/base/Document.cpp | 56 +++++++++---------- dom/base/Document.h | 23 +------- dom/base/nsContentUtils.cpp | 46 ++++++++++----- 4 files changed, 73 insertions(+), 76 deletions(-) diff --git a/dom/base/AutoSuppressEventHandlingAndSuspend.h b/dom/base/AutoSuppressEventHandlingAndSuspend.h index d2ae96f870a6..47e80b0521e6 100644 --- a/dom/base/AutoSuppressEventHandlingAndSuspend.h +++ b/dom/base/AutoSuppressEventHandlingAndSuspend.h @@ -7,14 +7,16 @@ #ifndef dom_base_AutoSuppressEventHandlingAndSuspend_h #define dom_base_AutoSuppressEventHandlingAndSuspend_h -#include "mozilla/dom/BrowsingContext.h" -#include "mozilla/dom/BrowsingContextGroup.h" #include "mozilla/dom/Document.h" #include "nsCOMPtr.h" #include "nsPIDOMWindow.h" #include "nsTArray.h" namespace mozilla::dom { + +class BrowsingContext; +class BrowsingContextGroup; + /** * Suppresses event handling and suspends the active inner window for all * in-process documents in a BrowsingContextGroup. This should be used while @@ -23,20 +25,16 @@ namespace mozilla::dom { * group. */ -class MOZ_RAII AutoSuppressEventHandlingAndSuspend - : private AutoWalkBrowsingContextGroup { +class MOZ_RAII AutoSuppressEventHandlingAndSuspend { public: - explicit AutoSuppressEventHandlingAndSuspend(BrowsingContextGroup* aGroup) { - if (aGroup) { - SuppressBrowsingContextGroup(aGroup); - } - } + explicit AutoSuppressEventHandlingAndSuspend(BrowsingContextGroup* aGroup); + ~AutoSuppressEventHandlingAndSuspend(); - ~AutoSuppressEventHandlingAndSuspend() { UnsuppressDocuments(); } + private: + void SuppressBrowsingContext(BrowsingContext* aBC); - protected: - void SuppressDocument(Document* aDocument) override; - void UnsuppressDocument(Document* aDocument) override; + AutoTArray, 16> mDocuments; + AutoTArray, 16> mWindows; }; } // namespace mozilla::dom diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 9d7c6dc48710..945e61f6261f 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -15627,32 +15627,38 @@ already_AddRefed Document::CreateHTMLElement(nsAtom* aTag) { return element.forget(); } -void AutoWalkBrowsingContextGroup::SuppressBrowsingContextGroup( - BrowsingContextGroup* aGroup) { - for (const auto& bc : aGroup->Toplevels()) { - bc->PreOrderWalk([&](BrowsingContext* aBC) { - if (nsCOMPtr win = aBC->GetDOMWindow()) { - if (RefPtr doc = win->GetExtantDoc()) { - SuppressDocument(doc); - mDocuments.AppendElement(doc); - } - } - }); +static CallState MarkDocumentTreeToBeInSyncOperation( + Document& aDoc, nsTArray>& aDocuments) { + aDoc.SetIsInSyncOperation(true); + if (nsCOMPtr window = aDoc.GetInnerWindow()) { + window->TimeoutManager().BeginSyncOperation(); } + aDocuments.AppendElement(&aDoc); + auto recurse = [&aDocuments](Document& aSubDoc) { + return MarkDocumentTreeToBeInSyncOperation(aSubDoc, aDocuments); + }; + aDoc.EnumerateSubDocuments(recurse); + return CallState::Continue; } nsAutoSyncOperation::nsAutoSyncOperation(Document* aDoc, SyncOperationBehavior aSyncBehavior) : mSyncBehavior(aSyncBehavior) { mMicroTaskLevel = 0; - if (CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get()) { + CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get(); + if (ccjs) { mMicroTaskLevel = ccjs->MicroTaskLevel(); ccjs->SetMicroTaskLevel(0); } if (aDoc) { - if (auto* bcg = aDoc->GetDocGroup()->GetBrowsingContextGroup()) { - SuppressBrowsingContextGroup(bcg); + if (nsPIDOMWindowOuter* win = aDoc->GetWindow()) { + if (nsCOMPtr top = win->GetInProcessTop()) { + if (RefPtr doc = top->GetExtantDoc()) { + MarkDocumentTreeToBeInSyncOperation(*doc, mDocuments); + } + } } + mBrowsingContext = aDoc->GetBrowsingContext(); if (mBrowsingContext && mSyncBehavior == SyncOperationBehavior::eSuspendInput && @@ -15662,26 +15668,18 @@ nsAutoSyncOperation::nsAutoSyncOperation(Document* aDoc, } } -void nsAutoSyncOperation::SuppressDocument(Document* aDoc) { - if (nsCOMPtr win = aDoc->GetInnerWindow()) { - win->TimeoutManager().BeginSyncOperation(); - } - aDoc->SetIsInSyncOperation(true); -} - -void nsAutoSyncOperation::UnsuppressDocument(Document* aDoc) { - if (nsCOMPtr win = aDoc->GetInnerWindow()) { - win->TimeoutManager().EndSyncOperation(); - } - aDoc->SetIsInSyncOperation(false); -} - nsAutoSyncOperation::~nsAutoSyncOperation() { - UnsuppressDocuments(); + for (RefPtr& doc : mDocuments) { + if (nsCOMPtr window = doc->GetInnerWindow()) { + window->TimeoutManager().EndSyncOperation(); + } + doc->SetIsInSyncOperation(false); + } CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get(); if (ccjs) { ccjs->SetMicroTaskLevel(mMicroTaskLevel); } + if (mBrowsingContext && mSyncBehavior == SyncOperationBehavior::eSuspendInput && InputTaskManager::CanSuspendInputEvent()) { diff --git a/dom/base/Document.h b/dom/base/Document.h index 18438cdf0b9f..8e5cd23676c2 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -5228,33 +5228,14 @@ class MOZ_STACK_CLASS mozAutoSubtreeModified { enum class SyncOperationBehavior { eSuspendInput, eAllowInput }; -class AutoWalkBrowsingContextGroup { - public: - virtual ~AutoWalkBrowsingContextGroup() = default; - - protected: - void SuppressBrowsingContextGroup(BrowsingContextGroup* aGroup); - void UnsuppressDocuments() { - for (const auto& doc : mDocuments) { - UnsuppressDocument(doc); - } - } - virtual void SuppressDocument(Document* aDocument) = 0; - virtual void UnsuppressDocument(Document* aDocument) = 0; - AutoTArray, 16> mDocuments; -}; - -class MOZ_RAII nsAutoSyncOperation : private AutoWalkBrowsingContextGroup { +class MOZ_STACK_CLASS nsAutoSyncOperation { public: explicit nsAutoSyncOperation(Document* aDocument, SyncOperationBehavior aSyncBehavior); ~nsAutoSyncOperation(); - protected: - void SuppressDocument(Document* aDocument) override; - void UnsuppressDocument(Document* aDocument) override; - private: + nsTArray> mDocuments; uint32_t mMicroTaskLevel; const SyncOperationBehavior mSyncBehavior; RefPtr mBrowsingContext; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 341f8497982b..4769ca6ca146 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -676,23 +676,43 @@ class SameOriginCheckerImpl final : public nsIChannelEventSink, } // namespace -void AutoSuppressEventHandlingAndSuspend::SuppressDocument(Document* aDoc) { - // Note: Document::SuppressEventHandling will also automatically suppress - // event handling for any in-process sub-documents. However, since we need - // to deal with cases where remote BrowsingContexts may be interleaved - // with in-process ones, we still need to walk the entire tree ourselves. - // This may be slightly redundant in some cases, but since event handling - // suppressions maintain a count of current blockers, it does not cause - // any problems. - aDoc->SuppressEventHandling(); - aDoc->GetInnerWindow()->Suspend(); +AutoSuppressEventHandlingAndSuspend::AutoSuppressEventHandlingAndSuspend( + BrowsingContextGroup* aGroup) { + for (const auto& bc : aGroup->Toplevels()) { + SuppressBrowsingContext(bc); + } } -void AutoSuppressEventHandlingAndSuspend::UnsuppressDocument(Document* aDoc) { - if (nsCOMPtr win = aDoc->GetInnerWindow()) { +void AutoSuppressEventHandlingAndSuspend::SuppressBrowsingContext( + BrowsingContext* aBC) { + if (nsCOMPtr win = aBC->GetDOMWindow()) { + if (RefPtr doc = win->GetExtantDoc()) { + mDocuments.AppendElement(doc); + mWindows.AppendElement(win->GetCurrentInnerWindow()); + // Note: Document::SuppressEventHandling will also automatically suppress + // event handling for any in-process sub-documents. However, since we need + // to deal with cases where remote BrowsingContexts may be interleaved + // with in-process ones, we still need to walk the entire tree ourselves. + // This may be slightly redundant in some cases, but since event handling + // suppressions maintain a count of current blockers, it does not cause + // any problems. + doc->SuppressEventHandling(); + win->GetCurrentInnerWindow()->Suspend(); + } + } + + for (const auto& bc : aBC->Children()) { + SuppressBrowsingContext(bc); + } +} + +AutoSuppressEventHandlingAndSuspend::~AutoSuppressEventHandlingAndSuspend() { + for (const auto& win : mWindows) { win->Resume(); } - aDoc->UnsuppressEventHandlingAndFireEvents(true); + for (const auto& doc : mDocuments) { + doc->UnsuppressEventHandlingAndFireEvents(true); + } } /**