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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user