зеркало из https://github.com/mozilla/gecko-dev.git
Bug 769254 - Part 2: Modify nsPIWindowWatcher::OpenWindowJS (renamed to OpenWindow2) so we can pass in the URL for target=_blank links without navigating the opened window to that URL. r=bz
--HG-- extra : rebase_source : 1de945d5933824d79866bbc61e2493f96217a9ee
This commit is contained in:
Родитель
034c7af655
Коммит
5fc011fdb8
|
@ -8294,16 +8294,19 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
|
||||
bool isNewWindow = false;
|
||||
if (!targetDocShell) {
|
||||
nsCOMPtr<nsIDOMWindow> win =
|
||||
nsCOMPtr<nsPIDOMWindow> win =
|
||||
do_GetInterface(GetAsSupports(this));
|
||||
NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsDependentString name(aWindowTarget);
|
||||
nsCOMPtr<nsIDOMWindow> newWin;
|
||||
rv = win->Open(EmptyString(), // URL to load
|
||||
name, // window name
|
||||
EmptyString(), // Features
|
||||
getter_AddRefs(newWin));
|
||||
nsCAutoString spec;
|
||||
if (aURI)
|
||||
aURI->GetSpec(spec);
|
||||
rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec),
|
||||
name, // window name
|
||||
EmptyString(), // Features
|
||||
getter_AddRefs(newWin));
|
||||
|
||||
// In some cases the Open call doesn't actually result in a new
|
||||
// window being opened. We can detect these cases by examining the
|
||||
|
|
|
@ -5846,6 +5846,7 @@ nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName,
|
|||
false, // aContentModal
|
||||
true, // aCalledNoScript
|
||||
false, // aDoJSFixups
|
||||
true, // aNavigate
|
||||
nsnull, nsnull, // No args
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsnull, // aJSCallerContext
|
||||
|
@ -5861,6 +5862,7 @@ nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName,
|
|||
false, // aContentModal
|
||||
false, // aCalledNoScript
|
||||
true, // aDoJSFixups
|
||||
true, // aNavigate
|
||||
nsnull, nsnull, // No args
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsContentUtils::GetCurrentJSContext(), // aJSCallerContext
|
||||
|
@ -5879,12 +5881,33 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
|
|||
false, // aContentModal
|
||||
true, // aCalledNoScript
|
||||
false, // aDoJSFixups
|
||||
true, // aNavigate
|
||||
nsnull, aExtraArgument, // Arguments
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsnull, // aJSCallerContext
|
||||
_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
|
||||
nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
|
||||
const nsAString& aOptions, nsIDOMWindow** _retval)
|
||||
|
@ -5925,6 +5948,7 @@ nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
|
|||
false, // aContentModal
|
||||
false, // aCalledNoScript
|
||||
false, // aDoJSFixups
|
||||
true, // aNavigate
|
||||
argvArray, nsnull, // Arguments
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
cx, // aJSCallerContext
|
||||
|
@ -7168,6 +7192,7 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
|
|||
true, // aContentModal
|
||||
true, // aCalledNoScript
|
||||
true, // aDoJSFixups
|
||||
true, // aNavigate
|
||||
nsnull, aArgs, // args
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsnull, // aJSCallerContext
|
||||
|
@ -9089,7 +9114,8 @@ nsresult
|
|||
nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||
const nsAString& aOptions, bool aDialog,
|
||||
bool aContentModal, bool aCalledNoScript,
|
||||
bool aDoJSFixups, nsIArray *argv,
|
||||
bool aDoJSFixups, bool aNavigate,
|
||||
nsIArray *argv,
|
||||
nsISupports *aExtraArgument,
|
||||
nsIPrincipal *aCalleePrincipal,
|
||||
JSContext *aJSCallerContext,
|
||||
|
@ -9097,8 +9123,8 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
{
|
||||
FORWARD_TO_OUTER(OpenInternal, (aUrl, aName, aOptions, aDialog,
|
||||
aContentModal, aCalledNoScript, aDoJSFixups,
|
||||
argv, aExtraArgument, aCalleePrincipal,
|
||||
aJSCallerContext, aReturn),
|
||||
aNavigate, argv, aExtraArgument,
|
||||
aCalleePrincipal, aJSCallerContext, aReturn),
|
||||
NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -9113,6 +9139,9 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript,
|
||||
"Shouldn't have caller context when called noscript");
|
||||
|
||||
// Calls to window.open from script should navigate.
|
||||
MOZ_ASSERT(aCalledNoScript || aNavigate);
|
||||
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserChrome> chrome;
|
||||
|
@ -9140,10 +9169,13 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
if (!aUrl.IsEmpty()) {
|
||||
AppendUTF16toUTF8(aUrl, url);
|
||||
|
||||
/* Check whether the URI is allowed, but not for dialogs --
|
||||
see bug 56851. The security of this function depends on
|
||||
window.openDialog being inaccessible from web scripts */
|
||||
if (url.get() && !aDialog)
|
||||
// It's safe to skip the security check below if we're not a dialog
|
||||
// because window.openDialog is not callable from content script. See bug
|
||||
// 56851.
|
||||
//
|
||||
// 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());
|
||||
}
|
||||
|
||||
|
@ -9184,6 +9216,9 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
const char *options_ptr = aOptions.IsEmpty() ? nsnull : options.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
|
||||
// current state from being active the whole time a modal
|
||||
|
@ -9191,15 +9226,12 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
nsAutoPopupStatePusher popupStatePusher(openAbused, true);
|
||||
|
||||
if (!aCalledNoScript) {
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
|
||||
NS_ASSERTION(pwwatch,
|
||||
"Unable to open windows from JS because window watcher "
|
||||
"is broken");
|
||||
NS_ENSURE_TRUE(pwwatch, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rv = pwwatch->OpenWindowJS(this, url.get(), name_ptr, options_ptr,
|
||||
aDialog, argv,
|
||||
getter_AddRefs(domReturn));
|
||||
// We asserted at the top of this function that aNavigate is true for
|
||||
// !aCalledNoScript.
|
||||
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ true,
|
||||
aDialog, aNavigate, argv,
|
||||
getter_AddRefs(domReturn));
|
||||
} else {
|
||||
// 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
|
||||
|
@ -9215,9 +9247,11 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
rv = stack->Push(nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = wwatch->OpenWindow(this, url.get(), name_ptr, options_ptr,
|
||||
aExtraArgument, getter_AddRefs(domReturn));
|
||||
|
||||
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
|
||||
/* aCalledFromScript = */ false,
|
||||
aDialog, aNavigate, aExtraArgument,
|
||||
getter_AddRefs(domReturn));
|
||||
|
||||
if (stack) {
|
||||
JSContext* cx;
|
||||
|
|
|
@ -673,37 +673,56 @@ protected:
|
|||
}
|
||||
|
||||
// Window Control Functions
|
||||
|
||||
virtual nsresult
|
||||
OpenNoNavigate(const nsAString& aUrl,
|
||||
const nsAString& aName,
|
||||
const nsAString& aOptions,
|
||||
nsIDOMWindow **_retval);
|
||||
|
||||
/**
|
||||
* @param aURL the URL to load in 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 aDialog true when called from variants of OpenDialog. If this is
|
||||
* true, this method will skip popup blocking checks. The
|
||||
* aDialog argument is passed on to the window watcher.
|
||||
* @param aCalledNoScript true when called via the [noscript] open()
|
||||
* and openDialog() methods. When this is true, we do
|
||||
* NOT want to use the JS stack for things like caller
|
||||
* determination.
|
||||
* @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 the caller's principal in the new window
|
||||
* for later consumption, and we make sure that there is a
|
||||
* document in the newly-opened window. Note that this
|
||||
* last will only be done if the newly-opened window is
|
||||
* non-chrome.
|
||||
* @param argv The arguments to pass to the new window. The first
|
||||
* three args, if present, will be aURL, aName, and aOptions. So
|
||||
* this param only matters if there are more than 3 arguments.
|
||||
* @param argc The number of arguments in argv.
|
||||
* @param aExtraArgument Another way to pass arguments in. This is mutually
|
||||
* exclusive with the argv/argc approach.
|
||||
* @param aJSCallerContext The calling script's context. This must be nsnull
|
||||
* when aCalledNoScript is true.
|
||||
* @param aReturn [out] The window that was opened, if any.
|
||||
* @param aUrl the URL we intend to load into the window. If aNavigate is
|
||||
* true, we'll actually load this URL into the window. Otherwise,
|
||||
* aUrl is advisory; OpenInternal will not load the URL into the
|
||||
* new window.
|
||||
*
|
||||
* @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.
|
||||
* @param aName the name 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
|
||||
* true, this method will skip popup blocking checks. The aDialog
|
||||
* argument is passed on to the window watcher.
|
||||
*
|
||||
* @param aCalledNoScript true when called via the [noscript] open()
|
||||
* and openDialog() methods. When this is true, we do NOT want to use
|
||||
* the JS stack for things like caller determination.
|
||||
*
|
||||
* @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
|
||||
* the caller's principal in the new window for later consumption, and
|
||||
* we make sure that there is a document in the newly-opened window.
|
||||
* Note that this 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
|
||||
* three args, if present, will be aUrl, aName, and aOptions. So this
|
||||
* param only matters if there are more than 3 arguments.
|
||||
*
|
||||
* @param argc The number of arguments in argv.
|
||||
*
|
||||
* @param aExtraArgument Another way to pass arguments in. This is mutually
|
||||
* exclusive with the argv/argc approach.
|
||||
*
|
||||
* @param aJSCallerContext The calling script's context. This must be nsnull
|
||||
* when aCalledNoScript is true.
|
||||
*
|
||||
* @param aReturn [out] The window that was opened, if any.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl,
|
||||
const nsAString& aName,
|
||||
|
@ -712,6 +731,7 @@ protected:
|
|||
bool aContentModal,
|
||||
bool aCalledNoScript,
|
||||
bool aDoJSFixups,
|
||||
bool aNavigate,
|
||||
nsIArray *argv,
|
||||
nsISupports *aExtraArgument,
|
||||
nsIPrincipal *aCalleePrincipal,
|
||||
|
|
|
@ -48,8 +48,8 @@ class nsIArray;
|
|||
class nsPIWindowRoot;
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0x0c4d0b84, 0xb524, 0x4572, \
|
||||
{ 0x8e, 0xd1, 0x7f, 0x78, 0x14, 0x7c, 0x4d, 0xf1 } }
|
||||
{0x66660102, 0xd875, 0x47e2, \
|
||||
{0xa1, 0xf7, 0x12, 0xbc, 0x83, 0xc9, 0x93, 0xa9}}
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
|
@ -602,6 +602,13 @@ public:
|
|||
*/
|
||||
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:
|
||||
// The nsPIDOMWindow constructor. The aOuterWindow argument should
|
||||
// be null if and only if the created window itself is an outer
|
||||
|
|
|
@ -34,44 +34,51 @@ interface nsIWindowProvider : nsISupports
|
|||
* to have the caller create a brand-new window.
|
||||
*
|
||||
* @param aParent Must not be null. This is the window that the caller wants
|
||||
* to use as the parent for the new window. Generally,
|
||||
* nsIWindowProvider implementors can expect to be somehow
|
||||
* related to aParent; the relationship may depend on the
|
||||
* nsIWindowProvider implementation.
|
||||
* to use as the parent for the new window. Generally,
|
||||
* nsIWindowProvider implementors can expect to be somehow related to
|
||||
* aParent; the relationship may depend on the nsIWindowProvider
|
||||
* implementation.
|
||||
*
|
||||
* @param aChromeFlags The chrome flags the caller will use to create a new
|
||||
* window if this provider returns null. See
|
||||
* nsIWebBrowserChrome for the possible values of this
|
||||
* field.
|
||||
* window if this provider returns null. See nsIWebBrowserChrome for
|
||||
* the possible values of this field.
|
||||
*
|
||||
* @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
|
||||
* specify a size for the new window.
|
||||
* @param aURI The URI to be loaded in the new window. The nsIWindowProvider
|
||||
* implementation MUST NOT load this URI in the window it
|
||||
* returns. This URI is provided solely to help the
|
||||
* nsIWindowProvider implementation make decisions; the caller
|
||||
* will handle loading the URI in the window returned if
|
||||
* provideWindow returns a window. Note that the URI may be null
|
||||
* if the load cannot be represented by a single URI (e.g. if
|
||||
* the load has extra load flags, POST data, etc).
|
||||
* specify a size for the new window.
|
||||
*
|
||||
* @param aURI The URI to be loaded in the new window (may be NULL). The
|
||||
* nsIWindowProvider implementation must not load this URI into the
|
||||
* window it returns. This URI is provided solely to help the
|
||||
* nsIWindowProvider implementation make decisions; the caller will
|
||||
* handle loading the URI in the window returned if provideWindow
|
||||
* returns a window.
|
||||
*
|
||||
* 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
|
||||
* return value of provideWindow will be handled by the caller;
|
||||
* aName is provided solely to help the nsIWindowProvider
|
||||
* implementation make decisions.
|
||||
* return value of provideWindow will be handled by the caller; aName
|
||||
* is provided solely to help the nsIWindowProvider implementation
|
||||
* make decisions.
|
||||
*
|
||||
* @param aFeatures The feature string for the window being opened. This may
|
||||
* be empty. The nsIWindowProvider implementation is
|
||||
* allowed to apply the feature string to the window it
|
||||
* returns in any way it sees fit. See the nsIWindowWatcher
|
||||
* interface for details on feature strings.
|
||||
* be empty. The nsIWindowProvider implementation is allowed to apply
|
||||
* the feature string to the window it 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
|
||||
* created by the window provider implementation.
|
||||
* This can be used by callers to keep track of which
|
||||
* windows were opened by the user as opposed to
|
||||
* being opened programmatically. This should be set
|
||||
* to false if the window being returned existed
|
||||
* before the provideWindow() call. The value of this
|
||||
* out parameter is meaningless if provideWindow()
|
||||
* returns null.
|
||||
* created by the window provider implementation. This can be used by
|
||||
* callers to keep track of which windows were opened by the user as
|
||||
* opposed to being opened programmatically. This should be set to
|
||||
* false if the window being returned existed 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
|
||||
* create a new window. The returned window may be newly opened by
|
||||
* the nsIWindowProvider implementation or may be a window that
|
||||
|
|
|
@ -16,7 +16,7 @@ interface nsIWebBrowserChrome;
|
|||
interface nsIDocShellTreeItem;
|
||||
interface nsIArray;
|
||||
|
||||
[uuid(8624594a-28d7-4bc3-8d12-b1c2b9eefd90)]
|
||||
[uuid(00788A84-152F-4BD8-A814-FD8EB545DB29)]
|
||||
|
||||
interface nsPIWindowWatcher : nsISupports
|
||||
{
|
||||
|
@ -35,8 +35,9 @@ interface nsPIWindowWatcher : nsISupports
|
|||
*/
|
||||
void removeWindow(in nsIDOMWindow aWindow);
|
||||
|
||||
/** Like the public interface's open(), but can deal with openDialog
|
||||
style arguments.
|
||||
/** Like the public interface's open(), but can handle openDialog-style
|
||||
arguments and calls which shouldn't result in us navigating the window.
|
||||
|
||||
@param aParent parent window, if any. Null if no parent. If it is
|
||||
impossible to get to an nsIWebBrowserChrome from aParent, this
|
||||
method will effectively act as if aParent were null.
|
||||
|
@ -46,7 +47,10 @@ interface nsPIWindowWatcher : nsISupports
|
|||
with this name already exists, the openWindow call may just load
|
||||
aUrl in it (if aUrl is not null) and return it.
|
||||
@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 aNavigate true if we should navigate the new window to the
|
||||
specified URL.
|
||||
@param aArgs Window argument
|
||||
@return the new window
|
||||
|
||||
|
@ -58,9 +62,10 @@ interface nsPIWindowWatcher : nsISupports
|
|||
(which is determined based on the JS stack and the value of
|
||||
aParent). This is not guaranteed, however.
|
||||
*/
|
||||
nsIDOMWindow openWindowJS(in nsIDOMWindow aParent, in string aUrl,
|
||||
in string aName, in string aFeatures, in boolean aDialog,
|
||||
in nsIArray aArgs);
|
||||
nsIDOMWindow openWindow2(in nsIDOMWindow aParent, in string aUrl,
|
||||
in string aName, in string aFeatures,
|
||||
in boolean aCalledFromScript, in boolean aDialog,
|
||||
in boolean aNavigate, in nsISupports aArgs);
|
||||
|
||||
/**
|
||||
* Find a named docshell tree item amongst all windows registered
|
||||
|
|
|
@ -319,6 +319,64 @@ nsWindowWatcher::Init()
|
|||
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
|
||||
nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
|
||||
const char *aUrl,
|
||||
|
@ -327,58 +385,17 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
|
|||
nsISupports *aArguments,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
nsCOMPtr<nsIArray> argsArray;
|
||||
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
|
||||
|
||||
PRUint32 argc = 0;
|
||||
if (aArguments) {
|
||||
// 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
|
||||
// case it becomes argv[0]).
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> supArray(do_QueryInterface(aArguments));
|
||||
if (!supArray) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argv) {
|
||||
argv->GetLength(&argc);
|
||||
}
|
||||
|
||||
bool dialog = (argc != 0);
|
||||
return OpenWindowJSInternal(aParent, aUrl, aName, aFeatures, dialog,
|
||||
argsArray, false, _retval);
|
||||
|
||||
return OpenWindowJSInternal(aParent, aUrl, aName, aFeatures,
|
||||
/* calledFromJS = */ false, dialog,
|
||||
/* navigate = */ true, argv, _retval);
|
||||
}
|
||||
|
||||
struct SizeSpec {
|
||||
|
@ -423,27 +440,20 @@ struct SizeSpec {
|
|||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowWatcher::OpenWindowJS(nsIDOMWindow *aParent,
|
||||
nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
|
||||
const char *aUrl,
|
||||
const char *aName,
|
||||
const char *aFeatures,
|
||||
bool aCalledFromScript,
|
||||
bool aDialog,
|
||||
nsIArray *argv,
|
||||
bool aNavigate,
|
||||
nsISupports *aArguments,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
if (argv) {
|
||||
PRUint32 argc;
|
||||
nsresult rv = argv->GetLength(&argc);
|
||||
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);
|
||||
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
|
||||
return OpenWindowJSInternal(aParent, aUrl, aName, aFeatures,
|
||||
aCalledFromScript, aDialog,
|
||||
aNavigate, argv, _retval);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -451,9 +461,10 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
const char *aUrl,
|
||||
const char *aName,
|
||||
const char *aFeatures,
|
||||
bool aDialog,
|
||||
nsIArray *argv,
|
||||
bool aCalledFromJS,
|
||||
bool aDialog,
|
||||
bool aNavigate,
|
||||
nsIArray *argv,
|
||||
nsIDOMWindow **_retval)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -868,7 +879,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
}
|
||||
}
|
||||
|
||||
if (uriToLoad) { // get the script principal and pass it to docshell
|
||||
if (uriToLoad && aNavigate) { // get the script principal and pass it to docshell
|
||||
JSContextAutoPopper contextGuard;
|
||||
|
||||
cx = GetJSContextFromCallStack();
|
||||
|
|
|
@ -76,9 +76,10 @@ protected:
|
|||
const char *aUrl,
|
||||
const char *aName,
|
||||
const char *aFeatures,
|
||||
bool aDialog,
|
||||
nsIArray *argv,
|
||||
bool aCalledFromJS,
|
||||
bool aDialog,
|
||||
bool aNavigate,
|
||||
nsIArray *argv,
|
||||
nsIDOMWindow **_retval);
|
||||
|
||||
static JSContext *GetJSContextFromWindow(nsIDOMWindow *aWindow);
|
||||
|
|
Загрузка…
Ссылка в новой задаче