mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-02-07 09:31:28 +00:00
#416: M1362924
This commit is contained in:
parent
b1cfd7830c
commit
61ec438893
@ -629,6 +629,15 @@ nsDocumentViewer::Init(nsIWidget* aParentWidget,
|
||||
nsresult
|
||||
nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow)
|
||||
{
|
||||
// We assert this because initializing the pres shell could otherwise cause
|
||||
// re-entrancy into nsDocumentViewer methods, which might cause a different
|
||||
// pres shell to be created. Callers of InitPresentationStuff should ensure
|
||||
// the call is appropriately bounded by an nsAutoScriptBlocker to decide
|
||||
// when it is safe for these re-entrant calls to be made.
|
||||
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
|
||||
"InitPresentationStuff must only be called when scripts are "
|
||||
"blocked");
|
||||
|
||||
if (GetIsPrintPreview())
|
||||
return NS_OK;
|
||||
|
||||
@ -1652,6 +1661,10 @@ nsDocumentViewer::Destroy()
|
||||
|
||||
// The document was not put in the bfcache
|
||||
|
||||
// Protect against pres shell destruction running scripts and re-entrantly
|
||||
// creating a new presentation.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (mPresShell) {
|
||||
DestroyPresShell();
|
||||
}
|
||||
@ -1817,6 +1830,10 @@ nsDocumentViewer::SetDocumentInternal(nsIDocument* aDocument,
|
||||
|
||||
// Replace the current pres shell with a new shell for the new document
|
||||
|
||||
// Protect against pres shell destruction running scripts and re-entrantly
|
||||
// creating a new presentation.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (mPresShell) {
|
||||
DestroyPresShell();
|
||||
}
|
||||
@ -2014,7 +2031,17 @@ nsDocumentViewer::Show(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Hold on to the document so we can use it after the script blocker below
|
||||
// has been released (which might re-entrantly call into other
|
||||
// nsDocumentViewer methods).
|
||||
nsCOMPtr<nsIDocument> document = mDocument;
|
||||
|
||||
if (mDocument && !mPresShell) {
|
||||
// The InitPresentationStuff call below requires a script blocker, because
|
||||
// its PresShell::Initialize call can cause scripts to run and therefore
|
||||
// re-entrant calls to nsDocumentViewer methods to be made.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
NS_ASSERTION(!mWindow, "Window already created but no presshell?");
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
||||
@ -2076,7 +2103,7 @@ nsDocumentViewer::Show(void)
|
||||
|
||||
// Notify observers that a new page has been shown. This will get run
|
||||
// from the event loop after we actually draw the page.
|
||||
NS_DispatchToMainThread(new nsDocumentShownDispatcher(mDocument));
|
||||
NS_DispatchToMainThread(new nsDocumentShownDispatcher(document));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2113,24 +2140,23 @@ nsDocumentViewer::Hide(void)
|
||||
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||
}
|
||||
|
||||
{
|
||||
// Do not run ScriptRunners queued by DestroyPresShell() in the intermediate
|
||||
// state before we're done destroying PresShell, PresContext, ViewManager, etc.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
DestroyPresShell();
|
||||
// Do not run ScriptRunners queued by DestroyPresShell() in the intermediate
|
||||
// state before we're done destroying PresShell, PresContext, ViewManager, etc.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
DestroyPresContext();
|
||||
DestroyPresShell();
|
||||
|
||||
mViewManager = nullptr;
|
||||
mWindow = nullptr;
|
||||
mDeviceContext = nullptr;
|
||||
mParentWidget = nullptr;
|
||||
DestroyPresContext();
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
||||
mViewManager = nullptr;
|
||||
mWindow = nullptr;
|
||||
mDeviceContext = nullptr;
|
||||
mParentWidget = nullptr;
|
||||
|
||||
if (base_win && !mAttachedToParent) {
|
||||
base_win->SetParentWidget(nullptr);
|
||||
}
|
||||
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
||||
|
||||
if (base_win && !mAttachedToParent) {
|
||||
base_win->SetParentWidget(nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -4153,9 +4179,14 @@ nsDocumentViewer::SetIsPrintPreview(bool aIsPrintPreview)
|
||||
SetIsPrintingInDocShellTree(docShell, aIsPrintPreview, true);
|
||||
}
|
||||
if (!aIsPrintPreview) {
|
||||
// Dispatch the 'afterprint' event now, if pending:
|
||||
mBeforeAndAfterPrint = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Protect against pres shell destruction running scripts.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (!aIsPrintPreview) {
|
||||
if (mPresShell) {
|
||||
DestroyPresShell();
|
||||
@ -4284,6 +4315,11 @@ NS_IMETHODIMP nsDocumentViewer::SetPageMode(bool aPageMode, nsIPrintSettings* aP
|
||||
// reftests that require a paginated context
|
||||
mIsPageMode = aPageMode;
|
||||
|
||||
// The DestroyPresShell call requires a script blocker, since the
|
||||
// PresShell::Destroy call it does can cause scripts to run, which could
|
||||
// re-entrantly call methods on the nsDocumentViewer.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (mPresShell) {
|
||||
DestroyPresShell();
|
||||
}
|
||||
@ -4344,6 +4380,13 @@ nsDocumentViewer::SetIsHidden(bool aHidden)
|
||||
void
|
||||
nsDocumentViewer::DestroyPresShell()
|
||||
{
|
||||
// We assert this because destroying the pres shell could otherwise cause
|
||||
// re-entrancy into nsDocumentViewer methods, and all callers of
|
||||
// DestroyPresShell need to do other cleanup work afterwards before it
|
||||
// is safe for those re-entrant method calls to be made.
|
||||
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
|
||||
"DestroyPresShell must only be called when scripts are blocked");
|
||||
|
||||
// Break circular reference (or something)
|
||||
mPresShell->EndObservingDocument();
|
||||
|
||||
@ -4351,7 +4394,6 @@ nsDocumentViewer::DestroyPresShell()
|
||||
if (selection && mSelectionListener)
|
||||
selection->RemoveSelectionListener(mSelectionListener);
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPresShell->Destroy();
|
||||
mPresShell = nullptr;
|
||||
}
|
||||
@ -4380,6 +4422,10 @@ nsDocumentViewer::SetPrintPreviewPresentation(nsViewManager* aViewManager,
|
||||
nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
// Protect against pres shell destruction running scripts and re-entrantly
|
||||
// creating a new presentation.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
if (mPresShell) {
|
||||
DestroyPresShell();
|
||||
}
|
||||
|
@ -1601,6 +1601,24 @@ PresShell::EndObservingDocument()
|
||||
char* nsPresShell_ReflowStackPointerTop;
|
||||
#endif
|
||||
|
||||
class XBLConstructorRunner : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit XBLConstructorRunner(nsIDocument* aDocument)
|
||||
: mDocument(aDocument)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
mDocument->BindingManager()->ProcessAttachedQueue();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
};
|
||||
|
||||
nsresult
|
||||
PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
@ -1698,24 +1716,14 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
||||
mFrameConstructor->EndUpdate();
|
||||
}
|
||||
|
||||
// nsAutoScriptBlocker going out of scope may have killed us too
|
||||
// nsAutoCauseReflowNotifier (which sets up a script blocker) going out of
|
||||
// scope may have killed us too
|
||||
NS_ENSURE_STATE(!mHaveShutDown);
|
||||
|
||||
// Run the XBL binding constructors for any new frames we've constructed
|
||||
mDocument->BindingManager()->ProcessAttachedQueue();
|
||||
|
||||
// Constructors may have killed us too
|
||||
NS_ENSURE_STATE(!mHaveShutDown);
|
||||
|
||||
// Now flush out pending restyles before we actually reflow, in
|
||||
// case XBL constructors changed styles somewhere.
|
||||
{
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
mPresContext->RestyleManager()->ProcessPendingRestyles();
|
||||
}
|
||||
|
||||
// And that might have run _more_ XBL constructors
|
||||
NS_ENSURE_STATE(!mHaveShutDown);
|
||||
// Run the XBL binding constructors for any new frames we've constructed.
|
||||
// (Do this in a script runner, since our caller might have a script
|
||||
// blocker on the stack.)
|
||||
nsContentUtils::AddScriptRunner(new XBLConstructorRunner(mDocument));
|
||||
}
|
||||
|
||||
NS_ASSERTION(rootFrame, "How did that happen?");
|
||||
|
Loading…
x
Reference in New Issue
Block a user