Bug 946641 - Part 1: Clear delayed events on closed documents. (r=smaug)
authorShu-yu Guo <shu@rfrn.org>
Fri, 06 Dec 2013 19:31:09 -0800
changeset 175019 80db40e98167f83a126c93b7550680f28094da56
parent 175018 9765cb37859d228781ddf926382d643c0c513944
child 175020 b7186d67c952d89ec6dab2d0adebab1dadafd340
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs946641
milestone28.0a1
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
Bug 946641 - Part 1: Clear delayed events on closed documents. (r=smaug)
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1278,17 +1278,17 @@ nsGlobalWindow::~nsGlobalWindow()
     // If our outer window's inner window is this window, null out the
     // outer window's reference to this window that's being deleted.
     nsGlobalWindow *outer = GetOuterWindowInternal();
     if (outer) {
       outer->MaybeClearInnerWindow(this);
     }
   }
 
-  mDoc = nullptr;
+  ClearDelayedEventsAndDropDocument();
 
   // Outer windows are always supposed to call CleanUp before letting themselves
   // be destroyed. And while CleanUp generally seems to be intended to clean up
   // outers, we've historically called it for both. Changing this would probably
   // involve auditing all of the references that inners and outers can have, and
   // separating the handling into CleanUp() and FreeInnerObjects.
   if (IsInnerWindow()) {
     CleanUp();
@@ -1350,16 +1350,25 @@ nsGlobalWindow::MaybeForgiveSpamCount()
     SetPopupSpamWindow(false);
     --gOpenPopupSpamCount;
     NS_ASSERTION(gOpenPopupSpamCount >= 0,
                  "Unbalanced decrement of gOpenPopupSpamCount");
   }
 }
 
 void
+nsGlobalWindow::ClearDelayedEventsAndDropDocument()
+{
+  if (mDoc && mDoc->EventHandlingSuppressed()) {
+    mDoc->UnsuppressEventHandlingAndFireEvents(false);
+  }
+  mDoc = nullptr;
+}
+
+void
 nsGlobalWindow::CleanUp()
 {
   // Guarantee idempotence.
   if (mCleanedUp)
     return;
   mCleanedUp = true;
 
   mEventTargetObjects.EnumerateEntries(DisconnectEventTargetObjects, nullptr);
@@ -2768,17 +2777,17 @@ nsGlobalWindow::DetachFromDocShell()
     NS_ASSERTION(mDoc, "Must have doc!");
 
     // Remember the document's principal and URI.
     mDocumentPrincipal = mDoc->NodePrincipal();
     mDocumentURI = mDoc->GetDocumentURI();
     mDocBaseURI = mDoc->GetDocBaseURI();
 
     // Release our document reference
-    mDoc = nullptr;
+    ClearDelayedEventsAndDropDocument();
     mFocusedNode = nullptr;
   }
 
   ClearControllers();
 
   mChromeEventHandler = nullptr; // force release now
 
   if (mContext) {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -973,16 +973,17 @@ protected:
 
   static bool sIdleObserversAPIFuzzTimeDisabled;
 
   friend class HashchangeCallback;
   friend class mozilla::dom::BarProp;
 
   // Object Management
   virtual ~nsGlobalWindow();
+  void ClearDelayedEventsAndDropDocument();
   void CleanUp();
   void ClearControllers();
   nsresult FinalClose();
 
   inline void MaybeClearInnerWindow(nsGlobalWindow* aExpectedInner)
   {
     if(mInnerWindow == aExpectedInner) {
       mInnerWindow = nullptr;