Backout bcac58cbf328 & 9c75f0428f8a (bug 775965) for causing bug 782981
authorEd Morley <emorley@mozilla.com>
Wed, 15 Aug 2012 18:10:55 +0100
changeset 108398 7d4268f8884cef2e331e46b7e64da81a5adc66b0
parent 108397 9c67b2ff95b76bcaa8e96e16209f5b01ffaebd4a
child 108399 131799806373850d8330f278a04f7f55480f634a
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs775965, 782981
milestone17.0a1
backs outbcac58cbf3280af21b0845639734a48e6b228167
first release with
nightly linux32
7d4268f8884c / 17.0a1 / 20120815101724 / files
nightly linux64
7d4268f8884c / 17.0a1 / 20120815101724 / files
nightly mac
7d4268f8884c / 17.0a1 / 20120815101724 / files
nightly win32
7d4268f8884c / 17.0a1 / 20120815101724 / files
nightly win64
7d4268f8884c / 17.0a1 / 20120815101724 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout bcac58cbf328 & 9c75f0428f8a (bug 775965) for causing bug 782981
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/generic/nsObjectFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsSubDocumentFrame.h
layout/generic/test/Makefile.in
layout/generic/test/test_contained_plugin_transplant.html
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -283,17 +283,16 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrame
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
   NS_INTERFACE_MAP_ENTRY(nsIFrameLoader)
   NS_INTERFACE_MAP_ENTRY(nsIContentViewManager)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFrameLoader)
 NS_INTERFACE_MAP_END
 
 nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
   : mOwnerContent(aOwner)
-  , mDetachedSubdocViews(nullptr)
   , mDepthTooGreat(false)
   , mIsTopLevelContent(false)
   , mDestroyCalled(false)
   , mNeedsAsyncDestroy(false)
   , mInSwap(false)
   , mInShow(false)
   , mHideCalled(false)
   , mNetworkCreated(aNetworkCreated)
@@ -2373,23 +2372,8 @@ nsFrameLoader::SetRemoteBrowser(nsITabPa
 {
   MOZ_ASSERT(!mRemoteBrowser);
   MOZ_ASSERT(!mCurrentRemoteFrame);
   mRemoteBrowser = static_cast<TabParent*>(aTabParent);
 
   ShowRemoteFrame(nsIntSize(0, 0));
 }
 
-void
-nsFrameLoader::SetDetachedSubdocView(nsIView* aDetachedViews,
-                                     nsIDocument* aContainerDoc)
-{
-  mDetachedSubdocViews = aDetachedViews;
-  mContainerDocWhileDetached = aContainerDoc;
-}
-
-nsIView*
-nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
-{
-  NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
-  return mDetachedSubdocViews;
-}
-
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -263,35 +263,16 @@ public:
    *
    * This will assert if mRemoteBrowser or mCurrentRemoteFrame is non-null.  In
    * practice, this means you can't have successfully run TryRemoteBrowser() on
    * this object, which means you can't have called ShowRemoteFrame() or
    * ReallyStartLoading().
    */
   void SetRemoteBrowser(nsITabParent* aTabParent);
 
-  /**
-   * Stashes a detached view on the frame loader. We do this when we're
-   * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
-   * being reframed we'll restore the detached view when it's recreated,
-   * otherwise we'll discard the old presentation and set the detached
-   * subdoc view to null. aContainerDoc is the document containing the
-   * the subdoc frame. This enables us to detect when the containing
-   * document has changed during reframe, so we can discard the presentation 
-   * in that case.
-   */
-  void SetDetachedSubdocView(nsIView* aDetachedView,
-                             nsIDocument* aContainerDoc);
-
-  /**
-   * Retrieves the detached view and the document containing the view,
-   * as set by SetDetachedSubdocView().
-   */
-  nsIView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
-
 private:
 
   void SetOwnerContent(mozilla::dom::Element* aContent);
 
   bool ShouldUseRemoteProcess();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozbrowser> or
@@ -340,26 +321,16 @@ private:
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   mozilla::dom::Element* mOwnerContent; // WEAK
 public:
   // public because a callback needs these.
   nsRefPtr<nsFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
 private:
-  // Stores the root view of the subdocument while the subdocument is being
-  // reframed. Used to restore the presentation after reframing.
-  nsIView* mDetachedSubdocViews;
-  // Stores the containing document of the frame corresponding to this
-  // frame loader. This is reference is kept valid while the subframe's
-  // presentation is detached and stored in mDetachedSubdocViews. This
-  // enables us to detect whether the frame has moved documents during
-  // a reframe, so that we know not to restore the presentation.
-  nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
-
   bool mDepthTooGreat : 1;
   bool mIsTopLevelContent : 1;
   bool mDestroyCalled : 1;
   bool mNeedsAsyncDestroy : 1;
   bool mInSwap : 1;
   bool mInShow : 1;
   bool mHideCalled : 1;
   // True when the object is created for an element which the parser has
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2356,45 +2356,41 @@ nsRootPresContext::~nsRootPresContext()
 {
   NS_ASSERTION(mRegisteredPlugins.Count() == 0,
                "All plugins should have been unregistered");
   CancelDidPaintTimer();
   CancelUpdatePluginGeometryTimer();
 }
 
 void
-nsRootPresContext::RegisterPluginForGeometryUpdates(nsIContent* aPlugin)
+nsRootPresContext::RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
 {
   mRegisteredPlugins.PutEntry(aPlugin);
 }
 
 void
-nsRootPresContext::UnregisterPluginForGeometryUpdates(nsIContent* aPlugin)
+nsRootPresContext::UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
 {
   mRegisteredPlugins.RemoveEntry(aPlugin);
 }
 
 struct PluginGeometryClosure {
   nsIFrame* mRootFrame;
   PRInt32   mRootAPD;
   nsIFrame* mChangedSubtree;
   nsRect    mChangedRect;
   nsTHashtable<nsPtrHashKey<nsObjectFrame> > mAffectedPlugins;
   nsRect    mAffectedPluginBounds;
   nsTArray<nsIWidget::Configuration>* mOutputConfigurations;
 };
 static PLDHashOperator
-PluginBoundsEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
+PluginBoundsEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
 {
   PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
-  nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
-  if (!f) {
-    NS_WARNING("Null frame in PluginBoundsEnumerator");
-    return PL_DHASH_NEXT;
-  }
+  nsObjectFrame* f = aEntry->GetKey();
   nsRect fBounds = f->GetContentRect() +
       f->GetParent()->GetOffsetToCrossDoc(closure->mRootFrame);
   PRInt32 APD = f->PresContext()->AppUnitsPerDevPixel();
   fBounds = fBounds.ConvertAppUnitsRoundOut(APD, closure->mRootAPD);
   // We're identifying the plugins that may have been affected by changes
   // to the frame subtree rooted at aChangedRoot. Any plugin that overlaps
   // the overflow area of aChangedRoot could have its clip region affected
   // because it might be covered (or uncovered) by changes to the subtree.
@@ -2665,23 +2661,19 @@ nsRootPresContext::RequestUpdatePluginGe
       return;
     mUpdatePluginGeometryForFrame->PresContext()->
       SetContainsUpdatePluginGeometryFrame(false);
     mUpdatePluginGeometryForFrame = nullptr;
   }
 }
 
 static PLDHashOperator
-PluginDidSetGeometryEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
+PluginDidSetGeometryEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
 {
-  nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
-  if (!f) {
-    NS_WARNING("Null frame in PluginDidSetGeometryEnumerator");
-    return PL_DHASH_NEXT;
-  }
+  nsObjectFrame* f = aEntry->GetKey();
   f->DidSetWidgetGeometry();
   return PL_DHASH_NEXT;
 }
 
 void
 nsRootPresContext::DidApplyPluginGeometryUpdates()
 {
   mRegisteredPlugins.EnumerateEntries(PluginDidSetGeometryEnumerator, nullptr);
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1222,23 +1222,23 @@ public:
   }
 
   /**
    * Registers a plugin to receive geometry updates (position and clip
    * region) so it can update its widget.
    * Callers must call UnregisterPluginForGeometryUpdates before
    * the aPlugin frame is destroyed.
    */
-  void RegisterPluginForGeometryUpdates(nsIContent* aPlugin);
+  void RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
   /**
    * Stops a plugin receiving geometry updates (position and clip
    * region). If the plugin was not already registered, this does
    * nothing.
    */
-  void UnregisterPluginForGeometryUpdates(nsIContent* aPlugin);
+  void UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
 
   /**
    * Iterate through all plugins that are registered for geometry updates
    * and update their position and clip region to match the current frame
    * tree.
    */
   void UpdatePluginGeometry();
 
@@ -1332,17 +1332,17 @@ protected:
     if (mUpdatePluginGeometryTimer) {
       mUpdatePluginGeometryTimer->Cancel();
       mUpdatePluginGeometryTimer = nullptr;
     }
   }
 
   nsCOMPtr<nsITimer> mNotifyDidPaintTimer;
   nsCOMPtr<nsITimer> mUpdatePluginGeometryTimer;
-  nsTHashtable<nsRefPtrHashKey<nsIContent> > mRegisteredPlugins;
+  nsTHashtable<nsPtrHashKey<nsObjectFrame> > mRegisteredPlugins;
   // if mNeedsToUpdatePluginGeometry is set, then this is the frame to
   // use as the root of the subtree to search for plugin updates, or
   // null to use the root frame of this prescontext
   nsTArray<nsCOMPtr<nsIRunnable> > mWillPaintObservers;
   nsRevocableEventPtr<RunWillPaintObservers> mWillPaintFallbackEvent;
   nsIFrame* mUpdatePluginGeometryForFrame;
   PRUint32 mDOMGeneration;
   bool mNeedsToUpdatePluginGeometry;
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -426,17 +426,17 @@ nsObjectFrame::PrepForDrawing(nsIWidget 
     // On Mac, we need to invalidate ourselves since even windowed
     // plugins are painted through Thebes and we need to ensure
     // the Thebes layer containing the plugin is updated.
     if (parentWidget == GetNearestWidget()) {
       Invalidate(GetContentRectRelativeToSelf());
     }
 #endif
 
-    rpc->RegisterPluginForGeometryUpdates(mContent);
+    rpc->RegisterPluginForGeometryUpdates(this);
     rpc->RequestUpdatePluginGeometry(this);
 
     // Here we set the background color for this widget because some plugins will use 
     // the child window background color when painting. If it's not set, it may default to gray
     // Sometimes, a frame doesn't have a background color or is transparent. In this
     // case, walk up the frame tree until we do find a frame with a background color
     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
       nscolor bgcolor =
@@ -446,17 +446,17 @@ nsObjectFrame::PrepForDrawing(nsIWidget 
         break;
       }
     }
   } else {
     // Changing to windowless mode changes the NPWindow geometry.
     FixupWindow(GetContentRectRelativeToSelf().Size());
 
 #ifndef XP_MACOSX
-    rpc->RegisterPluginForGeometryUpdates(mContent);
+    rpc->RegisterPluginForGeometryUpdates(this);
     rpc->RequestUpdatePluginGeometry(this);
 #endif
   }
 
   if (!IsHidden()) {
     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
   }
 
@@ -734,36 +734,42 @@ nsObjectFrame::CallSetWindow(bool aCheck
 
   return rv;
 }
 
 void
 nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
 {
   mInstanceOwner = aOwner;
-  if (mInstanceOwner) {
-    return;
-  }
-  nsRootPresContext* rpc = PresContext()->GetRootPresContext();
-  if (rpc) {
-    rpc->UnregisterPluginForGeometryUpdates(mContent);
-  }
-  if (mWidget && mInnerView) {
-    mInnerView->DetachWidgetEventHandler(mWidget);
-    // Make sure the plugin is hidden in case an update of plugin geometry
-    // hasn't happened since this plugin became hidden.
-    nsIWidget* parent = mWidget->GetParent();
-    if (parent) {
-      nsTArray<nsIWidget::Configuration> configurations;
-      this->GetEmptyClipConfiguration(&configurations);
-      parent->ConfigureChildren(configurations);
+  if (!mInstanceOwner) {
+    nsRootPresContext* rpc = PresContext()->GetRootPresContext();
+    if (rpc) {
+      if (mWidget) {
+        if (mInnerView) {
+          mInnerView->DetachWidgetEventHandler(mWidget);
 
-      mWidget->Show(false);
-      mWidget->Enable(false);
-      mWidget->SetParent(nullptr);
+          rpc->UnregisterPluginForGeometryUpdates(this);
+          // Make sure the plugin is hidden in case an update of plugin geometry
+          // hasn't happened since this plugin became hidden.
+          nsIWidget* parent = mWidget->GetParent();
+          if (parent) {
+            nsTArray<nsIWidget::Configuration> configurations;
+            this->GetEmptyClipConfiguration(&configurations);
+            parent->ConfigureChildren(configurations);
+
+            mWidget->Show(false);
+            mWidget->Enable(false);
+            mWidget->SetParent(nullptr);
+          }
+        }
+      } else {
+#ifndef XP_MACOSX
+        rpc->UnregisterPluginForGeometryUpdates(this);
+#endif
+      }
     }
   }
 }
 
 bool
 nsObjectFrame::IsFocusable(PRInt32 *aTabIndex, bool aWithMouse)
 {
   if (aTabIndex)
@@ -2208,17 +2214,17 @@ nsObjectFrame::BeginSwapDocShells(nsICon
   if (!obj)
     return;
 
   nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
   NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(),
                "Plugin windows must not be toplevel");
   nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
   NS_ASSERTION(rootPC, "unable to unregister the plugin frame");
-  rootPC->UnregisterPluginForGeometryUpdates(aContent);
+  rootPC->UnregisterPluginForGeometryUpdates(objectFrame);
 }
 
 /*static*/ void
 nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
 {
   NS_PRECONDITION(aContent, "");
 
   // This function is called from a document content enumerator so we need
@@ -2234,17 +2240,17 @@ nsObjectFrame::EndSwapDocShells(nsIConte
   if (widget) {
     // Reparent the widget.
     nsIWidget* parent =
       rootPC->PresShell()->GetRootFrame()->GetNearestWidget();
     widget->SetParent(parent);
     objectFrame->CallSetWindow();
 
     // Register for geometry updates and make a request.
-    rootPC->RegisterPluginForGeometryUpdates(aContent);
+    rootPC->RegisterPluginForGeometryUpdates(objectFrame);
     rootPC->RequestUpdatePluginGeometry(objectFrame);
   }
 }
 
 nsIFrame*
 NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsObjectFrame(aContext);
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -112,22 +112,16 @@ public:
       static_cast<nsSubDocumentFrame*>(mFrame.GetFrame())->ShowViewer();
     }
     return NS_OK;
   }
 private:
   nsWeakFrame mFrame;
 };
 
-static void
-InsertViewsInReverseOrder(nsIView* aSibling, nsIView* aParent);
-
-static void
-EndSwapDocShellsForViews(nsIView* aView);
-
 NS_IMETHODIMP
 nsSubDocumentFrame::Init(nsIContent*     aContent,
                          nsIFrame*       aParent,
                          nsIFrame*       aPrevInFlow)
 {
   // determine if we are a <frame> or <iframe>
   if (aContent) {
     nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = do_QueryInterface(aContent);
@@ -147,38 +141,16 @@ nsSubDocumentFrame::Init(nsIContent*    
   // really need it or not, and the inner view will get it as the
   // parent.
   if (!HasView()) {
     rv = nsContainerFrame::CreateViewForFrame(this, true);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   EnsureInnerView();
 
-  // If we have a detached subdoc's root view on our frame loader, re-insert
-  // 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.
-  nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
-  if (frameloader) {
-    nsCOMPtr<nsIDocument> oldContainerDoc;
-    nsIView* detachedViews =
-      frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
-    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);
-  }
-
   // Set the primary frame now so that
   // DocumentViewerImpl::FindContainerView called by ShowViewer below
   // can find it if necessary.
   aContent->SetPrimaryFrame(this);
 
   nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
   return NS_OK;
 }
@@ -781,87 +753,36 @@ nsSubDocumentFrame::AttributeChanged(PRI
 nsIFrame*
 NS_NewSubDocumentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSubDocumentFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSubDocumentFrame)
 
-class nsHideViewer : public nsRunnable {
-public:
-  nsHideViewer(nsIContent* aFrameElement,
-               nsFrameLoader* aFrameLoader,
-               nsIPresShell* aPresShell,
-               bool aHideViewerIfFrameless)
-    : mFrameElement(aFrameElement),
-      mFrameLoader(aFrameLoader),
-      mPresShell(aPresShell),
-      mHideViewerIfFrameless(aHideViewerIfFrameless)
-  {
-    NS_ASSERTION(mFrameElement, "Must have a frame element");
-    NS_ASSERTION(mFrameLoader, "Must have a frame loader");
-    NS_ASSERTION(mPresShell, "Must have a presshell");
-  }
-
-  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);
-    }
-    nsIFrame* frame = mFrameElement->GetPrimaryFrame();
-    if (!frame && mHideViewerIfFrameless) {
-      // The frame element has no nsIFrame. Hide the nsFrameLoader,
-      // which destroys the presentation.
-      mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
-      mFrameLoader->Hide();
-   }
-    return NS_OK;
-  }
-private:
-  nsCOMPtr<nsIContent> mFrameElement;
-  nsRefPtr<nsFrameLoader> mFrameLoader;
-  nsCOMPtr<nsIPresShell> mPresShell;
-  bool mHideViewerIfFrameless;
-};
-
-static nsIView*
-BeginSwapDocShellsForViews(nsIView* aSibling);
-
 void
 nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   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();
-  if (frameloader) {
-    nsIView* 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,
-                       PresContext()->PresShell(),
-                       (mDidCreateDoc || mCallingShow)));
-  }
+  
+  HideViewer();
 
   nsLeafFrame::DestroyFrom(aDestructRoot);
 }
 
+void
+nsSubDocumentFrame::HideViewer()
+{
+  if (mFrameLoader && (mDidCreateDoc || mCallingShow))
+    mFrameLoader->Hide();
+}
+
 nsIntSize
 nsSubDocumentFrame::GetMarginAttributes()
 {
   nsIntSize result(-1, -1);
   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
   if (content) {
     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::marginwidth);
     if (attr && attr->Type() == nsAttrValue::eInteger)
--- a/layout/generic/nsSubDocumentFrame.h
+++ b/layout/generic/nsSubDocumentFrame.h
@@ -114,19 +114,18 @@ protected:
 
   bool IsInline() { return mIsInline; }
 
   virtual nscoord GetIntrinsicWidth();
   virtual nscoord GetIntrinsicHeight();
 
   virtual int GetSkipSides() const;
 
-  // Show our document viewer. The document viewer is hidden via a script
-  // runner, so that we can save and restore the presentation if we're
-  // being reframed.
+  // Hide or show our document viewer
+  void HideViewer();
   void ShowViewer();
 
   /* Obtains the frame we should use for intrinsic size information if we are
    * an HTML <object>, <embed> or <applet> (a replaced element - not <iframe>)
    * and our sub-document has an intrinsic size. The frame returned is the
    * frame for the document element of the document we're embedding.
    *
    * Called "Obtain*" and not "Get*" because of comment on GetDocShell that
--- a/layout/generic/test/Makefile.in
+++ b/layout/generic/test/Makefile.in
@@ -9,17 +9,16 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 # in the list below, we make sure that the tests that require focus
 # run before test_plugin_clipping, which can steal focus for its window.
 MOCHITEST_FILES = \
-  test_contained_plugin_transplant.html \
   bug344830_testembed.svg \
   plugin_clipping_helper.xhtml \
   plugin_clipping_helper2.xhtml \
   plugin_clipping_helper_transformed.xhtml \
   plugin_clipping_helper_table.xhtml \
   plugin_clipping_lib.js \
   plugin_focus_helper.html \
   test_bug240933.html \
deleted file mode 100644
--- a/layout/generic/test/test_contained_plugin_transplant.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=775965
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 775965</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="run();">
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775965">Mozilla Bug 775965</a>
-<p id="display"></p>
-<div id="content">
-
-<iframe id="iframe1" src="data:text/html,<embed type='application/x-test' width='200' height='200'></embed>"></iframe>
-<iframe id="iframe2"></iframe>
-
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-/** Test for Bug 775965 **/
-SimpleTest.waitForExplicitFinish();
-
-function run() {
-  var iframe1 = document.getElementById("iframe1");
-  var iframe2 = document.getElementById("iframe2");
-  iframe1.parentNode.removeChild(iframe1);
-  iframe1.style.position = "fixed";
-  iframe2.contentDocument.body.appendChild(iframe1);
-  setTimeout(function() { ok(true, "We didn't crash!"); SimpleTest.finish(); }, 0);
-}
-
-
-</script>
-</pre>
-</body>
-</html>