Backed out 2 changesets (bug 1730117) for causing failures at test_suppressed_events_nested_iframe.html. CLOSED TREE
authorButkovits Atila <abutkovits@mozilla.com>
Tue, 21 Sep 2021 00:38:17 +0300
changeset 592554 ab5ec599ad1c751183830b6e187ffad0432eee62
parent 592553 510dd46a9de764e8730e081235a5d4d3aa9507ee
child 592555 5f34eb5761c4895d8edbd4ed4be94a941f32d52b
push id150066
push userabutkovits@mozilla.com
push dateMon, 20 Sep 2021 21:39:01 +0000
treeherderautoland@ab5ec599ad1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1730117
milestone94.0a1
backs out649984f4a9390b2b943ec440345b91dbbb6776e1
37a35b6b54b4baa5f5639080864b0fe4dcf2d534
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 2 changesets (bug 1730117) for causing failures at test_suppressed_events_nested_iframe.html. CLOSED TREE Backed out changeset 649984f4a939 (bug 1730117) Backed out changeset 37a35b6b54b4 (bug 1730117)
dom/base/AutoSuppressEventHandlingAndSuspend.h
dom/base/nsContentUtils.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsGlobalWindowOuter.h
dom/base/nsPIDOMWindow.h
dom/base/test/file_suppressed_events_inner.html
dom/base/test/file_suppressed_events_middle.html
dom/base/test/file_suppressed_events_top.html
dom/base/test/file_suppressed_events_top_modalstate.html
dom/base/test/file_suppressed_events_top_xhr.html
dom/base/test/mochitest.ini
dom/base/test/test_suppressed_events_nested_iframe.html
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
--- a/dom/base/AutoSuppressEventHandlingAndSuspend.h
+++ b/dom/base/AutoSuppressEventHandlingAndSuspend.h
@@ -10,59 +10,37 @@
 #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 {
-
-/**
- * Suppresses event handling and suspends for all in-process documents in a
- * BrowsingContext subtree.
- */
-class MOZ_RAII AutoSuppressEventHandling
-    : private AutoWalkBrowsingContextGroup {
- public:
-  explicit AutoSuppressEventHandling(BrowsingContext* aContext) {
-    if (aContext) {
-      SuppressBrowsingContext(aContext);
-    }
-  }
-
-  explicit AutoSuppressEventHandling(BrowsingContextGroup* aGroup) {
-    if (aGroup) {
-      SuppressBrowsingContextGroup(aGroup);
-    }
-  }
-
-  ~AutoSuppressEventHandling();
-
- protected:
-  void SuppressDocument(Document* aDocument) override;
-  void UnsuppressDocument(Document* aDocument) override;
-};
-
 /**
  * Suppresses event handling and suspends the active inner window for all
  * in-process documents in a BrowsingContextGroup. This should be used while
  * spinning the event loop for a synchronous operation (like `window.open()`)
  * which affects operations in any other window in the same BrowsingContext
  * group.
  */
+
 class MOZ_RAII AutoSuppressEventHandlingAndSuspend
-    : private AutoSuppressEventHandling {
+    : private AutoWalkBrowsingContextGroup {
  public:
-  explicit AutoSuppressEventHandlingAndSuspend(BrowsingContextGroup* aGroup)
-      : AutoSuppressEventHandling(aGroup) {}
+  explicit AutoSuppressEventHandlingAndSuspend(BrowsingContextGroup* aGroup) {
+    if (aGroup) {
+      SuppressBrowsingContextGroup(aGroup);
+    }
+  }
 
   ~AutoSuppressEventHandlingAndSuspend();
 
  protected:
   void SuppressDocument(Document* aDocument) override;
+  void UnsuppressDocument(Document* aDocument) override;
 
  private:
   AutoTArray<nsCOMPtr<nsPIDOMWindowInner>, 16> mWindows;
 };
 }  // namespace mozilla::dom
 
 #endif
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -668,47 +668,40 @@ class SameOriginCheckerImpl final : publ
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
 };
 
 }  // namespace
 
-void AutoSuppressEventHandling::SuppressDocument(Document* aDoc) {
+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();
-}
-
-void AutoSuppressEventHandling::UnsuppressDocument(Document* aDoc) {
-  aDoc->UnsuppressEventHandlingAndFireEvents(true);
-}
-
-AutoSuppressEventHandling::~AutoSuppressEventHandling() {
-  UnsuppressDocuments();
-}
-
-void AutoSuppressEventHandlingAndSuspend::SuppressDocument(Document* aDoc) {
-  AutoSuppressEventHandling::SuppressDocument(aDoc);
   if (nsCOMPtr<nsPIDOMWindowInner> win = aDoc->GetInnerWindow()) {
     win->Suspend();
     mWindows.AppendElement(win);
   }
 }
 
+void AutoSuppressEventHandlingAndSuspend::UnsuppressDocument(Document* aDoc) {
+  aDoc->UnsuppressEventHandlingAndFireEvents(true);
+}
+
 AutoSuppressEventHandlingAndSuspend::~AutoSuppressEventHandlingAndSuspend() {
   for (const auto& win : mWindows) {
     win->Resume();
   }
+  UnsuppressDocuments();
 }
 
 /**
  * This class is used to determine whether or not the user is currently
  * interacting with the browser. It listens to observer events to toggle the
  * value of the sUserActive static.
  *
  * This class is an internal implementation detail.
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1630,23 +1630,23 @@ nsDOMWindowUtils::DisableNonTestMouseEve
   PresShell* presShell = docShell->GetPresShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
   presShell->DisableNonTestMouseEvents(aDisable);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SuppressEventHandling(bool aSuppress) {
-  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
-  NS_ENSURE_STATE(window);
+  nsCOMPtr<Document> doc = GetDocument();
+  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   if (aSuppress) {
-    window->SuppressEventHandling();
+    doc->SuppressEventHandling();
   } else {
-    window->UnsuppressEventHandling();
+    doc->UnsuppressEventHandlingAndFireEvents(true);
   }
 
   return NS_OK;
 }
 
 static nsresult getScrollXYAppUnits(const nsWeakPtr& aWindow, bool aFlushLayout,
                                     nsPoint& aScrollPos) {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(aWindow);
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1487,17 +1487,17 @@ void nsGlobalWindowOuter::ShutDown() {
 
   delete sOuterWindowsById;
   sOuterWindowsById = nullptr;
 }
 
 void nsGlobalWindowOuter::DropOuterWindowDocs() {
   MOZ_ASSERT_IF(mDoc, !mDoc->EventHandlingSuppressed());
   mDoc = nullptr;
-  mSuspendedDocs.Clear();
+  mSuspendedDoc = nullptr;
 }
 
 void nsGlobalWindowOuter::CleanUp() {
   // Guarantee idempotence.
   if (mCleanedUp) return;
   mCleanedUp = true;
 
   StartDying();
@@ -1592,17 +1592,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArguments)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStorage)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedDocs)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuspendedDoc)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPartitionedPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)
 
   // Traverse stuff from nsPIDOMWindow
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)
@@ -1624,17 +1624,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   }
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mArguments)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedDocs)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuspendedDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPartitionedPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
 
   // Unlink stuff from nsPIDOMWindow
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)
@@ -2152,19 +2152,19 @@ nsresult nsGlobalWindowOuter::SetNewDocu
   nsDocShell::Cast(mDocShell)->MaybeRestoreWindowName();
 
   // We drop the print request for the old document on the floor, it never made
   // it. We don't close the window here either even if we were asked to.
   mShouldDelayPrintUntilAfterLoad = true;
   mDelayedCloseForPrinting = false;
   mDelayedPrintUntilAfterLoad = false;
 
-  // Take this opportunity to clear mSuspendedDocs. Our old inner window is now
+  // Take this opportunity to clear mSuspendedDoc. Our old inner window is now
   // responsible for unsuspending it.
-  mSuspendedDocs.Clear();
+  mSuspendedDoc = nullptr;
 
 #ifdef DEBUG
   mLastOpenedURI = aDocument->GetDocumentURI();
 #endif
 
   RefPtr<nsGlobalWindowInner> currentInner = GetCurrentInnerWindowInternal();
 
   if (currentInner && currentInner->mNavigator) {
@@ -6351,54 +6351,16 @@ void nsGlobalWindowOuter::ReallyCloseWin
   if (!treeOwnerAsWin) {
     return;
   }
 
   treeOwnerAsWin->Destroy();
   CleanUp();
 }
 
-void nsGlobalWindowOuter::SuppressEventHandling() {
-  if (mSuppressEventHandlingDepth == 0) {
-    if (BrowsingContext* bc = GetBrowsingContext()) {
-      bc->PreOrderWalk([&](BrowsingContext* aBC) {
-        if (nsCOMPtr<nsPIDOMWindowOuter> win = aBC->GetDOMWindow()) {
-          if (RefPtr<Document> doc = win->GetExtantDoc()) {
-            mSuspendedDocs.AppendElement(doc);
-            // 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();
-          }
-        }
-      });
-    }
-  }
-  mSuppressEventHandlingDepth++;
-}
-
-void nsGlobalWindowOuter::UnsuppressEventHandling() {
-  MOZ_ASSERT(mSuppressEventHandlingDepth != 0);
-  mSuppressEventHandlingDepth--;
-
-  if (mSuppressEventHandlingDepth == 0 && mSuspendedDocs.Length()) {
-    RefPtr<Document> currentDoc = GetExtantDoc();
-    bool fireEvent = currentDoc == mSuspendedDocs[0];
-    nsTArray<RefPtr<Document>> suspendedDocs = std::move(mSuspendedDocs);
-    for (const auto& doc : suspendedDocs) {
-      doc->UnsuppressEventHandlingAndFireEvents(fireEvent);
-    }
-  }
-}
-
 nsGlobalWindowOuter* nsGlobalWindowOuter::EnterModalState() {
   // GetInProcessScriptableTop, not GetInProcessTop, so that EnterModalState
   // works properly with <iframe mozbrowser>.
   nsGlobalWindowOuter* topWin = GetInProcessScriptableTopInternal();
 
   if (!topWin) {
     NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
     return nullptr;
@@ -6439,17 +6401,22 @@ nsGlobalWindowOuter* nsGlobalWindowOuter
   Document* topDoc = topWin->GetExtantDoc();
   nsIContent* capturingContent = PresShell::GetCapturingContent();
   if (capturingContent && topDoc &&
       nsContentUtils::ContentIsCrossDocDescendantOf(capturingContent, topDoc)) {
     PresShell::ReleaseCapturingContent();
   }
 
   if (topWin->mModalStateDepth == 0) {
-    topWin->SuppressEventHandling();
+    NS_ASSERTION(!topWin->mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
+
+    topWin->mSuspendedDoc = topDoc;
+    if (topDoc) {
+      topDoc->SuppressEventHandling();
+    }
 
     if (nsGlobalWindowInner* inner = topWin->GetCurrentInnerWindowInternal()) {
       inner->Suspend();
     }
   }
   topWin->mModalStateDepth++;
   return topWin;
 }
@@ -6473,17 +6440,22 @@ void nsGlobalWindowOuter::LeaveModalStat
   mModalStateDepth--;
 
   nsGlobalWindowInner* inner = GetCurrentInnerWindowInternal();
   if (mModalStateDepth == 0) {
     if (inner) {
       inner->Resume();
     }
 
-    UnsuppressEventHandling();
+    if (mSuspendedDoc) {
+      nsCOMPtr<Document> currentDoc = GetExtantDoc();
+      mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(currentDoc ==
+                                                          mSuspendedDoc);
+      mSuspendedDoc = nullptr;
+    }
   }
 
   // Remember the time of the last dialog quit.
   if (auto* bcg = GetBrowsingContextGroup()) {
     bcg->SetLastDialogQuitTime(TimeStamp::Now());
   }
 
   if (mModalStateDepth == 0) {
@@ -7734,17 +7706,16 @@ mozilla::dom::DocGroup* nsPIDOMWindowOut
     return doc->GetDocGroup();
   }
   return nullptr;
 }
 
 nsPIDOMWindowOuter::nsPIDOMWindowOuter(uint64_t aWindowID)
     : mFrameElement(nullptr),
       mModalStateDepth(0),
-      mSuppressEventHandlingDepth(0),
       mIsBackground(false),
       mMediaSuspend(StaticPrefs::media_block_autoplay_until_in_foreground()
                         ? nsISuspendedTypes::SUSPENDED_BLOCK
                         : nsISuspendedTypes::NONE_SUSPENDED),
       mDesktopModeViewport(false),
       mIsRootOuterWindow(false),
       mInnerWindow(nullptr),
       mWindowID(aWindowID),
--- a/dom/base/nsGlobalWindowOuter.h
+++ b/dom/base/nsGlobalWindowOuter.h
@@ -323,19 +323,16 @@ class nsGlobalWindowOuter final : public
   static void PrepareForProcessChange(JSObject* aProxy);
 
   // Outer windows only.
   void DispatchDOMWindowCreated();
 
   // Outer windows only.
   virtual void EnsureSizeAndPositionUpToDate() override;
 
-  virtual void SuppressEventHandling() override;
-  virtual void UnsuppressEventHandling() override;
-
   MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsGlobalWindowOuter* EnterModalState()
       override;
   virtual void LeaveModalState() override;
 
   // Outer windows only.
   virtual bool CanClose() override;
   virtual void ForceClose() override;
 
@@ -1126,20 +1123,20 @@ class nsGlobalWindowOuter final : public
   bool mSetOpenerWindowCalled;
   nsCOMPtr<nsIURI> mLastOpenedURI;
 #endif
 
   bool mCleanedUp;
 
   // It's useful when we get matched EnterModalState/LeaveModalState calls, in
   // which case the outer window is responsible for unsuspending events on the
-  // documents. If we don't (for example, if the outer window is closed before
-  // the LeaveModalState call), then the inner window whose mDoc is in our
-  // mSuspendedDocs is responsible for unsuspending.
-  nsTArray<RefPtr<Document>> mSuspendedDocs;
+  // document. If we don't (for example, if the outer window is closed before
+  // the LeaveModalState call), then the inner window whose mDoc is our
+  // mSuspendedDoc is responsible for unsuspending it.
+  RefPtr<Document> mSuspendedDoc;
 
   // This is the CC generation the last time we called CanSkip.
   uint32_t mCanSkipCCGeneration;
 
   // When non-zero, the document should receive a vrdisplayactivate event
   // after loading.  The value is the ID of the VRDisplay that content should
   // begin presentation on.
   uint32_t mAutoActivateVRDisplayID;
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -906,23 +906,16 @@ class nsPIDOMWindowOuter : public mozIDO
   /**
    * Ensure the size and position of this window are up-to-date by doing
    * a layout flush in the parent (which will in turn, do a layout flush
    * in its parent, etc.).
    */
   virtual void EnsureSizeAndPositionUpToDate() = 0;
 
   /**
-   * Suppresses/unsuppresses user initiated event handling in window's document
-   * and all in-process descendant documents.
-   */
-  virtual void SuppressEventHandling() = 0;
-  virtual void UnsuppressEventHandling() = 0;
-
-  /**
    * Callback for notifying a window about a modal dialog being
    * opened/closed with the window as a parent.
    *
    * If any script can run between the enter and leave modal states, and the
    * window isn't top, the LeaveModalState() should be called on the window
    * returned by EnterModalState().
    */
   virtual nsPIDOMWindowOuter* EnterModalState() = 0;
@@ -1126,18 +1119,16 @@ class nsPIDOMWindowOuter : public mozIDO
   nsCOMPtr<mozilla::dom::Element> mFrameElement;
 
   // These references are used by nsGlobalWindow.
   nsCOMPtr<nsIDocShell> mDocShell;
   RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
 
   uint32_t mModalStateDepth;
 
-  uint32_t mSuppressEventHandlingDepth;
-
   // Tracks whether our docshell is active.  If it is, mIsBackground
   // is false.  Too bad we have so many different concepts of
   // "active".
   bool mIsBackground;
 
   /**
    * The suspended types can be "disposable" or "permanent". This varable only
    * stores the value about permanent suspend.
deleted file mode 100644
--- a/dom/base/test/file_suppressed_events_inner.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Test event suppression</title>
-</head>
-<body>
-<div>Inner</div>
-<script type="application/javascript">
-
-window.onload = function() {
-  top.postMessage("ready", "*");
-};
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/base/test/file_suppressed_events_middle.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Test event suppression</title>
-</head>
-<body>
-<div>Middle</div>
-<iframe src="http://mochi.test:8888/tests/dom/base/test/file_suppressed_events_inner.html"></iframe>
-</body>
-</html>
deleted file mode 100644
--- a/dom/base/test/file_suppressed_events_top.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Test event suppression</title>
-<script src="/tests/SimpleTest/SimpleTest.js"></script>
-<script src="/tests/SimpleTest/EventUtils.js"></script>
-<script src="/tests/SimpleTest/paint_listener.js"></script>
-<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<div>Top</div>
-<script type="application/javascript">
-
-function waitForMessage(aMsg, aCallback) {
-  window.addEventListener("message", function handler(e) {
-    if (e.data != aMsg) {
-      return;
-    }
-
-    info(`received: ${e.data}`);
-    window.removeEventListener("message", handler);
-    if (aCallback) {
-      aCallback(e);
-    }
-  });
-}
-
-function waitForClickEvent(aElement, aWindow) {
-  return new Promise((aResolve) => {
-    aElement.addEventListener("click", aResolve, { once: true });
-    synthesizeMouseAtCenter(aElement, { type: "mousedown" }, aWindow);
-    synthesizeMouseAtCenter(aElement, { type: "mouseup" }, aWindow);
-  });
-}
-
-waitForMessage("ready", async function(e) {
-  await waitUntilApzStable();
-
-  let innerWin = e.source;
-  let innerDiv = innerWin.document.querySelector("div");
-
-  let eventCount = 0;
-  innerDiv.addEventListener("mousemove", function() {
-    eventCount++;
-  });
-
-  // Test that event handling is suppressed.
-  let utils = SpecialPowers.getDOMWindowUtils(window);
-  utils.suppressEventHandling(true);
-  const TOTAL = 100;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-  utils.suppressEventHandling(false);
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.ok(eventCount < TOTAL, "event should be suspressed");
-
-  // Test that event handling is not suppressed.
-  eventCount = 0;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.is(eventCount, TOTAL, "event should not be suspressed");
-
-  opener.postMessage("done", "*");
-});
-
-</script>
-<iframe src="http://example.org/tests/dom/base/test/file_suppressed_events_middle.html"></iframe>
-</body>
-</html>
deleted file mode 100644
--- a/dom/base/test/file_suppressed_events_top_modalstate.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Test event suppression</title>
-<script src="/tests/SimpleTest/SimpleTest.js"></script>
-<script src="/tests/SimpleTest/EventUtils.js"></script>
-<script src="/tests/SimpleTest/paint_listener.js"></script>
-<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<div>Top</div>
-<script type="application/javascript">
-
-function waitForMessage(aMsg, aCallback) {
-  window.addEventListener("message", function handler(e) {
-    if (e.data != aMsg) {
-      return;
-    }
-
-    info(`received: ${e.data}`);
-    window.removeEventListener("message", handler);
-    if (aCallback) {
-      aCallback(e);
-    }
-  });
-}
-
-function waitForClickEvent(aElement, aWindow) {
-  return new Promise((aResolve) => {
-    aElement.addEventListener("click", aResolve, { once: true });
-    synthesizeMouseAtCenter(aElement, { type: "mousedown" }, aWindow);
-    synthesizeMouseAtCenter(aElement, { type: "mouseup" }, aWindow);
-  });
-}
-
-waitForMessage("ready", async function(e) {
-  await waitUntilApzStable();
-
-  let innerWin = e.source;
-  let innerDiv = innerWin.document.querySelector("div");
-
-  let eventCount = 0;
-  innerDiv.addEventListener("mousemove", function() {
-    eventCount++;
-  });
-
-  // Test that event handling is suppressed.
-  let utils = SpecialPowers.getDOMWindowUtils(window);
-  utils.enterModalState();
-  const TOTAL = 100;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-  utils.leaveModalState();
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.ok(eventCount < TOTAL, "event should be suspressed");
-
-  // Test that event handling is not suppressed.
-  eventCount = 0;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.is(eventCount, TOTAL, "event should not be suspressed");
-
-  opener.postMessage("done", "*");
-});
-
-</script>
-<iframe src="http://example.org/tests/dom/base/test/file_suppressed_events_middle.html"></iframe>
-</body>
-</html>
deleted file mode 100644
--- a/dom/base/test/file_suppressed_events_top_xhr.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Test event suppression</title>
-<script src="/tests/SimpleTest/SimpleTest.js"></script>
-<script src="/tests/SimpleTest/EventUtils.js"></script>
-<script src="/tests/SimpleTest/paint_listener.js"></script>
-<script src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<div>Top</div>
-<script type="application/javascript">
-
-function waitForMessage(aMsg, aCallback) {
-  window.addEventListener("message", function handler(e) {
-    if (e.data != aMsg) {
-      return;
-    }
-
-    info(`received: ${e.data}`);
-    window.removeEventListener("message", handler);
-    if (aCallback) {
-      aCallback(e);
-    }
-  });
-}
-
-function waitForClickEvent(aElement, aWindow) {
-  return new Promise((aResolve) => {
-    aElement.addEventListener("click", aResolve, { once: true });
-    synthesizeMouseAtCenter(aElement, { type: "mousedown" }, aWindow);
-    synthesizeMouseAtCenter(aElement, { type: "mouseup" }, aWindow);
-  });
-}
-
-waitForMessage("ready", async function(e) {
-  await waitUntilApzStable();
-
-  let innerWin = e.source;
-  let innerDiv = innerWin.document.querySelector("div");
-
-  let eventCount = 0;
-  innerDiv.addEventListener("mousemove", function() {
-    eventCount++;
-  });
-
-  // Test that event handling is suppressed.
-  let xhr = new XMLHttpRequest();
-  opener.info("xhr open");
-  xhr.open('GET', 'slow.sjs', false);
-
-  const TOTAL = 100;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-  xhr.send();
-  opener.info(`xhr done`);
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.ok(eventCount < TOTAL, "event should be suspressed");
-
-  // Test that event handling is not suppressed.
-  eventCount = 0;
-  for (let i = 0; i < TOTAL; i++) {
-    synthesizeMouseAtCenter(innerDiv, { type: "mousemove" }, innerWin);
-  }
-
-  // Wait for click event to ensure we have received all mousemove events.
-  await waitForClickEvent(innerDiv, innerWin);
-  opener.info(`eventCount: ${eventCount}`);
-  opener.is(eventCount, TOTAL, "event should not be suspressed");
-
-  opener.postMessage("done", "*");
-});
-
-</script>
-<iframe src="http://example.org/tests/dom/base/test/file_suppressed_events_middle.html"></iframe>
-</body>
-</html>
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -769,24 +769,16 @@ skip-if = debug == false
 [test_setting_opener.html]
 [test_shared_compartment1.html]
 [test_shared_compartment2.html]
 [test_structuredclone_backref.html]
 [test_style_cssText.html]
 [test_suppressed_events_and_scrolling.html]
 support-files =
   file_suppressed_events_and_scrolling.html
-[test_suppressed_events_nested_iframe.html]
-support-files =
-  file_suppressed_events_top_xhr.html
-  file_suppressed_events_top_modalstate.html
-  file_suppressed_events_top.html
-  file_suppressed_events_middle.html
-  file_suppressed_events_inner.html
-  !/gfx/layers/apz/test/mochitest/apz_test_utils.js
 [test_suppressed_microtasks.html]
 skip-if = debug || asan || verify || toolkit == 'android' # The test needs to run reasonably fast.
 [test_text_wholeText.html]
 [test_textnode_normalize_in_selection.html]
 [test_textnode_split_in_selection.html]
 [test_timeout_clamp.html]
 [test_timer_flood.html]
 [test_title.html]
deleted file mode 100644
--- a/dom/base/test/test_suppressed_events_nested_iframe.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1730117
--->
-<head>
-  <title>Test event suppression on nested iframe</title>
-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1730117">Mozilla Bug 1730117</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-function waitForMessage(aMsg) {
-  return new Promise((aResolve) => {
-    window.addEventListener("message", function handler(e) {
-      info(`receive: ${e.data}`);
-      if (e.data != aMsg) {
-        return;
-      }
-
-      window.removeEventListener("message", handler);
-      aResolve();
-    });
-  });
-}
-
-/** Test for Bug 1730117 **/
-
-add_task(async function test_sync_xhr() {
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["test.events.async.enabled", true],
-    ["dom.events.coalesce.mousemove", false],
-  ]});
-
-  let w = window.open("file_suppressed_events_top_xhr.html");
-  await waitForMessage("done");
-  w.close();
-});
-
-add_task(async function test_modalstate() {
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["test.events.async.enabled", false],
-    ["dom.events.coalesce.mousemove", false],
-  ]});
-
-  let w = window.open("file_suppressed_events_top_modalstate.html");
-  await waitForMessage("done");
-  w.close();
-});
-
-add_task(async function test_suppress_event_handling() {
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["test.events.async.enabled", false],
-    ["dom.events.coalesce.mousemove", false],
-  ]});
-
-  let w = window.open("file_suppressed_events_top.html");
-  await waitForMessage("done");
-  w.close();
-});
-
-</script>
-</pre>
-</body>
-</html>
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -9,17 +9,16 @@
 #include <algorithm>
 #ifndef XP_WIN
 #  include <unistd.h>
 #endif
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Components.h"
-#include "mozilla/dom/AutoSuppressEventHandlingAndSuspend.h"
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/DocGroup.h"
 #include "mozilla/dom/DOMString.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileBinding.h"
 #include "mozilla/dom/FileCreatorHelper.h"
 #include "mozilla/dom/FetchUtil.h"
@@ -2793,20 +2792,25 @@ void XMLHttpRequestMainThread::EnsureCha
   nsAutoCString contentType;
   if (NS_FAILED(mChannel->GetContentType(contentType)) ||
       contentType.IsEmpty() ||
       contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE)) {
     mChannel->SetContentType("text/xml"_ns);
   }
 }
 
-void XMLHttpRequestMainThread::ResumeTimeout() {
+void XMLHttpRequestMainThread::UnsuppressEventHandlingAndResume() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mFlagSynchronous);
 
+  if (mSuspendedDoc) {
+    mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(true);
+    mSuspendedDoc = nullptr;
+  }
+
   if (mResumeTimeoutRunnable) {
     DispatchToMainThread(mResumeTimeoutRunnable.forget());
     mResumeTimeoutRunnable = nullptr;
   }
 }
 
 void XMLHttpRequestMainThread::Send(
     const Nullable<
@@ -3019,51 +3023,50 @@ void XMLHttpRequestMainThread::SendInter
   StartTimeoutTimer();
 
   mWaitingForOnStopRequest = true;
 
   // Step 8
   mFlagSend = true;
 
   // If we're synchronous, spin an event loop here and wait
-  RefPtr<Document> suspendedDoc;
   if (mFlagSynchronous) {
-    auto scopeExit = MakeScopeExit([&] {
-      CancelSyncTimeoutTimer();
-      ResumeTimeout();
-      ResumeEventDispatching();
-    });
-    Maybe<AutoSuppressEventHandling> autoSuppress;
-
     mFlagSyncLooping = true;
 
     if (GetOwner()) {
       if (nsCOMPtr<nsPIDOMWindowOuter> topWindow =
               GetOwner()->GetOuterWindow()->GetInProcessTop()) {
         if (nsCOMPtr<nsPIDOMWindowInner> topInner =
                 topWindow->GetCurrentInnerWindow()) {
-          suspendedDoc = topWindow->GetExtantDoc();
-          autoSuppress.emplace(topWindow->GetBrowsingContext());
+          mSuspendedDoc = topWindow->GetExtantDoc();
+          if (mSuspendedDoc) {
+            mSuspendedDoc->SuppressEventHandling();
+          }
           topInner->Suspend();
           mResumeTimeoutRunnable = new nsResumeTimeoutsEvent(topInner);
         }
       }
     }
 
     SuspendEventDispatching();
     StopProgressEventTimer();
+    auto scopeExit = MakeScopeExit([&] {
+      CancelSyncTimeoutTimer();
+      UnsuppressEventHandlingAndResume();
+      ResumeEventDispatching();
+    });
 
     SyncTimeoutType syncTimeoutType = MaybeStartSyncTimeoutTimer();
     if (syncTimeoutType == eErrorOrExpired) {
       Abort();
       aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
       return;
     }
 
-    nsAutoSyncOperation sync(suspendedDoc,
+    nsAutoSyncOperation sync(mSuspendedDoc,
                              SyncOperationBehavior::eSuspendInput);
     if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return;
     }
 
     // Time expired... We should throw.
     if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -299,17 +299,17 @@ class XMLHttpRequestMainThread final : p
 
   nsresult MaybeSilentSendFailure(nsresult aRv);
   void SendInternal(const BodyExtractorBase* aBody,
                     bool aBodyIsDocumentOrString, ErrorResult& aRv);
 
   bool IsCrossSiteCORSRequest() const;
   bool IsDeniedCrossSiteCORSRequest();
 
-  void ResumeTimeout();
+  void UnsuppressEventHandlingAndResume();
 
   void MaybeLowerChannelPriority();
 
  public:
   virtual void Send(
       const Nullable<
           DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
           aData,
@@ -674,16 +674,17 @@ class XMLHttpRequestMainThread final : p
 
   // Timeout support
   PRTime mRequestSentTime;
   uint32_t mTimeoutMilliseconds;
   nsCOMPtr<nsITimer> mTimeoutTimer;
   void StartTimeoutTimer();
   void HandleTimeoutCallback();
 
+  RefPtr<Document> mSuspendedDoc;
   nsCOMPtr<nsIRunnable> mResumeTimeoutRunnable;
 
   nsCOMPtr<nsITimer> mSyncTimeoutTimer;
 
   enum SyncTimeoutType { eErrorOrExpired, eTimerStarted, eNoTimerNeeded };
 
   SyncTimeoutType MaybeStartSyncTimeoutTimer();
   void HandleSyncTimeoutTimer();