mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-10 11:54:40 +00:00
#416: M1362924
This commit is contained in:
parent
b1cfd7830c
commit
61ec438893
@ -629,6 +629,15 @@ nsDocumentViewer::Init(nsIWidget* aParentWidget,
|
|||||||
nsresult
|
nsresult
|
||||||
nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow)
|
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())
|
if (GetIsPrintPreview())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
@ -1652,6 +1661,10 @@ nsDocumentViewer::Destroy()
|
|||||||
|
|
||||||
// The document was not put in the bfcache
|
// 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) {
|
if (mPresShell) {
|
||||||
DestroyPresShell();
|
DestroyPresShell();
|
||||||
}
|
}
|
||||||
@ -1817,6 +1830,10 @@ nsDocumentViewer::SetDocumentInternal(nsIDocument* aDocument,
|
|||||||
|
|
||||||
// Replace the current pres shell with a new shell for the new document
|
// 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) {
|
if (mPresShell) {
|
||||||
DestroyPresShell();
|
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) {
|
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?");
|
NS_ASSERTION(!mWindow, "Window already created but no presshell?");
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
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
|
// Notify observers that a new page has been shown. This will get run
|
||||||
// from the event loop after we actually draw the page.
|
// from the event loop after we actually draw the page.
|
||||||
NS_DispatchToMainThread(new nsDocumentShownDispatcher(mDocument));
|
NS_DispatchToMainThread(new nsDocumentShownDispatcher(document));
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -2113,24 +2140,23 @@ nsDocumentViewer::Hide(void)
|
|||||||
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
|
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
// Do not run ScriptRunners queued by DestroyPresShell() in the intermediate
|
||||||
// Do not run ScriptRunners queued by DestroyPresShell() in the intermediate
|
// state before we're done destroying PresShell, PresContext, ViewManager, etc.
|
||||||
// state before we're done destroying PresShell, PresContext, ViewManager, etc.
|
nsAutoScriptBlocker scriptBlocker;
|
||||||
nsAutoScriptBlocker scriptBlocker;
|
|
||||||
DestroyPresShell();
|
|
||||||
|
|
||||||
DestroyPresContext();
|
DestroyPresShell();
|
||||||
|
|
||||||
mViewManager = nullptr;
|
DestroyPresContext();
|
||||||
mWindow = nullptr;
|
|
||||||
mDeviceContext = nullptr;
|
|
||||||
mParentWidget = nullptr;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
mViewManager = nullptr;
|
||||||
|
mWindow = nullptr;
|
||||||
|
mDeviceContext = nullptr;
|
||||||
|
mParentWidget = nullptr;
|
||||||
|
|
||||||
if (base_win && !mAttachedToParent) {
|
nsCOMPtr<nsIBaseWindow> base_win(mContainer);
|
||||||
base_win->SetParentWidget(nullptr);
|
|
||||||
}
|
if (base_win && !mAttachedToParent) {
|
||||||
|
base_win->SetParentWidget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -4153,9 +4179,14 @@ nsDocumentViewer::SetIsPrintPreview(bool aIsPrintPreview)
|
|||||||
SetIsPrintingInDocShellTree(docShell, aIsPrintPreview, true);
|
SetIsPrintingInDocShellTree(docShell, aIsPrintPreview, true);
|
||||||
}
|
}
|
||||||
if (!aIsPrintPreview) {
|
if (!aIsPrintPreview) {
|
||||||
|
// Dispatch the 'afterprint' event now, if pending:
|
||||||
mBeforeAndAfterPrint = nullptr;
|
mBeforeAndAfterPrint = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Protect against pres shell destruction running scripts.
|
||||||
|
nsAutoScriptBlocker scriptBlocker;
|
||||||
|
|
||||||
if (!aIsPrintPreview) {
|
if (!aIsPrintPreview) {
|
||||||
if (mPresShell) {
|
if (mPresShell) {
|
||||||
DestroyPresShell();
|
DestroyPresShell();
|
||||||
@ -4284,6 +4315,11 @@ NS_IMETHODIMP nsDocumentViewer::SetPageMode(bool aPageMode, nsIPrintSettings* aP
|
|||||||
// reftests that require a paginated context
|
// reftests that require a paginated context
|
||||||
mIsPageMode = aPageMode;
|
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) {
|
if (mPresShell) {
|
||||||
DestroyPresShell();
|
DestroyPresShell();
|
||||||
}
|
}
|
||||||
@ -4344,6 +4380,13 @@ nsDocumentViewer::SetIsHidden(bool aHidden)
|
|||||||
void
|
void
|
||||||
nsDocumentViewer::DestroyPresShell()
|
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)
|
// Break circular reference (or something)
|
||||||
mPresShell->EndObservingDocument();
|
mPresShell->EndObservingDocument();
|
||||||
|
|
||||||
@ -4351,7 +4394,6 @@ nsDocumentViewer::DestroyPresShell()
|
|||||||
if (selection && mSelectionListener)
|
if (selection && mSelectionListener)
|
||||||
selection->RemoveSelectionListener(mSelectionListener);
|
selection->RemoveSelectionListener(mSelectionListener);
|
||||||
|
|
||||||
nsAutoScriptBlocker scriptBlocker;
|
|
||||||
mPresShell->Destroy();
|
mPresShell->Destroy();
|
||||||
mPresShell = nullptr;
|
mPresShell = nullptr;
|
||||||
}
|
}
|
||||||
@ -4380,6 +4422,10 @@ nsDocumentViewer::SetPrintPreviewPresentation(nsViewManager* aViewManager,
|
|||||||
nsPresContext* aPresContext,
|
nsPresContext* aPresContext,
|
||||||
nsIPresShell* aPresShell)
|
nsIPresShell* aPresShell)
|
||||||
{
|
{
|
||||||
|
// Protect against pres shell destruction running scripts and re-entrantly
|
||||||
|
// creating a new presentation.
|
||||||
|
nsAutoScriptBlocker scriptBlocker;
|
||||||
|
|
||||||
if (mPresShell) {
|
if (mPresShell) {
|
||||||
DestroyPresShell();
|
DestroyPresShell();
|
||||||
}
|
}
|
||||||
|
@ -1601,6 +1601,24 @@ PresShell::EndObservingDocument()
|
|||||||
char* nsPresShell_ReflowStackPointerTop;
|
char* nsPresShell_ReflowStackPointerTop;
|
||||||
#endif
|
#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
|
nsresult
|
||||||
PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
||||||
{
|
{
|
||||||
@ -1698,24 +1716,14 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
|||||||
mFrameConstructor->EndUpdate();
|
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);
|
NS_ENSURE_STATE(!mHaveShutDown);
|
||||||
|
|
||||||
// Run the XBL binding constructors for any new frames we've constructed
|
// Run the XBL binding constructors for any new frames we've constructed.
|
||||||
mDocument->BindingManager()->ProcessAttachedQueue();
|
// (Do this in a script runner, since our caller might have a script
|
||||||
|
// blocker on the stack.)
|
||||||
// Constructors may have killed us too
|
nsContentUtils::AddScriptRunner(new XBLConstructorRunner(mDocument));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(rootFrame, "How did that happen?");
|
NS_ASSERTION(rootFrame, "How did that happen?");
|
||||||
|
Loading…
Reference in New Issue
Block a user