Fixing bug 334891. Ignore close calls on windows that have a modal dialog parented at them. r=dveditz@cruzio.com, sr=bzbarsky@mit.edu, a=dbaron@mozilla.com

git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@202108 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jst%mozilla.jstenback.com
2006-07-14 01:19:33 +00:00
parent be469f1a3b
commit de57879100
4 changed files with 115 additions and 36 deletions

View File

@@ -333,8 +333,8 @@ protected:
};
#define NS_PIDOMWINDOW_MOZILLA_1_8_BRANCH_IID \
{ 0x7bf31d9e, 0xd17b, 0x47dc, \
{ 0xa6, 0xe4, 0x5f, 0xae, 0x29, 0x94, 0xf1, 0x07 } }
{ 0xa9b7f235, 0x4c98, 0x4257, \
{ 0xb1, 0x1a, 0xbe, 0x53, 0x39, 0x69, 0xdf, 0x2a } }
class nsPIDOMWindow_MOZILLA_1_8_BRANCH : public nsPIDOMWindow
{
@@ -357,6 +357,13 @@ public:
*/
virtual nsresult FireDelayedDOMEvents() = 0;
/**
* Callback for notifying a window about a modal dialog being
* opened/closed with the window as a parent.
*/
virtual void EnterModalState() = 0;
virtual void LeaveModalState() = 0;
protected:
nsPIDOMWindow_MOZILLA_1_8_BRANCH(nsPIDOMWindow *aOuterWindow)
: nsPIDOMWindow(aOuterWindow)

View File

@@ -315,6 +315,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mHavePendingClose(PR_FALSE),
mHadOriginalOpener(PR_FALSE),
mIsPopupSpam(PR_FALSE),
mModalStateDepth(0),
mArguments(nsnull),
mGlobalObjectOwner(nsnull),
mDocShell(nsnull),
@@ -4476,9 +4477,10 @@ nsGlobalWindow::Close()
{
FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
if (IsFrame() || !mDocShell) {
// window.close() is called on a frame in a frameset, or on a
// window that's already closed. Ignore such calls.
if (IsFrame() || !mDocShell || IsInModalState()) {
// window.close() is called on a frame in a frameset, on a window
// that's already closed, or on a window for which there's
// currently a modal dialog open. Ignore such calls.
return NS_OK;
}
@@ -4680,6 +4682,57 @@ nsGlobalWindow::ReallyCloseWindow()
}
}
void
nsGlobalWindow::EnterModalState()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
if (!top) {
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
return;
}
NS_STATIC_CAST(nsGlobalWindow *,
NS_STATIC_CAST(nsIDOMWindow *,
top.get()))->mModalStateDepth++;
}
void
nsGlobalWindow::LeaveModalState()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
if (!top) {
NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
return;
}
NS_STATIC_CAST(nsGlobalWindow *,
NS_STATIC_CAST(nsIDOMWindow *,
top.get()))->mModalStateDepth--;
}
PRBool
nsGlobalWindow::IsInModalState()
{
nsCOMPtr<nsIDOMWindow> top;
GetTop(getter_AddRefs(top));
if (!top) {
NS_ERROR("Uh, IsInModalState() called w/o a reachable top window?");
return PR_FALSE;
}
return NS_STATIC_CAST(nsGlobalWindow *,
NS_STATIC_CAST(nsIDOMWindow *,
top.get()))->mModalStateDepth != 0;
}
NS_IMETHODIMP
nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
{

View File

@@ -244,7 +244,9 @@ public:
virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents();
virtual NS_HIDDEN_(void) EnterModalState();
virtual NS_HIDDEN_(void) LeaveModalState();
// nsIDOMViewCSS
NS_DECL_NSIDOMVIEWCSS
@@ -471,6 +473,8 @@ protected:
mIsFrozen = PR_FALSE;
}
PRBool IsInModalState();
// When adding new member variables, be careful not to create cycles
// through JavaScript. If there is any chance that a member variable
// could own objects that are implemented in JavaScript, then those
@@ -498,6 +502,8 @@ protected:
PRPackedBool mHadOriginalOpener : 1;
PRPackedBool mIsPopupSpam : 1;
PRUint32 mModalStateDepth;
nsCOMPtr<nsIScriptContext> mContext;
nsCOMPtr<nsIDOMWindowInternal> mOpener;
nsCOMPtr<nsIControllers> mControllers;

View File

@@ -130,11 +130,11 @@ nsPrompt::Init()
// nsPrompt::nsIPrompt
//*****************************************************************************
class nsAutoDOMEventDispatcher
class nsAutoWindowStateHelper
{
public:
nsAutoDOMEventDispatcher(nsIDOMWindow *aWindow);
~nsAutoDOMEventDispatcher();
nsAutoWindowStateHelper(nsIDOMWindow *aWindow);
~nsAutoWindowStateHelper();
PRBool DefaultEnabled()
{
@@ -148,21 +148,34 @@ protected:
PRBool mDefaultEnabled;
};
nsAutoDOMEventDispatcher::nsAutoDOMEventDispatcher(nsIDOMWindow *aWindow)
nsAutoWindowStateHelper::nsAutoWindowStateHelper(nsIDOMWindow *aWindow)
: mWindow(aWindow),
mDefaultEnabled(DispatchCustomEvent("DOMWillOpenModalDialog"))
{
nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH> window =
do_QueryInterface(aWindow);
if (window) {
window->EnterModalState();
}
}
nsAutoDOMEventDispatcher::~nsAutoDOMEventDispatcher()
nsAutoWindowStateHelper::~nsAutoWindowStateHelper()
{
nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH> window =
do_QueryInterface(mWindow);
if (window) {
window->LeaveModalState();
}
if (mDefaultEnabled) {
DispatchCustomEvent("DOMModalDialogClosed");
}
}
PRBool
nsAutoDOMEventDispatcher::DispatchCustomEvent(const char *aEventName)
nsAutoWindowStateHelper::DispatchCustomEvent(const char *aEventName)
{
if (!mWindow) {
return PR_TRUE;
@@ -208,9 +221,9 @@ NS_IMETHODIMP
nsPrompt::Alert(const PRUnichar* dialogTitle,
const PRUnichar* text)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -223,9 +236,9 @@ nsPrompt::AlertCheck(const PRUnichar* dialogTitle,
const PRUnichar* checkMsg,
PRBool *checkValue)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -238,9 +251,9 @@ nsPrompt::Confirm(const PRUnichar* dialogTitle,
const PRUnichar* text,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -254,9 +267,9 @@ nsPrompt::ConfirmCheck(const PRUnichar* dialogTitle,
PRBool *checkValue,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -275,9 +288,9 @@ nsPrompt::ConfirmEx(const PRUnichar *dialogTitle,
PRBool *checkValue,
PRInt32 *buttonPressed)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -294,9 +307,9 @@ nsPrompt::Prompt(const PRUnichar *dialogTitle,
PRBool *checkValue,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -313,9 +326,9 @@ nsPrompt::PromptUsernameAndPassword(const PRUnichar *dialogTitle,
PRBool *checkValue,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -333,9 +346,9 @@ nsPrompt::PromptPassword(const PRUnichar *dialogTitle,
PRBool *checkValue,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -351,9 +364,9 @@ nsPrompt::Select(const PRUnichar *dialogTitle,
PRInt32 *outSelection,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -376,9 +389,9 @@ nsPrompt::Prompt(const PRUnichar* dialogTitle,
PRUnichar* *result,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -404,9 +417,9 @@ nsPrompt::PromptUsernameAndPassword(const PRUnichar* dialogTitle,
PRUnichar* *pwd,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}
@@ -424,9 +437,9 @@ nsPrompt::PromptPassword(const PRUnichar* dialogTitle,
PRUnichar* *pwd,
PRBool *_retval)
{
nsAutoDOMEventDispatcher autoDOMEventDispatcher(mParent);
nsAutoWindowStateHelper windowStateHelper(mParent);
if (!autoDOMEventDispatcher.DefaultEnabled()) {
if (!windowStateHelper.DefaultEnabled()) {
return NS_OK;
}