mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Fixing bug 61098. Give users a way out of inifinite modal dialog loops. Original patch by Nochum Sossonko. r=jonas@sicking.cc a=beta7+
This commit is contained in:
parent
0a4d13c52b
commit
16a2846c1a
@ -336,6 +336,7 @@ user_pref("dom.disable_open_during_load", false);
|
||||
user_pref("dom.max_script_run_time", 0); // no slow script dialogs
|
||||
user_pref("dom.max_chrome_script_run_time", 0);
|
||||
user_pref("dom.popup_maximum", -1);
|
||||
user_pref("dom.successive_dialog_time_limit", 0);
|
||||
user_pref("signed.applets.codebase_principal_support", true);
|
||||
user_pref("security.warn_submit_insecure", false);
|
||||
user_pref("browser.shell.checkDefaultBrowser", false);
|
||||
|
@ -690,13 +690,15 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
mPendingStorageEventsObsolete(nsnull),
|
||||
mTimeoutsSuspendDepth(0),
|
||||
mFocusMethod(0),
|
||||
mSerial(0)
|
||||
mSerial(0),
|
||||
#ifdef DEBUG
|
||||
, mSetOpenerWindowCalled(PR_FALSE)
|
||||
mSetOpenerWindowCalled(PR_FALSE),
|
||||
#endif
|
||||
, mCleanedUp(PR_FALSE)
|
||||
, mCallCleanUpAfterModalDialogCloses(PR_FALSE)
|
||||
, mWindowID(gNextWindowID++)
|
||||
mCleanedUp(PR_FALSE),
|
||||
mCallCleanUpAfterModalDialogCloses(PR_FALSE),
|
||||
mWindowID(gNextWindowID++),
|
||||
mDialogAbuseCount(0),
|
||||
mDialogDisabled(PR_FALSE)
|
||||
{
|
||||
nsLayoutStatics::AddRef();
|
||||
|
||||
@ -2346,6 +2348,105 @@ nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindow::DialogOpenAttempted()
|
||||
{
|
||||
nsGlobalWindow *topWindow = GetTop();
|
||||
if (!topWindow) {
|
||||
NS_ERROR("DialogOpenAttempted() called without a top window?");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
topWindow = topWindow->GetCurrentInnerWindowInternal();
|
||||
if (!topWindow ||
|
||||
topWindow->mLastDialogQuitTime.IsNull() ||
|
||||
nsContentUtils::IsCallerTrustedForCapability("UniversalXPConnect")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TimeDuration dialogDuration(TimeStamp::Now() -
|
||||
topWindow->mLastDialogQuitTime);
|
||||
|
||||
if (dialogDuration.ToSeconds() <
|
||||
nsContentUtils::GetIntPref("dom.successive_dialog_time_limit",
|
||||
SUCCESSIVE_DIALOG_TIME_LIMIT)) {
|
||||
topWindow->mDialogAbuseCount++;
|
||||
|
||||
return (topWindow->GetPopupControlState() > openAllowed ||
|
||||
topWindow->mDialogAbuseCount > MAX_DIALOG_COUNT);
|
||||
}
|
||||
|
||||
topWindow->mDialogAbuseCount = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindow::AreDialogsBlocked()
|
||||
{
|
||||
nsGlobalWindow *topWindow = GetTop();
|
||||
if (!topWindow) {
|
||||
NS_ERROR("AreDialogsBlocked() called without a top window?");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
topWindow = topWindow->GetCurrentInnerWindowInternal();
|
||||
|
||||
return !topWindow ||
|
||||
(topWindow->mDialogDisabled &&
|
||||
(topWindow->GetPopupControlState() > openAllowed ||
|
||||
topWindow->mDialogAbuseCount >= MAX_DIALOG_COUNT));
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindow::ConfirmDialogAllowed()
|
||||
{
|
||||
NS_ENSURE_TRUE(mDocShell, false);
|
||||
nsCOMPtr<nsIPromptService> promptSvc =
|
||||
do_GetService("@mozilla.org/embedcomp/prompt-service;1");
|
||||
|
||||
if (!DialogOpenAttempted() || !promptSvc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset popup state while opening a modal dialog, and firing events
|
||||
// about the dialog, to prevent the current state from being active
|
||||
// the whole time a modal dialog is open.
|
||||
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
|
||||
|
||||
PRBool disableDialog = PR_FALSE;
|
||||
nsXPIDLString label, title;
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
|
||||
"ScriptDialogLabel", label);
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
|
||||
"ScriptDialogPreventTitle", title);
|
||||
promptSvc->Confirm(this, title.get(), label.get(), &disableDialog);
|
||||
if (disableDialog) {
|
||||
PreventFurtherDialogs();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::PreventFurtherDialogs()
|
||||
{
|
||||
nsGlobalWindow *topWindow = GetTop();
|
||||
if (!topWindow) {
|
||||
NS_ERROR("PreventFurtherDialogs() called without a top window?");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
topWindow = topWindow->GetCurrentInnerWindowInternal();
|
||||
|
||||
if (topWindow)
|
||||
topWindow->mDialogDisabled = PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
@ -2673,8 +2774,6 @@ nsGlobalWindow::GetTop(nsIDOMWindow** aTop)
|
||||
{
|
||||
FORWARD_TO_OUTER(GetTop, (aTop), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
|
||||
*aTop = nsnull;
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
|
||||
@ -2682,12 +2781,12 @@ nsGlobalWindow::GetTop(nsIDOMWindow** aTop)
|
||||
docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
|
||||
if (root) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(root));
|
||||
CallQueryInterface(globalObject.get(), aTop);
|
||||
nsCOMPtr<nsIDOMWindow> top(do_GetInterface(root));
|
||||
top.swap(*aTop);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -4274,6 +4373,13 @@ nsGlobalWindow::Alert(const nsAString& aString)
|
||||
{
|
||||
FORWARD_TO_OUTER(Alert, (aString), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (AreDialogsBlocked())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// We have to capture this now so as not to get confused with the
|
||||
// popup state we push next
|
||||
PRBool shouldEnableDisableDialog = DialogOpenAttempted();
|
||||
|
||||
// Reset popup state while opening a modal dialog, and firing events
|
||||
// about the dialog, to prevent the current state from being active
|
||||
// the whole time a modal dialog is open.
|
||||
@ -4299,10 +4405,29 @@ nsGlobalWindow::Alert(const nsAString& aString)
|
||||
nsContentUtils::StripNullChars(*str, final);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
nsCOMPtr<nsIPromptService> promptSvc =
|
||||
do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return promptSvc->Alert(this, title.get(), final.get());
|
||||
EnterModalState();
|
||||
|
||||
if (shouldEnableDisableDialog) {
|
||||
PRBool disallowDialog = PR_FALSE;
|
||||
nsXPIDLString label;
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
|
||||
"ScriptDialogLabel", label);
|
||||
|
||||
rv = promptSvc->AlertCheck(this, title.get(), final.get(), label.get(),
|
||||
&disallowDialog);
|
||||
if (disallowDialog)
|
||||
PreventFurtherDialogs();
|
||||
} else {
|
||||
rv = promptSvc->Alert(this, title.get(), final.get());
|
||||
}
|
||||
|
||||
LeaveModalState();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -4310,6 +4435,13 @@ nsGlobalWindow::Confirm(const nsAString& aString, PRBool* aReturn)
|
||||
{
|
||||
FORWARD_TO_OUTER(Confirm, (aString, aReturn), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (AreDialogsBlocked())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// We have to capture this now so as not to get confused with the popup state
|
||||
// we push next
|
||||
PRBool shouldEnableDisableDialog = DialogOpenAttempted();
|
||||
|
||||
// Reset popup state while opening a modal dialog, and firing events
|
||||
// about the dialog, to prevent the current state from being active
|
||||
// the whole time a modal dialog is open.
|
||||
@ -4330,10 +4462,29 @@ nsGlobalWindow::Confirm(const nsAString& aString, PRBool* aReturn)
|
||||
nsContentUtils::StripNullChars(aString, final);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
nsCOMPtr<nsIPromptService> promptSvc =
|
||||
do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return promptSvc->Confirm(this, title.get(), final.get(), aReturn);
|
||||
EnterModalState();
|
||||
|
||||
if (shouldEnableDisableDialog) {
|
||||
PRBool disallowDialog = PR_FALSE;
|
||||
nsXPIDLString label;
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
|
||||
"ScriptDialogLabel", label);
|
||||
|
||||
rv = promptSvc->ConfirmCheck(this, title.get(), final.get(), label.get(),
|
||||
&disallowDialog, aReturn);
|
||||
if (disallowDialog)
|
||||
PreventFurtherDialogs();
|
||||
} else {
|
||||
rv = promptSvc->Confirm(this, title.get(), final.get(), aReturn);
|
||||
}
|
||||
|
||||
LeaveModalState();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -4342,6 +4493,13 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
|
||||
{
|
||||
SetDOMStringToNull(aReturn);
|
||||
|
||||
if (AreDialogsBlocked())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// We have to capture this now so as not to get confused with the popup state
|
||||
// we push next
|
||||
PRBool shouldEnableDisableDialog = DialogOpenAttempted();
|
||||
|
||||
// Reset popup state while opening a modal dialog, and firing events
|
||||
// about the dialog, to prevent the current state from being active
|
||||
// the whole time a modal dialog is open.
|
||||
@ -4361,15 +4519,32 @@ nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
|
||||
nsContentUtils::StripNullChars(aInitial, fixedInitial);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
nsCOMPtr<nsIPromptService> promptSvc =
|
||||
do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Pass in the default value, if any.
|
||||
PRUnichar *inoutValue = ToNewUnicode(fixedInitial);
|
||||
PRBool disallowDialog = PR_FALSE;
|
||||
|
||||
PRBool ok, dummy;
|
||||
nsXPIDLString label;
|
||||
if (shouldEnableDisableDialog) {
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
|
||||
"ScriptDialogLabel", label);
|
||||
}
|
||||
|
||||
EnterModalState();
|
||||
|
||||
PRBool ok;
|
||||
rv = promptSvc->Prompt(this, title.get(), fixedMessage.get(),
|
||||
&inoutValue, nsnull, &dummy, &ok);
|
||||
&inoutValue, label.get(), &disallowDialog, &ok);
|
||||
|
||||
LeaveModalState();
|
||||
|
||||
if (disallowDialog) {
|
||||
PreventFurtherDialogs();
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAdoptingString outValue(inoutValue);
|
||||
@ -4623,6 +4798,9 @@ nsGlobalWindow::Print()
|
||||
#ifdef NS_PRINTING
|
||||
FORWARD_TO_OUTER(Print, (), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (AreDialogsBlocked() || !ConfirmDialogAllowed())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
|
||||
if (NS_SUCCEEDED(GetInterface(NS_GET_IID(nsIWebBrowserPrint),
|
||||
getter_AddRefs(webBrowserPrint)))) {
|
||||
@ -5855,17 +6033,14 @@ nsGlobalWindow::ReallyCloseWindow()
|
||||
void
|
||||
nsGlobalWindow::EnterModalState()
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
GetTop(getter_AddRefs(top));
|
||||
nsGlobalWindow* topWin = GetTop();
|
||||
|
||||
if (!top) {
|
||||
if (!topWin) {
|
||||
NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsGlobalWindow* topWin =
|
||||
static_cast<nsGlobalWindow*>(static_cast<nsIDOMWindow *>(top.get()));
|
||||
if (topWin->mModalStateDepth == 0) {
|
||||
NS_ASSERTION(!mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
|
||||
|
||||
@ -5959,20 +6134,13 @@ private:
|
||||
void
|
||||
nsGlobalWindow::LeaveModalState()
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
GetTop(getter_AddRefs(top));
|
||||
nsGlobalWindow *topWin = GetTop();
|
||||
|
||||
if (!top) {
|
||||
if (!topWin) {
|
||||
NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsGlobalWindow *topWin =
|
||||
static_cast<nsGlobalWindow *>
|
||||
(static_cast<nsIDOMWindow *>
|
||||
(top.get()));
|
||||
|
||||
topWin->mModalStateDepth--;
|
||||
|
||||
if (topWin->mModalStateDepth == 0) {
|
||||
@ -5994,23 +6162,25 @@ nsGlobalWindow::LeaveModalState()
|
||||
if (cx && (scx = GetScriptContextFromJSContext(cx))) {
|
||||
scx->LeaveModalState();
|
||||
}
|
||||
|
||||
// Remember the time of the last dialog quit.
|
||||
nsGlobalWindow *inner = topWin->GetCurrentInnerWindowInternal();
|
||||
if (inner)
|
||||
inner->mLastDialogQuitTime = TimeStamp::Now();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGlobalWindow::IsInModalState()
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
GetTop(getter_AddRefs(top));
|
||||
nsGlobalWindow *topWin = GetTop();
|
||||
|
||||
if (!top) {
|
||||
if (!topWin) {
|
||||
NS_ERROR("Uh, IsInModalState() called w/o a reachable top window?");
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return static_cast<nsGlobalWindow *>
|
||||
(static_cast<nsIDOMWindow *>
|
||||
(top.get()))->mModalStateDepth != 0;
|
||||
return topWin->mModalStateDepth != 0;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -6316,7 +6486,12 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
|
||||
{
|
||||
*aRetVal = nsnull;
|
||||
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
// Before bringing up the window/dialog, unsuppress painting and flush
|
||||
// pending reflows.
|
||||
EnsureReflowFlushAndPaint();
|
||||
|
||||
if (AreDialogsBlocked() || !ConfirmDialogAllowed())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> dlgWin;
|
||||
nsAutoString options(NS_LITERAL_STRING("-moz-internal-modal=1,status=1"));
|
||||
@ -6325,10 +6500,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
|
||||
|
||||
options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
|
||||
|
||||
// Before bringing up the window, unsuppress painting and flush
|
||||
// pending reflows.
|
||||
EnsureReflowFlushAndPaint();
|
||||
|
||||
EnterModalState();
|
||||
nsresult rv = OpenInternal(aURI, EmptyString(), options,
|
||||
PR_FALSE, // aDialog
|
||||
PR_TRUE, // aContentModal
|
||||
@ -6338,6 +6510,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsnull, // aJSCallerContext
|
||||
getter_AddRefs(dlgWin));
|
||||
LeaveModalState();
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -43,6 +43,8 @@
|
||||
#ifndef nsGlobalWindow_h___
|
||||
#define nsGlobalWindow_h___
|
||||
|
||||
#include "mozilla/XPCOM.h" // for TimeStamp/TimeDuration
|
||||
|
||||
// Local Includes
|
||||
// Helper Classes
|
||||
#include "nsCOMPtr.h"
|
||||
@ -109,6 +111,14 @@
|
||||
#define DEFAULT_HOME_PAGE "www.mozilla.org"
|
||||
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
|
||||
|
||||
// Amount of time allowed between alert/prompt/confirm before enabling
|
||||
// the stop dialog checkbox.
|
||||
#define SUCCESSIVE_DIALOG_TIME_LIMIT 3 // 3 sec
|
||||
|
||||
// During click or mousedown events (and others, see nsDOMEvent) we allow modal
|
||||
// dialogs up to this limit, even if they were disabled.
|
||||
#define MAX_DIALOG_COUNT 10
|
||||
|
||||
class nsIDOMBarProp;
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
@ -244,6 +254,9 @@ class nsGlobalWindow : public nsPIDOMWindow,
|
||||
public PRCListStr
|
||||
{
|
||||
public:
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
typedef mozilla::TimeDuration TimeDuration;
|
||||
|
||||
// public methods
|
||||
nsPIDOMWindow* GetPrivateParent();
|
||||
// callback for close event
|
||||
@ -395,6 +408,32 @@ public:
|
||||
return FromSupports(wrapper->Native());
|
||||
}
|
||||
|
||||
inline nsGlobalWindow *GetTop()
|
||||
{
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
GetTop(getter_AddRefs(top));
|
||||
if (top)
|
||||
return static_cast<nsGlobalWindow *>(static_cast<nsIDOMWindow *>(top.get()));
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Call this when a modal dialog is about to be opened. Returns
|
||||
// true if we've reached the state in this top level window where we
|
||||
// ask the user if further dialogs should be blocked.
|
||||
bool DialogOpenAttempted();
|
||||
|
||||
// Returns true if dialogs have already been blocked for this
|
||||
// window.
|
||||
bool AreDialogsBlocked();
|
||||
|
||||
// Ask the user if further dialogs should be blocked. This is used
|
||||
// in the cases where we have no modifiable UI to show, in that case
|
||||
// we show a separate dialog when asking this question.
|
||||
bool ConfirmDialogAllowed();
|
||||
|
||||
// Prevent further dialogs in this (top level) window
|
||||
void PreventFurtherDialogs();
|
||||
|
||||
nsIScriptContext *GetContextInternal()
|
||||
{
|
||||
if (mOuterWindow) {
|
||||
@ -864,6 +903,18 @@ protected:
|
||||
// this window.
|
||||
PRUint64 mWindowID;
|
||||
|
||||
// In the case of a "trusted" dialog (@see PopupControlState), we
|
||||
// set this counter to ensure a max of MAX_DIALOG_LIMIT
|
||||
PRUint32 mDialogAbuseCount;
|
||||
|
||||
// This holds the time when the last modal dialog was shown, if two
|
||||
// dialogs are shown within CONCURRENT_DIALOG_TIME_LIMIT the
|
||||
// checkbox is shown. In the case of ShowModalDialog another Confirm
|
||||
// dialog will be shown, the result of the checkbox/confirm dialog
|
||||
// will be stored in mDialogDisabled variable.
|
||||
TimeStamp mLastDialogQuitTime;
|
||||
PRPackedBool mDialogDisabled;
|
||||
|
||||
friend class nsDOMScriptableHelper;
|
||||
friend class nsDOMWindowUtils;
|
||||
friend class PostMessageEvent;
|
||||
|
@ -123,6 +123,7 @@ _TEST_FILES = \
|
||||
test_bug585240.html \
|
||||
test_bug585819.html \
|
||||
test_bug369306.html \
|
||||
test_bug61098.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
@ -9,27 +9,31 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=504862
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<body onload="runTest()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=504862">Mozilla Bug 504862</a>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 504862 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function onMsgRcv(event)
|
||||
{
|
||||
is(event.data, "args: undefined", "Unexpected cross origin dialog arguments.");
|
||||
}
|
||||
|
||||
window.addEventListener("message", onMsgRcv, false);
|
||||
function runTest() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
window.addEventListener("message", onMsgRcv, false);
|
||||
|
||||
var subsequentDlg = "data:text/html,<html><body onload='opener.is(window.dialogArguments, \'my args\', \'subsequent dialog document did not get the right arguments.\'); close();'>";
|
||||
var subsequentDlg = "data:text/html,<html><body onload='opener.is(window.dialogArguments, \'my args\', \'subsequent dialog document did not get the right arguments.\'); close();'>";
|
||||
|
||||
var result = window.showModalDialog("file_bug504862.html", "my args");
|
||||
is(result, null, "window sees previous dialog documents return value.");
|
||||
var result = window.showModalDialog("file_bug504862.html", "my args");
|
||||
is(result, null, "window sees previous dialog documents return value.");
|
||||
|
||||
result = window.showModalDialog("http://test1.example.com/tests/dom/tests/mochitest/bugs/file_bug504862.html", "my args");
|
||||
result = window.showModalDialog("http://test1.example.com/tests/dom/tests/mochitest/bugs/file_bug504862.html", "my args");
|
||||
|
||||
is(result, null, "Able to see return value from cross origin dialog.");
|
||||
is(result, null, "Able to see return value from cross origin dialog.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
270
dom/tests/mochitest/bugs/test_bug61098.html
Normal file
270
dom/tests/mochitest/bugs/test_bug61098.html
Normal file
@ -0,0 +1,270 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=61098
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 61098</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/mozprefs.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/mockObjects.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runtests();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=61098">Mozilla Bug 61098</a>
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script class="testbody" type="text/javascript">
|
||||
/** Test for Bug 61098 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var mockPromptServiceRegisterer;
|
||||
|
||||
var promptState;
|
||||
|
||||
function registerMockPromptService()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
// Override the prompt service with our own so that we can test
|
||||
// modal dialogs
|
||||
|
||||
function MockPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
MockPromptService.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPromptService]),
|
||||
|
||||
alert: function(aParent, aDialogTitle, aText)
|
||||
{
|
||||
promptState = {method: "alert",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText
|
||||
};
|
||||
},
|
||||
|
||||
alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState)
|
||||
{
|
||||
promptState = {method: "alertCheck",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText,
|
||||
checkMsg: aCheckMsg,
|
||||
checkState: aCheckState
|
||||
};
|
||||
|
||||
aCheckState.value = true;
|
||||
},
|
||||
|
||||
confirm: function(aParent, aDialogTitle, aText)
|
||||
{
|
||||
promptState = {method: "confirm",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText
|
||||
};
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg,
|
||||
aCheckState)
|
||||
{
|
||||
promptState = {method: "confirmCheck",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText,
|
||||
checkMsg: aCheckMsg,
|
||||
checkState: aCheckState
|
||||
};
|
||||
|
||||
aCheckState.value = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags,
|
||||
aButton0Title, aButton1Title, aButton2Title,
|
||||
aCheckMsg, aCheckState)
|
||||
{
|
||||
promptState = {method: "confirmCheck",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText,
|
||||
checkMsg: aCheckMsg,
|
||||
checkState: aCheckState
|
||||
};
|
||||
|
||||
if (aCheckMsg != null)
|
||||
aCheckState.value = true;
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg,
|
||||
aCheckState)
|
||||
{
|
||||
promptState = {method: "prompt",
|
||||
parent: aParent,
|
||||
title: aDialogTitle,
|
||||
msg: aText,
|
||||
checkMsg: aCheckMsg,
|
||||
checkState: aCheckState
|
||||
};
|
||||
|
||||
if (aCheckMsg != null)
|
||||
aCheckState.value = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
mockPromptServiceRegisterer =
|
||||
new MockObjectRegisterer("@mozilla.org/embedcomp/prompt-service;1",
|
||||
MockPromptService);
|
||||
|
||||
mockPromptServiceRegisterer.register();
|
||||
};
|
||||
|
||||
function enableDialogLoopBlocking()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
prefs.setIntPref("dom.successive_dialog_time_limit", 3);
|
||||
}
|
||||
|
||||
function resetDialogLoopBlocking()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
prefs.setIntPref("dom.successive_dialog_time_limit", 0);
|
||||
}
|
||||
|
||||
var expectedState;
|
||||
|
||||
function runtests()
|
||||
{
|
||||
registerMockPromptService();
|
||||
enableDialogLoopBlocking();
|
||||
|
||||
// Test that alert() works normally and then gets blocked on the
|
||||
// second call.
|
||||
w = window.open();
|
||||
w.alert("alert message 1");
|
||||
is (promptState.method, "alert", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong alert parent");
|
||||
is (promptState.msg, "alert message 1", "Wrong alert message");
|
||||
promptState = void(0);
|
||||
|
||||
w.alert("alert message 2");
|
||||
is (promptState.method, "alertCheck", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong alert parent");
|
||||
is (promptState.msg, "alert message 2", "Wrong alert message");
|
||||
promptState = void(0);
|
||||
|
||||
try {
|
||||
w.alert("alert message 3");
|
||||
} catch(e) {
|
||||
is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception");
|
||||
}
|
||||
|
||||
is (promptState, void(0), "Wrong prompt state after blocked alert()");
|
||||
|
||||
w.close();
|
||||
|
||||
// Test that confirm() works normally and then gets blocked on the
|
||||
// second call.
|
||||
w = window.open();
|
||||
w.confirm("confirm message 1");
|
||||
is (promptState.method, "confirm", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong confirm parent");
|
||||
is (promptState.msg, "confirm message 1", "Wrong confirm message");
|
||||
promptState = void(0);
|
||||
|
||||
w.confirm("confirm message 2");
|
||||
is (promptState.method, "confirmCheck", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong confirm parent");
|
||||
is (promptState.msg, "confirm message 2", "Wrong confirm message");
|
||||
promptState = void(0);
|
||||
|
||||
try {
|
||||
w.confirm("confirm message 3");
|
||||
} catch(e) {
|
||||
is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception");
|
||||
}
|
||||
|
||||
is (promptState, void(0), "Wrong prompt state after blocked confirm()");
|
||||
|
||||
w.close();
|
||||
|
||||
// Test that prompt() works normally and then gets blocked on the
|
||||
// second call.
|
||||
w = window.open();
|
||||
w.prompt("prompt message 1");
|
||||
is (promptState.method, "prompt", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong prompt parent");
|
||||
is (promptState.msg, "prompt message 1", "Wrong prompt message");
|
||||
is (promptState.checkMsg, null, "Wrong dialog value");
|
||||
promptState = void(0);
|
||||
|
||||
w.prompt("prompt message 2");
|
||||
is (promptState.method, "prompt", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong prompt parent");
|
||||
is (promptState.msg, "prompt message 2", "Wrong prompt message");
|
||||
is (promptState.checkMsg, "Prevent this page from creating additional dialogs", "Wrong dialog value");
|
||||
promptState = void(0);
|
||||
|
||||
try {
|
||||
w.prompt("prompt message 3");
|
||||
} catch(e) {
|
||||
is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception");
|
||||
}
|
||||
|
||||
is (promptState, void(0), "Wrong prompt state after blocked prompt()");
|
||||
|
||||
w.close();
|
||||
|
||||
// Test that showModalDialog() works normally and then gets blocked
|
||||
// on the second call.
|
||||
w = window.open();
|
||||
w.showModalDialog("data:text/html,%3Cscript>window.close();%3C/script>")
|
||||
is (promptState, void(0), "Wrong prompt state");
|
||||
|
||||
// Test that showModalDialog() works normally and then gets blocked
|
||||
// on the second call.
|
||||
try {
|
||||
w.showModalDialog("data:text/html,%3Cscript>window.close();%3C/script>")
|
||||
} catch(e) {
|
||||
is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception");
|
||||
}
|
||||
is (promptState.method, "confirm", "Wrong prompt method called");
|
||||
is (promptState.parent, w, "Wrong confirm parent");
|
||||
is (promptState.msg, "Prevent this page from creating additional dialogs",
|
||||
"Wrong confirm message");
|
||||
promptState = void(0);
|
||||
|
||||
w.close();
|
||||
|
||||
resetDialogLoopBlocking();
|
||||
mockPromptServiceRegisterer.unregister();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -14,6 +14,8 @@ Revert=&Revert
|
||||
DontSave=&Don't Save
|
||||
ScriptDlgGenericHeading=[JavaScript Application]
|
||||
ScriptDlgHeading=The page at %S says:
|
||||
ScriptDialogLabel=Prevent this page from creating additional dialogs
|
||||
ScriptDialogPreventTitle=Confirm Dialog Preference
|
||||
# LOCALIZATION NOTE (EnterLoginForRealm, EnterLoginForProxy):
|
||||
# %1 is an untrusted string provided by a remote server. It could try to
|
||||
# take advantage of sentence structure in order to mislead the user (see
|
||||
|
Loading…
Reference in New Issue
Block a user