Bug 1261230. r=mats, a=ritu
authorTimothy Nikkel <tnikkel@gmail.com>
Fri, 13 May 2016 06:09:38 +0200
changeset 461580 4290826b078c0b34517f371d4c40ff6d451b799c
parent 461579 45a59425b49837514fc1f656a1acd53c71a4ffc7
child 461581 f6414e3aa3fef7103b4a133e061358ad3432e6c8
push id41669
push userbmo:mtabara@mozilla.com
push dateMon, 16 Jan 2017 18:05:57 +0000
reviewersmats, ritu
bugs1261230
milestone45.1.0
Bug 1261230. r=mats, a=ritu
layout/generic/nsSubDocumentFrame.cpp
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -130,27 +130,27 @@ nsSubDocumentFrame::Init(nsIContent*    
   // it into the view tree. This happens when we've been reframed, and
   // ensures the presentation persists across reframes. If the frame element
   // has changed documents however, we blow away the presentation.
   RefPtr<nsFrameLoader> frameloader = FrameLoader();
   if (frameloader) {
     nsCOMPtr<nsIDocument> oldContainerDoc;
     nsView* detachedViews =
       frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
+    frameloader->SetDetachedSubdocView(nullptr, nullptr);
     if (detachedViews) {
       if (oldContainerDoc == aContent->OwnerDoc()) {
         // Restore stashed presentation.
         ::InsertViewsInReverseOrder(detachedViews, mInnerView);
         ::EndSwapDocShellsForViews(mInnerView->GetFirstChild());
       } else {
         // Presentation is for a different document, don't restore it.
         frameloader->Hide();
       }
     }
-    frameloader->SetDetachedSubdocView(nullptr, nullptr);
   }
 
   nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
 }
 
 void
 nsSubDocumentFrame::ShowViewer()
 {
@@ -945,23 +945,26 @@ public:
   NS_IMETHOD Run()
   {
     // Flush frames, to ensure any pending display:none changes are made.
     // Note it can be unsafe to flush if we've destroyed the presentation
     // for some other reason, like if we're shutting down.
     if (!mPresShell->IsDestroying()) {
       mPresShell->FlushPendingNotifications(Flush_Frames);
     }
+
+    // Either the frame has been constructed by now, or it never will be,
+    // either way we want to clear the stashed views.
+    mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
+
     nsSubDocumentFrame* frame = do_QueryFrame(mFrameElement->GetPrimaryFrame());
     if ((!frame && mHideViewerIfFrameless) ||
         mPresShell->IsDestroying()) {
       // Either the frame element has no nsIFrame or the presshell is being
-      // destroyed. Hide the nsFrameLoader, which destroys the presentation,
-      // and clear our references to the stashed presentation.
-      mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
+      // destroyed. Hide the nsFrameLoader, which destroys the presentation.
       mFrameLoader->Hide();
     }
     return NS_OK;
   }
 private:
   nsCOMPtr<nsIContent> mFrameElement;
   RefPtr<nsFrameLoader> mFrameLoader;
   nsCOMPtr<nsIPresShell> mPresShell;
@@ -977,26 +980,26 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame
   if (mPostedReflowCallback) {
     PresContext()->PresShell()->CancelReflowCallback(this);
     mPostedReflowCallback = false;
   }
 
   // Detach the subdocument's views and stash them in the frame loader.
   // We can then reattach them if we're being reframed (for example if
   // the frame has been made position:fixed).
-  nsFrameLoader* frameloader = FrameLoader();
+  RefPtr<nsFrameLoader> frameloader = FrameLoader();
   if (frameloader) {
     nsView* detachedViews = ::BeginSwapDocShellsForViews(mInnerView->GetFirstChild());
     frameloader->SetDetachedSubdocView(detachedViews, mContent->OwnerDoc());
 
     // We call nsFrameLoader::HideViewer() in a script runner so that we can
     // safely determine whether the frame is being reframed or destroyed.
     nsContentUtils::AddScriptRunner(
       new nsHideViewer(mContent,
-                       mFrameLoader,
+                       frameloader,
                        PresContext()->PresShell(),
                        (mDidCreateDoc || mCallingShow)));
   }
 
   nsLeafFrame::DestroyFrom(aDestructRoot);
 }
 
 CSSIntSize