mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-22 12:04:38 +00:00
Backout bcac58cbf328 & 9c75f0428f8a (bug 775965) for causing bug 782981
This commit is contained in:
parent
4ca9719626
commit
83e4908d83
@ -288,7 +288,6 @@ NS_INTERFACE_MAP_END
|
||||
|
||||
nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
|
||||
: mOwnerContent(aOwner)
|
||||
, mDetachedSubdocViews(nullptr)
|
||||
, mDepthTooGreat(false)
|
||||
, mIsTopLevelContent(false)
|
||||
, mDestroyCalled(false)
|
||||
@ -2378,18 +2377,3 @@ nsFrameLoader::SetRemoteBrowser(nsITabParent* 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;
|
||||
}
|
||||
|
||||
|
@ -268,25 +268,6 @@ public:
|
||||
*/
|
||||
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);
|
||||
@ -345,16 +326,6 @@ public:
|
||||
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;
|
||||
|
@ -2361,13 +2361,13 @@ nsRootPresContext::~nsRootPresContext()
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::RegisterPluginForGeometryUpdates(nsIContent* aPlugin)
|
||||
nsRootPresContext::RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.PutEntry(aPlugin);
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::UnregisterPluginForGeometryUpdates(nsIContent* aPlugin)
|
||||
nsRootPresContext::UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.RemoveEntry(aPlugin);
|
||||
}
|
||||
@ -2382,14 +2382,10 @@ struct PluginGeometryClosure {
|
||||
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();
|
||||
@ -2670,13 +2666,9 @@ nsRootPresContext::RequestUpdatePluginGeometry(nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1227,13 +1227,13 @@ public:
|
||||
* 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
|
||||
@ -1337,7 +1337,7 @@ protected:
|
||||
|
||||
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
|
||||
|
@ -431,7 +431,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
|
||||
}
|
||||
#endif
|
||||
|
||||
rpc->RegisterPluginForGeometryUpdates(mContent);
|
||||
rpc->RegisterPluginForGeometryUpdates(this);
|
||||
rpc->RequestUpdatePluginGeometry(this);
|
||||
|
||||
// Here we set the background color for this widget because some plugins will use
|
||||
@ -451,7 +451,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
|
||||
FixupWindow(GetContentRectRelativeToSelf().Size());
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
rpc->RegisterPluginForGeometryUpdates(mContent);
|
||||
rpc->RegisterPluginForGeometryUpdates(this);
|
||||
rpc->RequestUpdatePluginGeometry(this);
|
||||
#endif
|
||||
}
|
||||
@ -739,26 +739,32 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2213,7 +2219,7 @@ nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*)
|
||||
"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
|
||||
@ -2239,7 +2245,7 @@ nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
|
||||
objectFrame->CallSetWindow();
|
||||
|
||||
// Register for geometry updates and make a request.
|
||||
rootPC->RegisterPluginForGeometryUpdates(aContent);
|
||||
rootPC->RegisterPluginForGeometryUpdates(objectFrame);
|
||||
rootPC->RequestUpdatePluginGeometry(objectFrame);
|
||||
}
|
||||
}
|
||||
|
@ -117,12 +117,6 @@ private:
|
||||
nsWeakFrame mFrame;
|
||||
};
|
||||
|
||||
static void
|
||||
InsertViewsInReverseOrder(nsIView* aSibling, nsIView* aParent);
|
||||
|
||||
static void
|
||||
EndSwapDocShellsForViews(nsIView* aView);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
@ -152,28 +146,6 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||
}
|
||||
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.
|
||||
@ -786,49 +758,6 @@ NS_NewSubDocumentFrame(nsIPresShell* aPresShell, nsStyleContext* 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)
|
||||
{
|
||||
@ -836,27 +765,19 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
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()
|
||||
{
|
||||
|
@ -119,9 +119,8 @@ protected:
|
||||
|
||||
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
|
||||
|
@ -14,7 +14,6 @@ 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 \
|
||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user