--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4077,17 +4077,26 @@ nsDocShell::IsPrintingOrPP(bool aDisplay
}
return mIsPrintingOrPP;
}
bool
nsDocShell::IsNavigationAllowed(bool aDisplayPrintErrorDialog)
{
- return !IsPrintingOrPP(aDisplayPrintErrorDialog) && !mFiredUnloadEvent;
+ bool isAllowed = !IsPrintingOrPP(aDisplayPrintErrorDialog) && !mFiredUnloadEvent;
+ if (!isAllowed) {
+ return false;
+ }
+ if (!mContentViewer) {
+ return true;
+ }
+ bool firingBeforeUnload;
+ mContentViewer->GetBeforeUnloadFiring(&firingBeforeUnload);
+ return !firingBeforeUnload;
}
//*****************************************************************************
// nsDocShell::nsIWebNavigation
//*****************************************************************************
NS_IMETHODIMP
nsDocShell::GetCanGoBack(bool * aCanGoBack)
--- a/docshell/base/nsIContentViewer.idl
+++ b/docshell/base/nsIContentViewer.idl
@@ -23,17 +23,17 @@ class nsDOMNavigationTiming;
[ptr] native nsIWidgetPtr(nsIWidget);
[ptr] native nsIDocumentPtr(nsIDocument);
[ref] native nsIntRectRef(nsIntRect);
[ptr] native nsIPresShellPtr(nsIPresShell);
[ptr] native nsPresContextPtr(nsPresContext);
[ptr] native nsViewPtr(nsView);
[ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming);
-[scriptable, builtinclass, uuid(1b22be51-efe8-42ac-a9a0-06f50f39beee)]
+[scriptable, builtinclass, uuid(a73d693a-6260-468a-ae64-d64237f0858c)]
interface nsIContentViewer : nsISupports
{
[noscript] void init(in nsIWidgetPtr aParentWidget,
[const] in nsIntRectRef aBounds);
attribute nsIDocShell container;
@@ -54,16 +54,22 @@ interface nsIContentViewer : nsISupports
* As above, but this passes around the aShouldPrompt argument to keep
* track of whether the user has responded to a prompt.
* Used internally by the scriptable version to ensure we only prompt once.
*/
[noscript,nostdcall] boolean permitUnloadInternal(in boolean aCallerClosesWindow,
inout boolean aShouldPrompt);
/**
+ * Exposes whether we're in the process of firing the beforeunload event.
+ * In this case, the corresponding docshell will not allow navigation.
+ */
+ readonly attribute boolean beforeUnloadFiring;
+
+ /**
* Works in tandem with permitUnload, if the caller decides not to close the
* window it indicated it will, it is the caller's responsibility to reset
* that with this method.
*
* @Note this method is only meant to be called on documents for which the
* caller has indicated that it will close the window. If that is not the case
* the behavior of this method is undefined.
*/
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1226,16 +1226,23 @@ nsDocumentViewer::PermitUnloadInternal(b
if (aCallerClosesWindow && *aPermitUnload)
mCallerIsClosingWindow = true;
return NS_OK;
}
NS_IMETHODIMP
+nsDocumentViewer::GetBeforeUnloadFiring(bool* aInEvent)
+{
+ *aInEvent = mInPermitUnload;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsDocumentViewer::ResetCloseWindow()
{
mCallerIsClosingWindow = false;
nsCOMPtr<nsIDocShellTreeNode> docShellNode(mContainer);
if (docShellNode) {
int32_t childCount;
docShellNode->GetChildCount(&childCount);