Fixing bug 194404. Adding support for window.showModalDialog() for compatibility with IE. r+sr=jonas@sicking.cc

This commit is contained in:
jst@mozilla.org 2007-07-26 10:52:26 -07:00
Родитель 9523660665
Коммит 63bd26c924
15 изменённых файлов: 452 добавлений и 35 удалений

Просмотреть файл

@ -8500,7 +8500,15 @@ nsDocShell::EnsureScriptEnvironment()
do_GetService(kDOMScriptObjectFactoryCID);
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr<nsPIDOMWindow> pw(do_GetInterface(parent));
// If the parent (chrome or not) is a modal content window, make
// this window a modal content window as well.
factory->NewScriptGlobalObject(mItemType == typeChrome,
pw && pw->IsModalContentWindow(),
getter_AddRefs(mScriptGlobal));
NS_ENSURE_TRUE(mScriptGlobal, NS_ERROR_FAILURE);

Просмотреть файл

@ -72,8 +72,8 @@ class nsPresContext;
struct nsTimeout;
#define NS_PIDOMWINDOW_IID \
{ 0xbf81c452, 0xbd39, 0x4001, \
{ 0x85, 0xf4, 0x21, 0x79, 0x36, 0xc5, 0x85, 0x7d } }
{ 0x42764ad5, 0xa196, 0x408c, \
{ 0xa4, 0x87, 0x97, 0xf4, 0xc6, 0x31, 0x57, 0x21 } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -361,6 +361,15 @@ public:
virtual void EnterModalState() = 0;
virtual void LeaveModalState() = 0;
void SetModalContentWindow(PRBool aIsModalContentWindow)
{
mIsModalContentWindow = aIsModalContentWindow;
}
PRBool IsModalContentWindow() const
{
return mIsModalContentWindow;
}
protected:
// The nsPIDOMWindow constructor. The aOuterWindow argument should
@ -371,7 +380,8 @@ protected:
: mFrameElement(nsnull), mDocShell(nsnull), mModalStateDepth(0),
mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(PR_FALSE),
mIsHandlingResizeEvent(PR_FALSE), mIsInnerWindow(aOuterWindow != nsnull),
mInnerWindow(nsnull), mOuterWindow(aOuterWindow)
mIsModalContentWindow(PR_FALSE), mInnerWindow(nsnull),
mOuterWindow(aOuterWindow)
{
}
@ -396,6 +406,10 @@ protected:
PRPackedBool mIsHandlingResizeEvent;
PRPackedBool mIsInnerWindow;
// This variable is used on both inner and outer windows (and they
// should match).
PRPackedBool mIsModalContentWindow;
// And these are the references between inner and outer windows.
nsPIDOMWindow *mInnerWindow;
nsPIDOMWindow *mOuterWindow;

Просмотреть файл

@ -57,7 +57,7 @@ SDK_XPIDLSRCS = \
XPIDLSRCS = \
nsIBrowserDOMWindow.idl \
nsIDOMClientInformation.idl \
nsIDOMClientInformation.idl \
nsIDOMConstructor.idl \
nsIDOMCRMFObject.idl \
nsIDOMCrypto.idl \
@ -74,10 +74,11 @@ XPIDLSRCS = \
nsIDOMScreen.idl \
nsIDOMWindowInternal.idl \
nsIDOMJSWindow.idl \
nsIDOMModalContentWindow.idl \
nsIDOMChromeWindow.idl \
nsIDOMNSFeatureFactory.idl \
nsIDOMTextRectangle.idl \
nsIDOMTextRectangleList.idl \
nsIDOMTextRectangle.idl \
nsIDOMTextRectangleList.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,58 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johnny Stenback <jst@mozilla.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIVariant;
interface nsIArray;
[scriptable, uuid(51aebd45-b979-4ec6-9d11-3a3fd3d5d59e)]
interface nsIDOMModalContentWindow : nsISupports
{
/**
* Readonly attribute containing an array of arguments that was
* passed to the code that opened this modal content window.
*/
readonly attribute nsIArray dialogArguments;
/**
* The return value that will be returned to the function that
* opened the modal content window.
*/
attribute nsIVariant returnValue;
};

Просмотреть файл

@ -42,8 +42,9 @@
interface nsIPrompt;
interface nsIControllers;
interface nsIDOMLocation;
interface nsIVariant;
[scriptable, uuid(f914492c-0138-4123-a634-6ef8e3f126f8)]
[scriptable, uuid(0d12a345-3fe2-491e-af0d-bcfd5c4baa03)]
interface nsIDOMWindowInternal : nsIDOMWindow2
{
readonly attribute nsIDOMWindowInternal window;
@ -195,4 +196,8 @@ interface nsIDOMWindowInternal : nsIDOMWindow2
DOMString btoa(in DOMString aBase64Data);
readonly attribute nsIDOMElement frameElement;
nsIVariant showModalDialog(in DOMString aURI,
[optional] in nsIVariant aArgs,
[optional] in DOMString aOptions);
};

Просмотреть файл

@ -411,6 +411,9 @@ enum nsDOMClassInfoID {
eDOMClassInfo_File_id,
eDOMClassInfo_FileException_id,
// DOM modal content window class, almost identical to Window
eDOMClassInfo_ModalContentWindow_id,
// This one better be the last one in this list
eDOMClassInfoIDCount
};

Просмотреть файл

@ -43,9 +43,8 @@
#include "nsStringGlue.h"
#define NS_IDOM_SCRIPT_OBJECT_FACTORY_IID \
{ /* {38EC7717-6CBE-44a8-B2BB-53F2BA998B31} */ \
0x38ec7717, 0x6cbe, 0x44a8, \
{ 0xb2, 0xbb, 0x53, 0xf2, 0xba, 0x99, 0x8b, 0x31 } }
{ 0xd5a4f935, 0xe428, 0x47ec, \
{ 0x8f, 0x36, 0x44, 0x23, 0xfa, 0xa2, 0x21, 0x90 } }
class nsIScriptContext;
class nsIScriptGlobalObject;
@ -74,6 +73,7 @@ public:
PRUint32 *aScriptTypeID) = 0;
NS_IMETHOD NewScriptGlobalObject(PRBool aIsChrome,
PRBool aIsModalContentWindow,
nsIScriptGlobalObject **aGlobal) = 0;
NS_IMETHOD_(nsISupports *) GetClassInfoInstance(nsDOMClassInfoID aID) = 0;

Просмотреть файл

@ -1214,6 +1214,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
DEFAULT_SCRIPTABLE_FLAGS |
WINDOW_SCRIPTABLE_FLAGS)
};
// Objects that shuld be constructable through |new Name();|
@ -3307,6 +3310,17 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIException)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(ModalContentWindow, nsIDOMWindow)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowInternal)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMViewCSS)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMAbstractView)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageWindow)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow)
DOM_CLASSINFO_MAP_END
#ifdef NS_DEBUG
{
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);

Просмотреть файл

@ -212,9 +212,10 @@ nsDOMScriptObjectFactory::GetIDForScriptType(const nsAString &aLanguageName,
NS_IMETHODIMP
nsDOMScriptObjectFactory::NewScriptGlobalObject(PRBool aIsChrome,
PRBool aIsModalContentWindow,
nsIScriptGlobalObject **aGlobal)
{
return NS_NewScriptGlobalObject(aIsChrome, aGlobal);
return NS_NewScriptGlobalObject(aIsChrome, aIsModalContentWindow, aGlobal);
}
NS_IMETHODIMP_(nsISupports *)

Просмотреть файл

@ -82,6 +82,7 @@ public:
PRUint32 *aLanguageID);
NS_IMETHOD NewScriptGlobalObject(PRBool aIsChrome,
PRBool aIsModalContentWindow,
nsIScriptGlobalObject **aGlobal);
NS_IMETHOD_(nsISupports *) GetClassInfoInstance(nsDOMClassInfoID aID);

Просмотреть файл

@ -260,6 +260,18 @@ PRInt32 gTimeoutCnt = 0;
} \
PR_END_MACRO
#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval) \
PR_BEGIN_MACRO \
if (IsInnerWindow()) { \
nsGlobalWindow *outer = GetOuterWindowInternal(); \
if (!outer) { \
NS_WARNING("No outer window available!"); \
return err_rval; \
} \
return ((nsGlobalModalWindow *)outer)->method args; \
} \
PR_END_MACRO
#define FORWARD_TO_INNER(method, args, err_rval) \
PR_BEGIN_MACRO \
if (IsOuterWindow()) { \
@ -271,6 +283,17 @@ PRInt32 gTimeoutCnt = 0;
} \
PR_END_MACRO
#define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval) \
PR_BEGIN_MACRO \
if (IsOuterWindow()) { \
if (!mInnerWindow) { \
NS_WARNING("No inner window available!"); \
return err_rval; \
} \
return ((nsGlobalModalWindow*)GetCurrentInnerWindowInternal())->method args; \
} \
PR_END_MACRO
#define FORWARD_TO_INNER_VOID(method, args) \
PR_BEGIN_MACRO \
if (IsOuterWindow()) { \
@ -1426,7 +1449,11 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
isChrome = PR_TRUE;
} else {
newInnerWindow = new nsGlobalWindow(this);
if (mIsModalContentWindow) {
newInnerWindow = new nsGlobalModalWindow(this);
} else {
newInnerWindow = new nsGlobalWindow(this);
}
}
mLocation = nsnull;
@ -2053,7 +2080,11 @@ nsGlobalWindow::SetNewArguments(nsIArray *aArguments)
void *glob = currentInner->GetScriptGlobal(langID);
nsIScriptContext *ctx = GetScriptContext(langID);
if (glob && ctx) {
rv = ctx->SetProperty(glob, "arguments", aArguments);
if (mIsModalContentWindow) {
rv = ctx->SetProperty(glob, "dialogArguments", aArguments);
} else {
rv = ctx->SetProperty(glob, "arguments", aArguments);
}
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -5079,6 +5110,163 @@ nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
return NS_OK;
}
void
ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult)
{
nsAString::const_iterator end;
aOptions.EndReading(end);
nsAString::const_iterator iter;
aOptions.BeginReading(iter);
while (iter != end) {
// Skip whitespace.
while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
++iter;
}
nsAString::const_iterator name_start = iter;
// Skip characters until we find whitespace, ';', ':', or '='
while (iter != end && !nsCRT::IsAsciiSpace(*iter) &&
*iter != ';' &&
*iter != ':' &&
*iter != '=') {
++iter;
}
nsAString::const_iterator name_end = iter;
// Skip whitespace.
while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
++iter;
}
if (*iter == ';') {
// No value found, skip the ';' and keep going.
++iter;
continue;
}
nsAString::const_iterator value_start = iter;
nsAString::const_iterator value_end = iter;
if (*iter == ':' || *iter == '=') {
// We found name followed by ':' or '='. Look for a value.
iter++; // Skip the ':' or '='
// Skip whitespace.
while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
++iter;
}
value_start = iter;
// Skip until we find whitespace, or ';'.
while (iter != end && !nsCRT::IsAsciiSpace(*iter) &&
*iter != ';') {
++iter;
}
value_end = iter;
// Skip whitespace.
while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
++iter;
}
}
const nsDependentSubstring& name = Substring(name_start, name_end);
const nsDependentSubstring& value = Substring(value_start, value_end);
if (name.LowerCaseEqualsLiteral("center")) {
if (value.LowerCaseEqualsLiteral("on") ||
value.LowerCaseEqualsLiteral("yes") ||
value.LowerCaseEqualsLiteral("1")) {
aResult.AppendLiteral(",centerscreen=1");
}
} else if (name.LowerCaseEqualsLiteral("dialogwidth")) {
if (!value.IsEmpty()) {
aResult.AppendLiteral(",width=");
aResult.Append(value);
}
} else if (name.LowerCaseEqualsLiteral("dialogheight")) {
if (!value.IsEmpty()) {
aResult.AppendLiteral(",height=");
aResult.Append(value);
}
} else if (name.LowerCaseEqualsLiteral("dialogtop")) {
if (!value.IsEmpty()) {
aResult.AppendLiteral(",top=");
aResult.Append(value);
}
} else if (name.LowerCaseEqualsLiteral("dialogleft")) {
if (!value.IsEmpty()) {
aResult.AppendLiteral(",left=");
aResult.Append(value);
}
} else if (name.LowerCaseEqualsLiteral("resizable")) {
if (value.LowerCaseEqualsLiteral("on") ||
value.LowerCaseEqualsLiteral("yes") ||
value.LowerCaseEqualsLiteral("1")) {
aResult.AppendLiteral(",resizable=1");
}
} else if (name.LowerCaseEqualsLiteral("scroll")) {
if (value.LowerCaseEqualsLiteral("off") ||
value.LowerCaseEqualsLiteral("no") ||
value.LowerCaseEqualsLiteral("0")) {
aResult.AppendLiteral(",scrollbars=0");
}
}
if (iter == end) {
break;
}
iter++;
}
}
NS_IMETHODIMP
nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
const nsAString& aOptions,
nsIVariant **aRetVal)
{
nsCOMPtr<nsIDOMWindow> dlgWin;
nsAutoString options(NS_LITERAL_STRING("modal=1,status=1"));
nsAutoString dialogOptions(aOptions);
ConvertDialogOptions(dialogOptions, options);
options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
nsresult rv = OpenInternal(aURI, EmptyString(), options,
PR_FALSE, // aDialog
PR_TRUE, // aCalledNoScript
PR_FALSE, // aDoJSFixups
nsnull, aArgs, // args
GetPrincipal(), // aCalleePrincipal
nsnull, // aJSCallerContext
getter_AddRefs(dlgWin));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(dlgWin));
nsPIDOMWindow *inner = win->GetCurrentInnerWindow();
nsCOMPtr<nsIDOMModalContentWindow> dlgInner(do_QueryInterface(inner));
if (dlgInner) {
dlgInner->GetReturnValue(aRetVal);
}
return NS_OK;
}
NS_IMETHODIMP
nsGlobalWindow::UpdateCommands(const nsAString& anAction)
{
@ -7651,6 +7839,8 @@ nsGlobalWindow::SetScriptTypeID(PRUint32 aScriptType)
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsGlobalChromeWindow implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
nsGlobalWindow)
@ -7666,8 +7856,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
NS_IMPL_ADDREF_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
NS_IMPL_RELEASE_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
// nsGlobalChromeWindow implementation
static void TitleConsoleWarning()
{
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
@ -7906,12 +8094,68 @@ nsGlobalChromeWindow::SetBrowserDOMWindow(nsIBrowserDOMWindow *aBrowserWindow)
return NS_OK;
}
// nsGlobalModalWindow implementation
// QueryInterface implementation for nsGlobalModalWindow
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalModalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalModalWindow,
nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArguments)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalModalWindow)
NS_INTERFACE_MAP_ENTRY(nsIDOMModalContentWindow)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ModalContentWindow)
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalModalWindow,
nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReturnValue)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMETHODIMP
nsGlobalModalWindow::GetDialogArguments(nsIArray **aArguments)
{
FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(GetDialogArguments, (aArguments),
NS_ERROR_NOT_INITIALIZED);
*aArguments = mArguments;
return NS_OK;
}
NS_IMETHODIMP
nsGlobalModalWindow::GetReturnValue(nsIVariant **aRetVal)
{
FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(GetReturnValue, (aRetVal), NS_OK);
NS_IF_ADDREF(*aRetVal = mReturnValue);
return NS_OK;
}
NS_IMETHODIMP
nsGlobalModalWindow::SetReturnValue(nsIVariant *aRetVal)
{
FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(SetReturnValue, (aRetVal), NS_OK);
mReturnValue = aRetVal;
return NS_OK;
}
//*****************************************************************************
// nsGlobalWindow: Creator Function (This should go away)
//*****************************************************************************
nsresult
NS_NewScriptGlobalObject(PRBool aIsChrome, nsIScriptGlobalObject **aResult)
NS_NewScriptGlobalObject(PRBool aIsChrome, PRBool aIsModalContentWindow,
nsIScriptGlobalObject **aResult)
{
*aResult = nsnull;
@ -7919,14 +8163,17 @@ NS_NewScriptGlobalObject(PRBool aIsChrome, nsIScriptGlobalObject **aResult)
if (aIsChrome) {
global = new nsGlobalChromeWindow(nsnull);
} else if (aIsModalContentWindow) {
global = new nsGlobalModalWindow(nsnull);
} else {
global = new nsGlobalWindow(nsnull);
}
NS_ENSURE_TRUE(global, NS_ERROR_OUT_OF_MEMORY);
return CallQueryInterface(static_cast<nsIScriptGlobalObject *>(global),
aResult);
NS_ADDREF(*aResult = global);
return NS_OK;
}
//*****************************************************************************

Просмотреть файл

@ -78,6 +78,7 @@
#include "nsITimer.h"
#include "nsIWebBrowserChrome.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMModalContentWindow.h"
#include "nsIScriptSecurityManager.h"
#include "nsIEventListenerManager.h"
#include "nsIDOMDocument.h"
@ -96,6 +97,7 @@
#include "nsIDOMStorageWindow.h"
#include "nsIDOMOfflineResourceList.h"
#include "nsPIDOMEventTarget.h"
#include "nsIArray.h"
#define DEFAULT_HOME_PAGE "www.mozilla.org"
#define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
@ -106,7 +108,6 @@ class nsIContent;
class nsPresContext;
class nsIDOMEvent;
class nsIScrollableView;
class nsIArray;
class nsBarProp;
class nsLocation;
@ -729,6 +730,31 @@ protected:
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
};
/*
* nsGlobalModalWindow inherits from nsGlobalWindow. It is the global
* object created for a modal content windows only (i.e. not modal
* chrome dialogs).
*/
class nsGlobalModalWindow : public nsGlobalWindow,
public nsIDOMModalContentWindow
{
public:
nsGlobalModalWindow(nsGlobalWindow *aOuterWindow)
: nsGlobalWindow(aOuterWindow)
{
mIsModalContentWindow = PR_TRUE;
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMMODALCONTENTWINDOW
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
protected:
nsCOMPtr<nsIVariant> mReturnValue;
};
//*****************************************************************************
// nsNavigator: Script "navigator" object
//*****************************************************************************
@ -812,7 +838,8 @@ protected:
};
/* factory function */
nsresult NS_NewScriptGlobalObject(PRBool aIsChrome,
nsIScriptGlobalObject **aResult);
nsresult
NS_NewScriptGlobalObject(PRBool aIsChrome, PRBool aIsModalContentWindow,
nsIScriptGlobalObject **aResult);
#endif /* nsGlobalWindow_h___ */

Просмотреть файл

@ -2364,18 +2364,32 @@ nsJSContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aArg
void *mark;
JSAutoRequest ar(mContext);
nsresult rv;
rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc,
reinterpret_cast<void **>(&argv), &mark);
NS_ENSURE_SUCCESS(rv, rv);
AutoFreeJSStack stackGuard(mContext, mark); // ensure always freed.
// got the array, now attach it.
JSObject *args = ::JS_NewArrayObject(mContext, argc, argv);
jsval vargs = OBJECT_TO_JSVAL(args);
jsval vargs;
rv = ::JS_SetProperty(mContext, reinterpret_cast<JSObject *>(aTarget), aPropName, &vargs) ?
// got the arguments, now attach them.
// window.dialogArguments is supposed to be an array if a JS array
// was passed to showModalDialog(), deal with that here.
if (strcmp(aPropName, "dialogArguments") == 0 && argc == 1 &&
JSVAL_IS_OBJECT(argv[0]) &&
::JS_IsArrayObject(mContext, JSVAL_TO_OBJECT(argv[0]))) {
vargs = argv[0];
} else {
JSObject *args = ::JS_NewArrayObject(mContext, argc, argv);
vargs = OBJECT_TO_JSVAL(args);
}
// Make sure to use JS_DefineProperty here so that we can override
// readonly XPConnect properties here as well (read dialogArguments).
rv = ::JS_DefineProperty(mContext, reinterpret_cast<JSObject *>(aTarget),
aPropName, vargs, nsnull, nsnull, 0) ?
NS_OK : NS_ERROR_FAILURE;
// free 'args'???
@ -2446,7 +2460,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
// as we have code for handling all, we may as well use it.
rv = AddSupportsPrimitiveTojsvals(arg, thisval);
if (rv == NS_ERROR_NO_INTERFACE) {
// something else - probably an event object or similar - just
// something else - probably an event object or similar -
// just wrap it.
#ifdef NS_DEBUG
// but first, check its not another nsISupportsPrimitive, as

Просмотреть файл

@ -499,7 +499,8 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
windowIsNew = PR_FALSE,
windowNeedsName = PR_FALSE,
windowIsModal = PR_FALSE,
uriToLoadIsChrome = PR_FALSE;
uriToLoadIsChrome = PR_FALSE,
windowIsModalContentDialog = PR_FALSE;
PRUint32 chromeFlags;
nsAutoString name; // string version of aName
nsCAutoString features; // string version of aFeatures
@ -545,6 +546,14 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
nsCOMPtr<nsIDOMChromeWindow> chromeParent(do_QueryInterface(aParent));
// If we're not called through our JS version of the API, and we got
// a modal option, treat the window we're opening as a modal content
// window.
if (!aCalledFromJS && argv &&
WinHasOption(features.get(), "modal", 0, nsnull)) {
windowIsModalContentDialog = PR_TRUE;
}
// Make sure we call CalculateChromeFlags() *before* we push the
// callee context onto the context stack so that
// CalculateChromeFlags() sees the actual caller when doing it's
@ -719,7 +728,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
}
}
if (aDialog && argv) {
if ((aDialog || windowIsModalContentDialog) && argv) {
// Set the args on the new object.
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_QueryInterface(*_retval));
NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_UNEXPECTED);
@ -899,7 +908,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
if (isNewToplevelWindow)
SizeOpenedDocShellItem(newDocShellItem, aParent, sizeSpec);
if (windowIsModal) {
if (windowIsModal || windowIsModalContentDialog) {
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
@ -1358,6 +1367,7 @@ void nsWindowWatcher::CheckWindowName(nsString& aName)
* @param aDialog affects the assumptions made about unnamed features
* @return the chrome bitmask
*/
// static
PRUint32 nsWindowWatcher::CalculateChromeFlags(const char *aFeatures,
PRBool aFeaturesSpecified,
PRBool aDialog,
@ -1366,9 +1376,9 @@ PRUint32 nsWindowWatcher::CalculateChromeFlags(const char *aFeatures,
{
if(!aFeaturesSpecified || !aFeatures) {
if(aDialog)
return nsIWebBrowserChrome::CHROME_ALL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
return nsIWebBrowserChrome::CHROME_ALL |
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
else
return nsIWebBrowserChrome::CHROME_ALL;
}
@ -1504,7 +1514,7 @@ PRUint32 nsWindowWatcher::CalculateChromeFlags(const char *aFeatures,
prevents untrusted script from opening modal windows in general
while still allowing alerts and the like. */
if (!aChromeURL)
chromeFlags &= ~(nsIWebBrowserChrome::CHROME_MODAL | nsIWebBrowserChrome::CHROME_OPENAS_CHROME);
chromeFlags &= ~nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
}
if (!(chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
@ -1515,6 +1525,7 @@ PRUint32 nsWindowWatcher::CalculateChromeFlags(const char *aFeatures,
return chromeFlags;
}
// static
PRInt32
nsWindowWatcher::WinHasOption(const char *aOptions, const char *aName,
PRInt32 aDefault, PRBool *aPresenceFlag)
@ -1735,6 +1746,7 @@ nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem *aOpenedItem,
return rv;
}
// static
void
nsWindowWatcher::CalcSizeSpec(const char* aFeatures, SizeSpec& aResult)
{

Просмотреть файл

@ -65,7 +65,7 @@
#include "nsIPrivateDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMXULElement.h"
#include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMScreen.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsIEmbeddingSiteWindow2.h"
@ -1798,6 +1798,18 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(PRInt32 aChromeFlags,
(static_cast<nsIXULWindow*>
(newWindow));
nsCOMPtr<nsIDocShell> newDocShell;
xulWin->GetDocShell(getter_AddRefs(newDocShell));
// If we're opening a non-chrome modal window (i.e. a modal content
// window), tell the DOM window that it is modal.
nsCOMPtr<nsPIDOMWindow> domWin(do_GetInterface(newDocShell));
if (domWin && (aChromeFlags & nsIWebBrowserChrome::CHROME_MODAL) &&
!(aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
domWin->SetModalContentWindow(PR_TRUE);
}
xulWin->LockUntilChromeLoad();
// Push nsnull onto the JSContext stack before we dispatch a native event.