Flush layout before starting to pump data into plug-ins if we started the data

load ourselves.  Fixes various issues with a number of plug-ins that expect
NPP_SetWindow() to have been called before NPP_WriteReady or NPP_Write.  Bug
381512, r=biesi, sr=jst
This commit is contained in:
bzbarsky@mit.edu 2007-08-02 10:54:36 -07:00
parent 642110d085
commit 40f1f36bf8
4 changed files with 21 additions and 11 deletions

View File

@ -128,7 +128,7 @@ nsAsyncInstantiateEvent::Run()
// the type here - GetFrame() only returns object frames, and that means we're
// a plugin)
// Also make sure that we still refer to the same data.
if (mContent->GetFrame() == mFrame &&
if (mContent->GetFrame(PR_FALSE) == mFrame &&
mContent->mURI == mURI &&
mContent->mContentType.Equals(mContentType)) {
if (LOG_ENABLED()) {
@ -455,7 +455,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte
notifier.Notify();
}
nsIObjectFrame* frame;
frame = GetFrame();
frame = GetFrame(PR_TRUE);
if (!frame) {
// Do nothing in this case: This is probably due to a display:none
// frame. If we ever get a frame, HasNewFrame will do the right thing.
@ -577,7 +577,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance)
return NS_OK;
}
nsIObjectFrame* frame = GetFrame();
nsIObjectFrame* frame = GetFrame(PR_FALSE);
if (frame) {
// If we have a frame, we may have pending instantiate events; revoke
// them.
@ -614,7 +614,7 @@ nsObjectLoadingContent::EnsureInstantiation(nsIPluginInstance** aInstance)
mInstantiating = PR_FALSE;
frame = GetFrame();
frame = GetFrame(PR_FALSE);
if (!frame) {
return NS_OK;
}
@ -1369,7 +1369,7 @@ nsObjectLoadingContent::GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI)
}
nsIObjectFrame*
nsObjectLoadingContent::GetFrame()
nsObjectLoadingContent::GetFrame(PRBool aFlushLayout)
{
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
@ -1399,7 +1399,9 @@ nsObjectLoadingContent::GetFrame()
// OK, let's flush out and try again. Note that we want to reget
// the document, etc, since flushing might run script.
doc->FlushPendingNotifications(Flush_ContentAndNotify);
mozFlushType flushType =
aFlushLayout ? Flush_Layout : Flush_ContentAndNotify;
doc->FlushPendingNotifications(flushType);
flushed = PR_TRUE;
} while (1);
@ -1412,7 +1414,7 @@ nsObjectLoadingContent::GetFrame()
nsresult
nsObjectLoadingContent::Instantiate(const nsACString& aMIMEType, nsIURI* aURI)
{
nsIObjectFrame* frame = GetFrame();
nsIObjectFrame* frame = GetFrame(PR_FALSE);
if (!frame) {
LOG(("OBJLC [%p]: Attempted to instantiate, but have no frame\n", this));
return NS_OK; // Not a failure to have no frame

View File

@ -277,9 +277,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
/**
* Gets the frame that's associated with this content node in
* presentation 0.
* presentation 0. If aFlushLayout is true, this function will
* flush layout before trying to get the frame. This is needed
* in some cases by plug-ins to ensure that NPP_SetWindow() gets
* called (from nsObjectFrame::DidReflow).
*/
nsIObjectFrame* GetFrame();
nsIObjectFrame* GetFrame(PRBool aFlushLayout);
/**
* Instantiates the plugin. This differs from GetFrame()->Instantiate() in

View File

@ -96,7 +96,7 @@ nsPluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
return rv;
}
nsIContent* embed = mPluginDoc->GetPluginContent();
nsCOMPtr<nsIContent> embed = mPluginDoc->GetPluginContent();
// Now we have a frame for our <embed>, start the load
nsIPresShell* shell = mDocument->GetPrimaryShell();
@ -105,6 +105,11 @@ nsPluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
return NS_BINDING_ABORTED;
}
// Flush out layout before we go to instantiate, because some
// plug-ins depend on NPP_SetWindow() being called early enough and
// nsObjectFrame does that at the end of reflow.
shell->FlushPendingNotifications(Flush_Layout);
nsIFrame* frame = shell->GetPrimaryFrameFor(embed);
if (!frame) {
return rv;

View File

@ -967,7 +967,7 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
}
// this will call pi->SetWindow and take care of window subclassing
// if needed, see bug 132759
// if needed, see bug 132759.
window->CallSetWindow(pi);
mInstanceOwner->ReleasePluginPort((nsPluginPort *)window->window);