Back out fbdb3104c9e5, d2fe54ae00a8, d378362cbe01, fe623d60bea1 (bug 769254) on suspicion of causing Windows debug mochitest-plain-3 timeouts

This commit is contained in:
Matt Brubeck 2012-07-23 20:30:12 -07:00
parent 90029e0bf6
commit 867c5f52a6
17 changed files with 170 additions and 341 deletions

View File

@ -8307,19 +8307,16 @@ nsDocShell::InternalLoad(nsIURI * aURI,
bool isNewWindow = false; bool isNewWindow = false;
if (!targetDocShell) { if (!targetDocShell) {
nsCOMPtr<nsPIDOMWindow> win = nsCOMPtr<nsIDOMWindow> win =
do_GetInterface(GetAsSupports(this)); do_GetInterface(GetAsSupports(this));
NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE);
nsDependentString name(aWindowTarget); nsDependentString name(aWindowTarget);
nsCOMPtr<nsIDOMWindow> newWin; nsCOMPtr<nsIDOMWindow> newWin;
nsCAutoString spec; rv = win->Open(EmptyString(), // URL to load
if (aURI) name, // window name
aURI->GetSpec(spec); EmptyString(), // Features
rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec), getter_AddRefs(newWin));
name, // window name
EmptyString(), // Features
getter_AddRefs(newWin));
// In some cases the Open call doesn't actually result in a new // In some cases the Open call doesn't actually result in a new
// window being opened. We can detect these cases by examining the // window being opened. We can detect these cases by examining the

View File

@ -5866,7 +5866,6 @@ nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName,
false, // aContentModal false, // aContentModal
true, // aCalledNoScript true, // aCalledNoScript
false, // aDoJSFixups false, // aDoJSFixups
true, // aNavigate
nsnull, nsnull, // No args nsnull, nsnull, // No args
GetPrincipal(), // aCalleePrincipal GetPrincipal(), // aCalleePrincipal
nsnull, // aJSCallerContext nsnull, // aJSCallerContext
@ -5882,7 +5881,6 @@ nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName,
false, // aContentModal false, // aContentModal
false, // aCalledNoScript false, // aCalledNoScript
true, // aDoJSFixups true, // aDoJSFixups
true, // aNavigate
nsnull, nsnull, // No args nsnull, nsnull, // No args
GetPrincipal(), // aCalleePrincipal GetPrincipal(), // aCalleePrincipal
nsContentUtils::GetCurrentJSContext(), // aJSCallerContext nsContentUtils::GetCurrentJSContext(), // aJSCallerContext
@ -5901,33 +5899,12 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
false, // aContentModal false, // aContentModal
true, // aCalledNoScript true, // aCalledNoScript
false, // aDoJSFixups false, // aDoJSFixups
true, // aNavigate
nsnull, aExtraArgument, // Arguments nsnull, aExtraArgument, // Arguments
GetPrincipal(), // aCalleePrincipal GetPrincipal(), // aCalleePrincipal
nsnull, // aJSCallerContext nsnull, // aJSCallerContext
_retval); _retval);
} }
// Like Open, but passes aNavigate=false.
/* virtual */ nsresult
nsGlobalWindow::OpenNoNavigate(const nsAString& aUrl,
const nsAString& aName,
const nsAString& aOptions,
nsIDOMWindow **_retval)
{
return OpenInternal(aUrl, aName, aOptions,
false, // aDialog
false, // aContentModal
true, // aCalledNoScript
false, // aDoJSFixups
false, // aNavigate
nsnull, nsnull, // No args
GetPrincipal(), // aCalleePrincipal
nsnull, // aJSCallerContext
_retval);
}
NS_IMETHODIMP NS_IMETHODIMP
nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName, nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, nsIDOMWindow** _retval) const nsAString& aOptions, nsIDOMWindow** _retval)
@ -5968,7 +5945,6 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
false, // aContentModal false, // aContentModal
false, // aCalledNoScript false, // aCalledNoScript
false, // aDoJSFixups false, // aDoJSFixups
true, // aNavigate
argvArray, nsnull, // Arguments argvArray, nsnull, // Arguments
GetPrincipal(), // aCalleePrincipal GetPrincipal(), // aCalleePrincipal
cx, // aJSCallerContext cx, // aJSCallerContext
@ -7212,7 +7188,6 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
true, // aContentModal true, // aContentModal
true, // aCalledNoScript true, // aCalledNoScript
true, // aDoJSFixups true, // aDoJSFixups
true, // aNavigate
nsnull, aArgs, // args nsnull, aArgs, // args
GetPrincipal(), // aCalleePrincipal GetPrincipal(), // aCalleePrincipal
nsnull, // aJSCallerContext nsnull, // aJSCallerContext
@ -9131,8 +9106,7 @@ nsresult
nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName, nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, bool aDialog, const nsAString& aOptions, bool aDialog,
bool aContentModal, bool aCalledNoScript, bool aContentModal, bool aCalledNoScript,
bool aDoJSFixups, bool aNavigate, bool aDoJSFixups, nsIArray *argv,
nsIArray *argv,
nsISupports *aExtraArgument, nsISupports *aExtraArgument,
nsIPrincipal *aCalleePrincipal, nsIPrincipal *aCalleePrincipal,
JSContext *aJSCallerContext, JSContext *aJSCallerContext,
@ -9140,8 +9114,8 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
{ {
FORWARD_TO_OUTER(OpenInternal, (aUrl, aName, aOptions, aDialog, FORWARD_TO_OUTER(OpenInternal, (aUrl, aName, aOptions, aDialog,
aContentModal, aCalledNoScript, aDoJSFixups, aContentModal, aCalledNoScript, aDoJSFixups,
aNavigate, argv, aExtraArgument, argv, aExtraArgument, aCalleePrincipal,
aCalleePrincipal, aJSCallerContext, aReturn), aJSCallerContext, aReturn),
NS_ERROR_NOT_INITIALIZED); NS_ERROR_NOT_INITIALIZED);
#ifdef DEBUG #ifdef DEBUG
@ -9156,9 +9130,6 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript, NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript,
"Shouldn't have caller context when called noscript"); "Shouldn't have caller context when called noscript");
// Calls to window.open from script should navigate.
MOZ_ASSERT(aCalledNoScript || aNavigate);
*aReturn = nsnull; *aReturn = nsnull;
nsCOMPtr<nsIWebBrowserChrome> chrome; nsCOMPtr<nsIWebBrowserChrome> chrome;
@ -9186,13 +9157,10 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
if (!aUrl.IsEmpty()) { if (!aUrl.IsEmpty()) {
AppendUTF16toUTF8(aUrl, url); AppendUTF16toUTF8(aUrl, url);
// It's safe to skip the security check below if we're not a dialog /* Check whether the URI is allowed, but not for dialogs --
// because window.openDialog is not callable from content script. See bug see bug 56851. The security of this function depends on
// 56851. window.openDialog being inaccessible from web scripts */
// if (url.get() && !aDialog)
// If we're not navigating, we assume that whoever *does* navigate the
// window will do a security check of their own.
if (url.get() && !aDialog && aNavigate)
rv = SecurityCheckURL(url.get()); rv = SecurityCheckURL(url.get());
} }
@ -9233,9 +9201,6 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
const char *options_ptr = aOptions.IsEmpty() ? nsnull : options.get(); const char *options_ptr = aOptions.IsEmpty() ? nsnull : options.get();
const char *name_ptr = aName.IsEmpty() ? nsnull : name.get(); const char *name_ptr = aName.IsEmpty() ? nsnull : name.get();
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
NS_ENSURE_STATE(pwwatch);
{ {
// Reset popup state while opening a window to prevent the // Reset popup state while opening a window to prevent the
// current state from being active the whole time a modal // current state from being active the whole time a modal
@ -9243,12 +9208,15 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
nsAutoPopupStatePusher popupStatePusher(openAbused, true); nsAutoPopupStatePusher popupStatePusher(openAbused, true);
if (!aCalledNoScript) { if (!aCalledNoScript) {
// We asserted at the top of this function that aNavigate is true for nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
// !aCalledNoScript. NS_ASSERTION(pwwatch,
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr, "Unable to open windows from JS because window watcher "
/* aCalledFromScript = */ true, "is broken");
aDialog, aNavigate, argv, NS_ENSURE_TRUE(pwwatch, NS_ERROR_UNEXPECTED);
getter_AddRefs(domReturn));
rv = pwwatch->OpenWindowJS(this, url.get(), name_ptr, options_ptr,
aDialog, argv,
getter_AddRefs(domReturn));
} else { } else {
// Push a null JSContext here so that the window watcher won't screw us // Push a null JSContext here so that the window watcher won't screw us
// up. We do NOT want this case looking at the JS context on the stack // up. We do NOT want this case looking at the JS context on the stack
@ -9264,11 +9232,9 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
rv = stack->Push(nsnull); rv = stack->Push(nsnull);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr, rv = wwatch->OpenWindow(this, url.get(), name_ptr, options_ptr,
/* aCalledFromScript = */ false, aExtraArgument, getter_AddRefs(domReturn));
aDialog, aNavigate, aExtraArgument,
getter_AddRefs(domReturn));
if (stack) { if (stack) {
JSContext* cx; JSContext* cx;

View File

@ -674,56 +674,37 @@ protected:
} }
// Window Control Functions // Window Control Functions
virtual nsresult
OpenNoNavigate(const nsAString& aUrl,
const nsAString& aName,
const nsAString& aOptions,
nsIDOMWindow **_retval);
/** /**
* @param aUrl the URL we intend to load into the window. If aNavigate is * @param aURL the URL to load in the new window
* true, we'll actually load this URL into the window. Otherwise,
* aUrl is advisory; OpenInternal will not load the URL into the
* new window.
*
* @param aName the name to use for the new window * @param aName the name to use for the new window
*
* @param aOptions the window options to use for the new window * @param aOptions the window options to use for the new window
*
* @param aDialog true when called from variants of OpenDialog. If this is * @param aDialog true when called from variants of OpenDialog. If this is
* true, this method will skip popup blocking checks. The aDialog * true, this method will skip popup blocking checks. The
* argument is passed on to the window watcher. * aDialog argument is passed on to the window watcher.
*
* @param aCalledNoScript true when called via the [noscript] open() * @param aCalledNoScript true when called via the [noscript] open()
* and openDialog() methods. When this is true, we do NOT want to use * and openDialog() methods. When this is true, we do
* the JS stack for things like caller determination. * NOT want to use the JS stack for things like caller
* * determination.
* @param aDoJSFixups true when this is the content-accessible JS version of * @param aDoJSFixups true when this is the content-accessible JS version of
* window opening. When true, popups do not cause us to throw, we save * window opening. When true, popups do not cause us to
* the caller's principal in the new window for later consumption, and * throw, we save the caller's principal in the new window
* we make sure that there is a document in the newly-opened window. * for later consumption, and we make sure that there is a
* Note that this last will only be done if the newly-opened window is * document in the newly-opened window. Note that this
* non-chrome. * last will only be done if the newly-opened window is
* * non-chrome.
* @param aNavigate true if we should navigate to the provided URL, false
* otherwise. When aNavigate is false, we also skip our can-load
* security check, on the assumption that whoever *actually* loads this
* page will do their own security check.
*
* @param argv The arguments to pass to the new window. The first * @param argv The arguments to pass to the new window. The first
* three args, if present, will be aUrl, aName, and aOptions. So this * three args, if present, will be aURL, aName, and aOptions. So
* param only matters if there are more than 3 arguments. * this param only matters if there are more than 3 arguments.
*
* @param argc The number of arguments in argv. * @param argc The number of arguments in argv.
*
* @param aExtraArgument Another way to pass arguments in. This is mutually * @param aExtraArgument Another way to pass arguments in. This is mutually
* exclusive with the argv/argc approach. * exclusive with the argv/argc approach.
*
* @param aJSCallerContext The calling script's context. This must be nsnull * @param aJSCallerContext The calling script's context. This must be nsnull
* when aCalledNoScript is true. * when aCalledNoScript is true.
*
* @param aReturn [out] The window that was opened, if any. * @param aReturn [out] The window that was opened, if any.
*
* @note that the boolean args are const because the function shouldn't be
* messing with them. That also makes it easier for the compiler to sort out
* its build warning stuff.
*/ */
NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl, NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl,
const nsAString& aName, const nsAString& aName,
@ -732,7 +713,6 @@ protected:
bool aContentModal, bool aContentModal,
bool aCalledNoScript, bool aCalledNoScript,
bool aDoJSFixups, bool aDoJSFixups,
bool aNavigate,
nsIArray *argv, nsIArray *argv,
nsISupports *aExtraArgument, nsISupports *aExtraArgument,
nsIPrincipal *aCalleePrincipal, nsIPrincipal *aCalleePrincipal,

View File

@ -48,8 +48,8 @@ class nsIArray;
class nsPIWindowRoot; class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \ #define NS_PIDOMWINDOW_IID \
{0x66660102, 0xd875, 0x47e2, \ { 0x0c4d0b84, 0xb524, 0x4572, \
{0xa1, 0xf7, 0x12, 0xbc, 0x83, 0xc9, 0x93, 0xa9}} { 0x8e, 0xd1, 0x7f, 0x78, 0x14, 0x7c, 0x4d, 0xf1 } }
class nsPIDOMWindow : public nsIDOMWindowInternal class nsPIDOMWindow : public nsIDOMWindowInternal
{ {
@ -602,13 +602,6 @@ public:
*/ */
virtual bool IsPartOfApp() = 0; virtual bool IsPartOfApp() = 0;
/**
* Like nsIDOMWindow::Open, except that we don't navigate to the given URL.
*/
virtual nsresult
OpenNoNavigate(const nsAString& aUrl, const nsAString& aName,
const nsAString& aOptions, nsIDOMWindow **_retval) = 0;
protected: protected:
// The nsPIDOMWindow constructor. The aOuterWindow argument should // The nsPIDOMWindow constructor. The aOuterWindow argument should
// be null if and only if the created window itself is an outer // be null if and only if the created window itself is an outer

View File

@ -193,9 +193,7 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
NS_ENSURE_TRUE(popupFrameElement, false); NS_ENSURE_TRUE(popupFrameElement, false);
nsCAutoString spec; nsCAutoString spec;
if (aURI) { aURI->GetSpec(spec);
aURI->GetSpec(spec);
}
bool dispatchSucceeded = bool dispatchSucceeded =
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
NS_ConvertUTF8toUTF16(spec), NS_ConvertUTF8toUTF16(spec),

View File

@ -53,8 +53,6 @@ public:
* set aPopupTabParent's frame element to event.detail.frameElement. * set aPopupTabParent's frame element to event.detail.frameElement.
* Otherwise, we return false. * Otherwise, we return false.
* *
* @param aURL the absolute URL the new window should load. The empty string
* is allowed indicates we shouldn't load anything.
* @param aOpenerTabParent the TabParent whose TabChild called window.open. * @param aOpenerTabParent the TabParent whose TabChild called window.open.
* @param aPopupTabParent the TabParent inside which the opened window will * @param aPopupTabParent the TabParent inside which the opened window will
* live. * live.
@ -77,9 +75,6 @@ public:
* *
* (These parameter types are silly, but they match what our caller has in * (These parameter types are silly, but they match what our caller has in
* hand. Feel free to add an override, if they are inconvenient to you.) * hand. Feel free to add an override, if they are inconvenient to you.)
*
* @param aURI the URI the new window should load. May be null, which
* indicates that we shouldn't load anything.
*/ */
static bool static bool
OpenWindowInProcess(nsIDOMWindow* aOpenerWindow, OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,

View File

@ -63,9 +63,6 @@ MOCHITEST_FILES = \
test_browserElement_inproc_AlertInFrame.html \ test_browserElement_inproc_AlertInFrame.html \
file_browserElement_AlertInFrame.html \ file_browserElement_AlertInFrame.html \
file_browserElement_AlertInFrame_Inner.html \ file_browserElement_AlertInFrame_Inner.html \
browserElement_TargetBlank.js \
test_browserElement_inproc_TargetBlank.html \
file_browserElement_TargetBlank.html \
browserElement_TargetTop.js \ browserElement_TargetTop.js \
test_browserElement_inproc_TargetTop.html \ test_browserElement_inproc_TargetTop.html \
file_browserElement_TargetTop.html \ file_browserElement_TargetTop.html \
@ -133,7 +130,6 @@ MOCHITEST_FILES += \
test_browserElement_oop_XFrameOptionsSameOrigin.html \ test_browserElement_oop_XFrameOptionsSameOrigin.html \
test_browserElement_oop_Alert.html \ test_browserElement_oop_Alert.html \
test_browserElement_oop_AlertInFrame.html \ test_browserElement_oop_AlertInFrame.html \
test_browserElement_oop_TargetBlank.html \
test_browserElement_oop_TargetTop.html \ test_browserElement_oop_TargetTop.html \
test_browserElement_oop_PromptCheck.html \ test_browserElement_oop_PromptCheck.html \
test_browserElement_oop_PromptConfirm.html \ test_browserElement_oop_PromptConfirm.html \

View File

@ -1,26 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 764718 - Test that clicking a link with _target=blank works.
"use strict";
SimpleTest.waitForExplicitFinish();
function runTest() {
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addToWhitelist();
var iframe = document.createElement('iframe');
iframe.mozbrowser = true;
iframe.addEventListener('mozbrowseropenwindow', function(e) {
is(e.detail.url, 'http://example.com/');
SimpleTest.finish();
});
iframe.src = "file_browserElement_TargetBlank.html";
document.body.appendChild(iframe);
}
runTest();

View File

@ -1,18 +0,0 @@
<html>
<body>
<a id='link' target='_blank' href="http://example.com">Click me</a>
<script>
function clickLink() {
// See testcase in bug 666604.
var e = document.createEvent("MouseEvent");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0,
false, false, false, false, 0, null);
document.getElementById('link').dispatchEvent(e);
}
addEventListener('load', function() { setTimeout(clickLink, 0) });
</script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for mozbrowser</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_TargetBlank.js">
</script>
</body>
</html>

View File

@ -1,13 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for mozbrowser</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_TargetBlank.js">
</script>
</body>
</html>

View File

@ -385,9 +385,7 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
/* aChromeFlags = */ 0, mIsBrowserElement, mAppId)); /* aChromeFlags = */ 0, mIsBrowserElement, mAppId));
nsCAutoString spec; nsCAutoString spec;
if (aURI) { aURI->GetSpec(spec);
aURI->GetSpec(spec);
}
NS_ConvertUTF8toUTF16 url(spec); NS_ConvertUTF8toUTF16 url(spec);
nsString name(aName); nsString name(aName);

View File

@ -34,51 +34,44 @@ interface nsIWindowProvider : nsISupports
* to have the caller create a brand-new window. * to have the caller create a brand-new window.
* *
* @param aParent Must not be null. This is the window that the caller wants * @param aParent Must not be null. This is the window that the caller wants
* to use as the parent for the new window. Generally, * to use as the parent for the new window. Generally,
* nsIWindowProvider implementors can expect to be somehow related to * nsIWindowProvider implementors can expect to be somehow
* aParent; the relationship may depend on the nsIWindowProvider * related to aParent; the relationship may depend on the
* implementation. * nsIWindowProvider implementation.
*
* @param aChromeFlags The chrome flags the caller will use to create a new * @param aChromeFlags The chrome flags the caller will use to create a new
* window if this provider returns null. See nsIWebBrowserChrome for * window if this provider returns null. See
* the possible values of this field. * nsIWebBrowserChrome for the possible values of this
* * field.
* @param aPositionSpecified Whether the attempt to create a window is trying * @param aPositionSpecified Whether the attempt to create a window is trying
* to specify a position for the new window. * to specify a position for the new window.
*
* @param aSizeSpecified Whether the attempt to create a window is trying to * @param aSizeSpecified Whether the attempt to create a window is trying to
* specify a size for the new window. * specify a size for the new window.
* * @param aURI The URI to be loaded in the new window. The nsIWindowProvider
* @param aURI The URI to be loaded in the new window (may be NULL). The * implementation MUST NOT load this URI in the window it
* nsIWindowProvider implementation must not load this URI into the * returns. This URI is provided solely to help the
* window it returns. This URI is provided solely to help the * nsIWindowProvider implementation make decisions; the caller
* nsIWindowProvider implementation make decisions; the caller will * will handle loading the URI in the window returned if
* handle loading the URI in the window returned if provideWindow * provideWindow returns a window. Note that the URI may be null
* returns a window. * if the load cannot be represented by a single URI (e.g. if
* * the load has extra load flags, POST data, etc).
* When making decisions based on aURI, note that even when it's not
* null, aURI may not represent all relevant information about the
* load. For example, the load may have extra load flags, POST data,
* etc.
*
* @param aName The name of the window being opened. Setting the name on the * @param aName The name of the window being opened. Setting the name on the
* return value of provideWindow will be handled by the caller; aName * return value of provideWindow will be handled by the caller;
* is provided solely to help the nsIWindowProvider implementation * aName is provided solely to help the nsIWindowProvider
* make decisions. * implementation make decisions.
*
* @param aFeatures The feature string for the window being opened. This may * @param aFeatures The feature string for the window being opened. This may
* be empty. The nsIWindowProvider implementation is allowed to apply * be empty. The nsIWindowProvider implementation is
* the feature string to the window it returns in any way it sees fit. * allowed to apply the feature string to the window it
* See the nsIWindowWatcher interface for details on feature strings. * returns in any way it sees fit. See the nsIWindowWatcher
* * interface for details on feature strings.
* @param aWindowIsNew [out] Whether the window being returned was just * @param aWindowIsNew [out] Whether the window being returned was just
* created by the window provider implementation. This can be used by * created by the window provider implementation.
* callers to keep track of which windows were opened by the user as * This can be used by callers to keep track of which
* opposed to being opened programmatically. This should be set to * windows were opened by the user as opposed to
* false if the window being returned existed before the * being opened programmatically. This should be set
* provideWindow() call. The value of this out parameter is * to false if the window being returned existed
* meaningless if provideWindow() returns null. * before the provideWindow() call. The value of this
* out parameter is meaningless if provideWindow()
* returns null.
* @return A window the caller should use or null if the caller should just * @return A window the caller should use or null if the caller should just
* create a new window. The returned window may be newly opened by * create a new window. The returned window may be newly opened by
* the nsIWindowProvider implementation or may be a window that * the nsIWindowProvider implementation or may be a window that

View File

@ -16,7 +16,7 @@ interface nsIWebBrowserChrome;
interface nsIDocShellTreeItem; interface nsIDocShellTreeItem;
interface nsIArray; interface nsIArray;
[uuid(00788A84-152F-4BD8-A814-FD8EB545DB29)] [uuid(8624594a-28d7-4bc3-8d12-b1c2b9eefd90)]
interface nsPIWindowWatcher : nsISupports interface nsPIWindowWatcher : nsISupports
{ {
@ -35,9 +35,8 @@ interface nsPIWindowWatcher : nsISupports
*/ */
void removeWindow(in nsIDOMWindow aWindow); void removeWindow(in nsIDOMWindow aWindow);
/** Like the public interface's open(), but can handle openDialog-style /** Like the public interface's open(), but can deal with openDialog
arguments and calls which shouldn't result in us navigating the window. style arguments.
@param aParent parent window, if any. Null if no parent. If it is @param aParent parent window, if any. Null if no parent. If it is
impossible to get to an nsIWebBrowserChrome from aParent, this impossible to get to an nsIWebBrowserChrome from aParent, this
method will effectively act as if aParent were null. method will effectively act as if aParent were null.
@ -47,10 +46,7 @@ interface nsPIWindowWatcher : nsISupports
with this name already exists, the openWindow call may just load with this name already exists, the openWindow call may just load
aUrl in it (if aUrl is not null) and return it. aUrl in it (if aUrl is not null) and return it.
@param aFeatures window features from JS window.open. can be null. @param aFeatures window features from JS window.open. can be null.
@param aCalledFromScript true if we were called from script.
@param aDialog use dialog defaults (see nsIDOMWindow::openDialog) @param aDialog use dialog defaults (see nsIDOMWindow::openDialog)
@param aNavigate true if we should navigate the new window to the
specified URL.
@param aArgs Window argument @param aArgs Window argument
@return the new window @return the new window
@ -62,10 +58,9 @@ interface nsPIWindowWatcher : nsISupports
(which is determined based on the JS stack and the value of (which is determined based on the JS stack and the value of
aParent). This is not guaranteed, however. aParent). This is not guaranteed, however.
*/ */
nsIDOMWindow openWindow2(in nsIDOMWindow aParent, in string aUrl, nsIDOMWindow openWindowJS(in nsIDOMWindow aParent, in string aUrl,
in string aName, in string aFeatures, in string aName, in string aFeatures, in boolean aDialog,
in boolean aCalledFromScript, in boolean aDialog, in nsIArray aArgs);
in boolean aNavigate, in nsISupports aArgs);
/** /**
* Find a named docshell tree item amongst all windows registered * Find a named docshell tree item amongst all windows registered

View File

@ -319,64 +319,6 @@ nsWindowWatcher::Init()
return NS_OK; return NS_OK;
} }
/**
* Convert aArguments into either an nsIArray or NULL.
*
* - If aArguments is NULL, return NULL.
* - If aArguments is an nsArray, return NULL if it's empty, or otherwise
* return the array.
* - If aArguments is an nsISupportsArray, return NULL if it's empty, or
* otherwise add its elements to an nsArray and return the new array.
* - Otherwise, return an nsIArray with one element: aArguments.
*/
static already_AddRefed<nsIArray>
ConvertArgsToArray(nsISupports* aArguments)
{
if (!aArguments) {
return NULL;
}
nsCOMPtr<nsIArray> array = do_QueryInterface(aArguments);
if (array) {
PRUint32 argc = 0;
array->GetLength(&argc);
if (argc == 0)
return NULL;
return array.forget();
}
nsCOMPtr<nsISupportsArray> supArray = do_QueryInterface(aArguments);
if (supArray) {
PRUint32 argc = 0;
supArray->Count(&argc);
if (argc == 0) {
return NULL;
}
nsCOMPtr<nsIMutableArray> mutableArray =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_TRUE(mutableArray, NULL);
for (PRUint32 i = 0; i < argc; i++) {
nsCOMPtr<nsISupports> elt = dont_AddRef(supArray->ElementAt(i));
nsresult rv = mutableArray->AppendElement(elt, /* aWeak = */ false);
NS_ENSURE_SUCCESS(rv, NULL);
}
return mutableArray.forget();
}
nsCOMPtr<nsIMutableArray> singletonArray =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_TRUE(singletonArray, NULL);
nsresult rv = singletonArray->AppendElement(aArguments, /* aWeak = */ false);
NS_ENSURE_SUCCESS(rv, NULL);
return singletonArray.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent, nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
const char *aUrl, const char *aUrl,
@ -385,17 +327,58 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
nsISupports *aArguments, nsISupports *aArguments,
nsIDOMWindow **_retval) nsIDOMWindow **_retval)
{ {
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments); nsCOMPtr<nsIArray> argsArray;
PRUint32 argc = 0; PRUint32 argc = 0;
if (argv) { if (aArguments) {
argv->GetLength(&argc); // aArguments is allowed to be either an nsISupportsArray or an nsIArray
} // (in which case it is treated as argv) or any other COM object (in which
bool dialog = (argc != 0); // case it becomes argv[0]).
nsresult rv;
return OpenWindowInternal(aParent, aUrl, aName, aFeatures, nsCOMPtr<nsISupportsArray> supArray(do_QueryInterface(aArguments));
/* calledFromJS = */ false, dialog, if (!supArray) {
/* navigate = */ true, argv, _retval); nsCOMPtr<nsIArray> array(do_QueryInterface(aArguments));
if (!array) {
nsCOMPtr<nsIMutableArray> muteArray;
argsArray = muteArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = muteArray->AppendElement(aArguments, false);
if (NS_FAILED(rv))
return rv;
argc = 1;
} else {
rv = array->GetLength(&argc);
if (NS_FAILED(rv))
return rv;
if (argc > 0)
argsArray = array;
}
} else {
// nsISupports array - copy into nsIArray...
rv = supArray->Count(&argc);
if (NS_FAILED(rv))
return rv;
// But only create an arguments array if there's at least one element in
// the supports array.
if (argc > 0) {
nsCOMPtr<nsIMutableArray> muteArray;
argsArray = muteArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
for (PRUint32 i = 0; i < argc; i++) {
nsCOMPtr<nsISupports> elt(dont_AddRef(supArray->ElementAt(i)));
rv = muteArray->AppendElement(elt, false);
if (NS_FAILED(rv))
return rv;
}
}
}
}
bool dialog = (argc != 0);
return OpenWindowJSInternal(aParent, aUrl, aName, aFeatures, dialog,
argsArray, false, _retval);
} }
struct SizeSpec { struct SizeSpec {
@ -440,32 +423,38 @@ struct SizeSpec {
}; };
NS_IMETHODIMP NS_IMETHODIMP
nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent, nsWindowWatcher::OpenWindowJS(nsIDOMWindow *aParent,
const char *aUrl, const char *aUrl,
const char *aName, const char *aName,
const char *aFeatures, const char *aFeatures,
bool aCalledFromScript,
bool aDialog, bool aDialog,
bool aNavigate, nsIArray *argv,
nsISupports *aArguments,
nsIDOMWindow **_retval) nsIDOMWindow **_retval)
{ {
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments); if (argv) {
return OpenWindowInternal(aParent, aUrl, aName, aFeatures, PRUint32 argc;
aCalledFromScript, aDialog, nsresult rv = argv->GetLength(&argc);
aNavigate, argv, _retval); NS_ENSURE_SUCCESS(rv, rv);
// For compatibility with old code, no arguments implies that we shouldn't
// create an arguments object on the new window at all.
if (argc == 0)
argv = nsnull;
}
return OpenWindowJSInternal(aParent, aUrl, aName, aFeatures, aDialog,
argv, true, _retval);
} }
nsresult nsresult
nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent, nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
const char *aUrl, const char *aUrl,
const char *aName, const char *aName,
const char *aFeatures, const char *aFeatures,
bool aCalledFromJS, bool aDialog,
bool aDialog, nsIArray *argv,
bool aNavigate, bool aCalledFromJS,
nsIArray *argv, nsIDOMWindow **_retval)
nsIDOMWindow **_retval)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
bool nameSpecified, bool nameSpecified,
@ -875,7 +864,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
} }
} }
if (uriToLoad && aNavigate) { // get the script principal and pass it to docshell if (uriToLoad) { // get the script principal and pass it to docshell
JSContextAutoPopper contextGuard; JSContextAutoPopper contextGuard;
cx = GetJSContextFromCallStack(); cx = GetJSContextFromCallStack();

View File

@ -72,15 +72,14 @@ protected:
// Just like OpenWindowJS, but knows whether it got called via OpenWindowJS // Just like OpenWindowJS, but knows whether it got called via OpenWindowJS
// (which means called from script) or called via OpenWindow. // (which means called from script) or called via OpenWindow.
nsresult OpenWindowInternal(nsIDOMWindow *aParent, nsresult OpenWindowJSInternal(nsIDOMWindow *aParent,
const char *aUrl, const char *aUrl,
const char *aName, const char *aName,
const char *aFeatures, const char *aFeatures,
bool aCalledFromJS, bool aDialog,
bool aDialog, nsIArray *argv,
bool aNavigate, bool aCalledFromJS,
nsIArray *argv, nsIDOMWindow **_retval);
nsIDOMWindow **_retval);
static JSContext *GetJSContextFromWindow(nsIDOMWindow *aWindow); static JSContext *GetJSContextFromWindow(nsIDOMWindow *aWindow);
static JSContext *GetJSContextFromCallStack(); static JSContext *GetJSContextFromCallStack();

View File

@ -373,7 +373,7 @@ function openModalWindow(domWin, uri, args) {
// domWin may still be null here if there are _no_ windows open. // domWin may still be null here if there are _no_ windows open.
// Note that we don't need to fire DOMWillOpenModalDialog and // Note that we don't need to fire DOMWillOpenModalDialog and
// DOMModalDialogClosed events here, wwatcher's OpenWindowInternal // DOMModalDialogClosed events here, wwatcher's OpenWindowJSInternal
// will do that. Similarly for enterModalState / leaveModalState. // will do that. Similarly for enterModalState / leaveModalState.
Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args); Services.ww.openWindow(domWin, uri, "_blank", "centerscreen,chrome,modal,titlebar", args);
@ -413,7 +413,7 @@ function openTabPrompt(domWin, tabPrompt, args) {
newPrompt = tabPrompt.appendPrompt(args, onPromptClose); newPrompt = tabPrompt.appendPrompt(args, onPromptClose);
// TODO since we don't actually open a window, need to check if // TODO since we don't actually open a window, need to check if
// there's other stuff in nsWindowWatcher::OpenWindowInternal // there's other stuff in nsWindowWatcher::OpenWindowJSInternal
// that we might need to do here as well. // that we might need to do here as well.
let thread = Services.tm.currentThread; let thread = Services.tm.currentThread;