Bug 613800 - A Race Condition when closing inactive tab with alerts in OnBeforeUnload; r=jst a=blocking-final

This commit is contained in:
Justin Dolske 2011-02-15 19:35:28 -05:00
parent e0feabee39
commit a0e80dc774
3 changed files with 60 additions and 3 deletions

View File

@ -134,3 +134,16 @@ interface nsIContentViewer : nsISupports
*/
readonly attribute nsISHEntry historyEntry;
};
[scriptable, uuid(4710ef6e-6de3-47fe-88f4-e49b48c87fc9)]
interface nsIContentViewer_MOZILLA_2_0_BRANCH : nsISupports
{
/*
* Indicates when we're in a state where content shouldn't be allowed to
* trigger a tab-modal prompt (as opposed to a window-modal prompt) because
* we're part way through some operation (eg beforeunload) that shouldn't be
* rentrant if the user closes the tab while the prompt is showing.
* See bug 613800.
*/
readonly attribute boolean isTabModalPromptAllowed;
};

View File

@ -4622,6 +4622,17 @@ nsGlobalWindow::Alert(const nsAString& aString)
nsAutoString final;
nsContentUtils::StripNullChars(*str, final);
// Check if we're being called at a point where we can't use tab-modal
// prompts, because something doesn't want reentrancy.
PRBool allowTabModal = PR_TRUE;
if (mDocShell) {
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIContentViewer_MOZILLA_2_0_BRANCH> cv2 = do_QueryInterface(cv);
if (cv2)
cv2->GetIsTabModalPromptAllowed(&allowTabModal);
}
nsresult rv;
nsCOMPtr<nsIPromptFactory> promptFac =
do_GetService("@mozilla.org/prompter;1", &rv);
@ -4634,7 +4645,7 @@ nsGlobalWindow::Alert(const nsAString& aString)
nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
if (promptBag)
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), PR_TRUE);
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
if (shouldEnableDisableDialog) {
PRBool disallowDialog = PR_FALSE;
@ -4684,6 +4695,17 @@ nsGlobalWindow::Confirm(const nsAString& aString, PRBool* aReturn)
nsAutoString final;
nsContentUtils::StripNullChars(aString, final);
// Check if we're being called at a point where we can't use tab-modal
// prompts, because something doesn't want reentrancy.
PRBool allowTabModal = PR_TRUE;
if (mDocShell) {
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIContentViewer_MOZILLA_2_0_BRANCH> cv2 = do_QueryInterface(cv);
if (cv2)
cv2->GetIsTabModalPromptAllowed(&allowTabModal);
}
nsresult rv;
nsCOMPtr<nsIPromptFactory> promptFac =
do_GetService("@mozilla.org/prompter;1", &rv);
@ -4696,7 +4718,7 @@ nsGlobalWindow::Confirm(const nsAString& aString, PRBool* aReturn)
nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
if (promptBag)
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), PR_TRUE);
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
if (shouldEnableDisableDialog) {
PRBool disallowDialog = PR_FALSE;
@ -4749,6 +4771,17 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsContentUtils::StripNullChars(aMessage, fixedMessage);
nsContentUtils::StripNullChars(aInitial, fixedInitial);
// Check if we're being called at a point where we can't use tab-modal
// prompts, because something doesn't want reentrancy.
PRBool allowTabModal = PR_TRUE;
if (mDocShell) {
nsCOMPtr<nsIContentViewer> cv;
mDocShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIContentViewer_MOZILLA_2_0_BRANCH> cv2 = do_QueryInterface(cv);
if (cv2)
cv2->GetIsTabModalPromptAllowed(&allowTabModal);
}
nsresult rv;
nsCOMPtr<nsIPromptFactory> promptFac =
do_GetService("@mozilla.org/prompter;1", &rv);
@ -4761,7 +4794,7 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
if (promptBag)
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), PR_TRUE);
promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
// Pass in the default value, if any.
PRUnichar *inoutValue = ToNewUnicode(fixedInitial);

View File

@ -297,6 +297,7 @@ private:
//-------------------------------------------------------------
class DocumentViewerImpl : public nsIDocumentViewer,
public nsIContentViewer_MOZILLA_2_0_BRANCH,
public nsIContentViewerEdit,
public nsIContentViewerFile,
public nsIMarkupDocumentViewer,
@ -356,6 +357,8 @@ public:
// nsIDocumentViewerPrint Printing Methods
NS_DECL_NSIDOCUMENTVIEWERPRINT
// nsIContentViewer_MOZILLA_2_0_BRANCH interface...
NS_DECL_NSICONTENTVIEWER_MOZILLA_2_0_BRANCH
protected:
virtual ~DocumentViewerImpl();
@ -585,6 +588,7 @@ NS_INTERFACE_MAP_BEGIN(DocumentViewerImpl)
#ifdef NS_PRINTING
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPrint)
#endif
NS_INTERFACE_MAP_ENTRY(nsIContentViewer_MOZILLA_2_0_BRANCH)
NS_INTERFACE_MAP_END
DocumentViewerImpl::~DocumentViewerImpl()
@ -4303,6 +4307,13 @@ DocumentViewerImpl::GetHistoryEntry(nsISHEntry **aHistoryEntry)
return NS_OK;
}
NS_IMETHODIMP
DocumentViewerImpl::GetIsTabModalPromptAllowed(PRBool *aAllowed)
{
*aAllowed = !(mInPermitUnload || mHidden);
return NS_OK;
}
void
DocumentViewerImpl::DestroyPresShell()
{