mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
moving window opening code to WindowWatcher component. bug 67368 r=hyatt,jst
This commit is contained in:
parent
f5437ab8bf
commit
48ff9b0878
@ -2940,48 +2940,34 @@ NS_IMETHODIMP GlobalWindowImpl::OpenInternal(JSContext *cx,
|
||||
PRBool aDialog,
|
||||
nsIDOMWindowInternal ** aReturn)
|
||||
{
|
||||
#if 0
|
||||
/* The other version of this method will soon be replaced by this one,
|
||||
after the new supporting code has had time to settle in.
|
||||
Note to self: also remove AttachArguments, CalculateChromeFlags,
|
||||
SizeOpenedDocShellItem, ReadyOpenedDocShellItem, CheckWindowName,
|
||||
WinHasOption
|
||||
*/
|
||||
JSString *jsName,
|
||||
*jsUrl,
|
||||
*jsFeatures;
|
||||
const PRUnichar *name,
|
||||
*url,
|
||||
*features;
|
||||
const PRUnichar *name = nsnull,
|
||||
*url = nsnull,
|
||||
*features = nsnull;
|
||||
nsresult rv;
|
||||
PRUint32 extraArgc;
|
||||
nsCOMPtr<nsIDOMWindow> domReturn;
|
||||
|
||||
*aReturn = nsnull;
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
name = nsnull;
|
||||
url = nsnull;
|
||||
features = nsnull;
|
||||
if (argc > 0) {
|
||||
jsUrl = ::JS_ValueToString(cx, argv[0]);
|
||||
if (jsUrl)
|
||||
url = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(jsUrl));
|
||||
JSString *str = ::JS_ValueToString(cx, argv[0]);
|
||||
if (str)
|
||||
url = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(str));
|
||||
}
|
||||
if (argc > 1) {
|
||||
jsName = ::JS_ValueToString(cx, argv[1]);
|
||||
if (jsName)
|
||||
name = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(jsName));
|
||||
JSString *str = ::JS_ValueToString(cx, argv[1]);
|
||||
if (str)
|
||||
name = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(str));
|
||||
}
|
||||
if (argc > 2) {
|
||||
jsFeatures = ::JS_ValueToString(cx, argv[2]);
|
||||
if (jsFeatures)
|
||||
features = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(jsFeatures));
|
||||
JSString *str = ::JS_ValueToString(cx, argv[2]);
|
||||
if (str)
|
||||
features = NS_REINTERPRET_CAST(const PRUnichar *, ::JS_GetStringChars(str));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIWindowWatcher> wwatch(do_GetService(sWindowWatcherContractID));
|
||||
if (wwatch) {
|
||||
extraArgc = argc >= 3 ? argc-3 : 0;
|
||||
PRUint32 extraArgc = argc >= 3 ? argc-3 : 0;
|
||||
rv = wwatch->OpenWindowJS(this, url, name, features, aDialog,
|
||||
extraArgc, argv+3,
|
||||
getter_AddRefs(domReturn));
|
||||
@ -2989,689 +2975,6 @@ NS_IMETHODIMP GlobalWindowImpl::OpenInternal(JSContext *cx,
|
||||
CallQueryInterface(domReturn, aReturn);
|
||||
}
|
||||
return rv;
|
||||
#else
|
||||
PRUint32 chromeFlags;
|
||||
nsAutoString name;
|
||||
char *options;
|
||||
PRBool nameSpecified = PR_FALSE;
|
||||
nsCOMPtr<nsIURI> uriToLoad;
|
||||
|
||||
*aReturn = nsnull;
|
||||
|
||||
if (argc > 0) {
|
||||
JSString *jsStrURL = ::JS_ValueToString(cx, argv[0]);
|
||||
NS_ENSURE_TRUE(jsStrURL, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString unescapedURL;
|
||||
unescapedURL.Assign(NS_REINTERPRET_CAST(const PRUnichar *,
|
||||
::JS_GetStringChars(jsStrURL)));
|
||||
|
||||
// fix bug 35076
|
||||
// if the URL contains non ASCII, then escape from the first non ASCII char
|
||||
nsAutoString mURL;
|
||||
if (unescapedURL.IsASCII()) {
|
||||
mURL = unescapedURL;
|
||||
}
|
||||
else {
|
||||
const PRUnichar *pt = unescapedURL.GetUnicode();
|
||||
PRUint32 len = unescapedURL.Length();
|
||||
PRUint32 i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (0 != (0xFF80 & (*pt++)))
|
||||
break;
|
||||
}
|
||||
nsAutoString right, right2;
|
||||
unescapedURL.Left(mURL, i);
|
||||
unescapedURL.Right(right, len - i);
|
||||
if (NS_SUCCEEDED(Escape(right, right2)))
|
||||
mURL.Append(right2);
|
||||
else
|
||||
mURL = unescapedURL;
|
||||
}
|
||||
if (!mURL.IsEmpty()) {
|
||||
nsAutoString mAbsURL;
|
||||
if (mDocument) {
|
||||
// Build absolute URL relative to this document.
|
||||
nsCOMPtr<nsIURI> docURL;
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
|
||||
if (doc)
|
||||
docURL = dont_AddRef(doc->GetDocumentURL());
|
||||
|
||||
nsCOMPtr<nsIURI> baseUri(do_QueryInterface(docURL));
|
||||
NS_ENSURE_TRUE(baseUri, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ENSURE_SUCCESS(NS_MakeAbsoluteURI(mAbsURL, mURL, baseUri),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
// No document. Probably because this window's URL hasn't finished
|
||||
// loading. All we can do is hope the URL we've been given is absolute.
|
||||
mAbsURL.Assign(NS_REINTERPRET_CAST(const PRUnichar *,
|
||||
::JS_GetStringChars(jsStrURL)));
|
||||
// Make URI; if mAbsURL is relative (or otherwise bogus) this will fail.
|
||||
}
|
||||
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(uriToLoad), mAbsURL),
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity-check the optional window_name argument. */
|
||||
if (argc > 1) {
|
||||
JSString *jsStrName = ::JS_ValueToString(cx, argv[1]);
|
||||
NS_ENSURE_TRUE(jsStrName, NS_ERROR_FAILURE);
|
||||
|
||||
name.Assign(NS_REINTERPRET_CAST(const PRUnichar *,
|
||||
::JS_GetStringChars(jsStrName)));
|
||||
nameSpecified = PR_TRUE;
|
||||
|
||||
// Check for an illegal name e.g. frame3.1
|
||||
// This prints a warning message and returns NS_ERROR_FAILURE.
|
||||
// Don't use NS_ENSURE_SUCCESS - go ahead and open up the window
|
||||
// even if the name contains an illegal character. See bug 32898.
|
||||
CheckWindowName(cx, name);
|
||||
}
|
||||
|
||||
options = nsnull;
|
||||
if (argc > 2) {
|
||||
JSString *str;
|
||||
NS_ENSURE_TRUE((str = ::JS_ValueToString(cx, argv[2])), NS_ERROR_FAILURE);
|
||||
options = ::JS_GetStringBytes(str);
|
||||
}
|
||||
chromeFlags = CalculateChromeFlags(options, aDialog);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> newDocShellItem;
|
||||
|
||||
// special handling for certain targets
|
||||
if (nameSpecified) {
|
||||
/* Oh good. special target names are now handled in multiple places:
|
||||
Here and within FindItemWithName, just below. I put _top here because
|
||||
here it's able to do what it should: get the topmost shell of the same
|
||||
(content/chrome) type as the docshell. treeOwner is always chrome, so
|
||||
this scheme doesn't work there, where a lot of other special case
|
||||
targets are handled. (treeOwner is, however, a good place to look
|
||||
for browser windows by name, as it does.)
|
||||
*/
|
||||
if (name.EqualsIgnoreCase("_top")) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> shelltree(do_QueryInterface(mDocShell));
|
||||
if (shelltree)
|
||||
shelltree->GetSameTypeRootTreeItem(getter_AddRefs(newDocShellItem));
|
||||
}
|
||||
else
|
||||
treeOwner->FindItemWithName(name.GetUnicode(), nsnull,
|
||||
getter_AddRefs(newDocShellItem));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventQueue> modalEventQueue; // This has an odd ownership model
|
||||
nsCOMPtr<nsIEventQueueService> eventQService;
|
||||
|
||||
PRBool windowIsNew = PR_FALSE;
|
||||
PRBool windowIsModal = PR_FALSE;
|
||||
|
||||
if (!newDocShellItem) {
|
||||
windowIsNew = PR_TRUE;
|
||||
PRBool weAreModal = PR_FALSE;
|
||||
treeOwner->IsModal(&weAreModal);
|
||||
if (weAreModal || (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL)) {
|
||||
eventQService = do_GetService(kEventQueueServiceCID);
|
||||
if (eventQService &&
|
||||
NS_SUCCEEDED(eventQService->
|
||||
PushThreadEventQueue(getter_AddRefs(modalEventQueue))))
|
||||
windowIsModal = PR_TRUE;
|
||||
// in case we added this because weAreModal
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_MODAL | nsIWebBrowserChrome::CHROME_DEPENDENT;
|
||||
}
|
||||
treeOwner->GetNewWindow(chromeFlags, getter_AddRefs(newDocShellItem));
|
||||
NS_ENSURE_TRUE(newDocShellItem, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(ReadyOpenedDocShellItem(newDocShellItem, aReturn),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
if (windowIsNew) {
|
||||
PRBool present = PR_FALSE;
|
||||
PRInt32 temp;
|
||||
|
||||
if (!((temp = WinHasOption(options, "outerWidth", 0, &present)) ||
|
||||
present) &&
|
||||
!((temp = WinHasOption(options, "outerHeight", 0, &present)) ||
|
||||
present))
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
|
||||
newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
|
||||
NS_ENSURE_TRUE(newTreeOwner, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIWebBrowserChrome> newChrome = do_GetInterface(newTreeOwner);
|
||||
if (newChrome)
|
||||
newChrome->SetPersistence(PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (aDialog && argc > 3)
|
||||
AttachArguments(*aReturn, argv + 3, argc - 3);
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan;
|
||||
if (uriToLoad) {
|
||||
// Get security manager, check to see if URI is allowed.
|
||||
// Don't call CheckLoadURI for dialogs - see bug 56851
|
||||
// The security of this function depends on window.openDialog being
|
||||
// inaccessible from web scripts
|
||||
nsCOMPtr<nsIURI> newUrl;
|
||||
nsCOMPtr<nsIScriptContext> scriptCX;
|
||||
nsJSUtils::nsGetStaticScriptContext(cx, (JSObject *) mScriptObject,
|
||||
getter_AddRefs(scriptCX));
|
||||
if (!scriptCX ||
|
||||
NS_FAILED(scriptCX->GetSecurityManager(getter_AddRefs(secMan))) ||
|
||||
((!aDialog && NS_FAILED(secMan->CheckLoadURIFromScript(cx, uriToLoad)))))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
newDocShellItem->SetName(nameSpecified ? name.GetUnicode() : nsnull);
|
||||
|
||||
nsCOMPtr<nsIDocShell> newDocShell(do_QueryInterface(newDocShellItem));
|
||||
if (uriToLoad) { // Get script principal and pass to docshell
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
||||
newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
|
||||
|
||||
if (principal) {
|
||||
nsCOMPtr<nsISupports> owner(do_QueryInterface(principal));
|
||||
loadInfo->SetOwner(owner);
|
||||
}
|
||||
|
||||
// Get the calling context off the JS context stack
|
||||
nsCOMPtr<nsIJSContextStack> stack =
|
||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
|
||||
JSContext* ccx = nsnull;
|
||||
|
||||
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
|
||||
JSObject *global = ::JS_GetGlobalObject(ccx);
|
||||
|
||||
if (global) {
|
||||
JSClass* jsclass = ::JS_GetClass(ccx, global);
|
||||
|
||||
// Check if the global object on the calling context has
|
||||
// nsISupports * private data
|
||||
if (jsclass &&
|
||||
!((~jsclass->flags) & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
|
||||
nsISupports* sup = (nsISupports *)::JS_GetPrivate(ccx, global);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> w(do_QueryInterface(sup));
|
||||
|
||||
if (w) {
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
|
||||
// Get the document from the window.
|
||||
w->GetDocument(getter_AddRefs(document));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
|
||||
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIURI> uri(dont_AddRef(doc->GetDocumentURL()));
|
||||
|
||||
// Set the referrer
|
||||
loadInfo->SetReferrer(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDocShell->LoadURI(uriToLoad, loadInfo,
|
||||
nsIWebNavigation::LOAD_FLAGS_NONE);
|
||||
}
|
||||
|
||||
if (windowIsNew)
|
||||
SizeOpenedDocShellItem(newDocShellItem, options, chromeFlags);
|
||||
if (windowIsModal) {
|
||||
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
|
||||
newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
|
||||
|
||||
if (newTreeOwner)
|
||||
newTreeOwner->ShowModal();
|
||||
|
||||
eventQService->PopThreadEventQueue(modalEventQueue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// attach the given array of JS values to the given window, as a property array
|
||||
// named "arguments"
|
||||
NS_IMETHODIMP GlobalWindowImpl::AttachArguments(nsIDOMWindowInternal *aWindow,
|
||||
jsval *argv, PRUint32 argc)
|
||||
{
|
||||
if (argc == 0)
|
||||
return NS_OK;
|
||||
|
||||
// copy the extra parameters into a JS Array and attach it
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_QueryInterface(aWindow));
|
||||
if (!scriptGlobal)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||
scriptGlobal->GetContext(getter_AddRefs(scriptContext));
|
||||
if (!scriptContext)
|
||||
return NS_OK;
|
||||
|
||||
JSContext *jsContext;
|
||||
jsContext = (JSContext *) scriptContext->GetNativeContext();
|
||||
nsCOMPtr<nsIScriptObjectOwner> owner(do_QueryInterface(aWindow));
|
||||
if (!owner)
|
||||
return NS_OK;
|
||||
|
||||
JSObject *scriptObject;
|
||||
owner->GetScriptObject(scriptContext, (void **) &scriptObject);
|
||||
|
||||
JSObject *args;
|
||||
args = ::JS_NewArrayObject(jsContext, argc, argv);
|
||||
if (!args)
|
||||
return NS_OK;
|
||||
|
||||
jsval argsVal = OBJECT_TO_JSVAL(args);
|
||||
// ::JS_DefineProperty(jsContext, scriptObject, "arguments",
|
||||
// argsVal, NULL, NULL, JSPROP_PERMANENT);
|
||||
::JS_SetProperty(jsContext, scriptObject, "arguments", &argsVal);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the chrome bitmask from a string list of features.
|
||||
* @param aFeatures a string containing a list of named chrome features
|
||||
* @param aDialog affects the assumptions made about unnamed features
|
||||
* @return the chrome bitmask
|
||||
*/
|
||||
PRUint32 GlobalWindowImpl::CalculateChromeFlags(char *aFeatures, PRBool aDialog)
|
||||
{
|
||||
if(!aFeatures) {
|
||||
if(aDialog)
|
||||
return nsIWebBrowserChrome::CHROME_ALL |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
|
||||
else
|
||||
return nsIWebBrowserChrome::CHROME_ALL;
|
||||
}
|
||||
|
||||
/* This function has become complicated since browser windows and
|
||||
dialogs diverged. The difference is, browser windows assume all
|
||||
chrome not explicitly mentioned is off, if the features string
|
||||
is not null. Exceptions are some OS border chrome new with Mozilla.
|
||||
Dialogs interpret a (mostly) empty features string to mean
|
||||
"OS's choice," and also support an "all" flag explicitly disallowed
|
||||
in the standards-compliant window.(normal)open. */
|
||||
|
||||
PRUint32 chromeFlags = 0;
|
||||
PRBool presenceFlag = PR_FALSE;
|
||||
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_WINDOW_BORDERS;
|
||||
if (aDialog && WinHasOption(aFeatures, "all", 0, &presenceFlag))
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_ALL;
|
||||
|
||||
/* Next, allow explicitly named options to override the initial settings */
|
||||
|
||||
chromeFlags |= WinHasOption(aFeatures, "titlebar", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_TITLEBAR : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "close", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_WINDOW_CLOSE : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "toolbar", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_TOOLBAR : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "location", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_LOCATIONBAR : 0;
|
||||
chromeFlags |= (WinHasOption(aFeatures, "directories", 0, &presenceFlag) ||
|
||||
WinHasOption(aFeatures, "personalbar", 0, &presenceFlag))
|
||||
? nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "status", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_STATUSBAR : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "menubar", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_MENUBAR : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "scrollbars", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_SCROLLBARS : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "resizable", 0, &presenceFlag)
|
||||
? nsIWebBrowserChrome::CHROME_WINDOW_RESIZE : 0;
|
||||
|
||||
/* OK.
|
||||
Normal browser windows, in spite of a stated pattern of turning off
|
||||
all chrome not mentioned explicitly, will want the new OS chrome (window
|
||||
borders, titlebars, closebox) on, unless explicitly turned off.
|
||||
Dialogs, on the other hand, take the absence of any explicit settings
|
||||
to mean "OS' choice." */
|
||||
|
||||
// default titlebar and closebox to "on," if not mentioned at all
|
||||
if (!PL_strcasestr(aFeatures, "titlebar"))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
|
||||
if (!PL_strcasestr(aFeatures, "close"))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_CLOSE;
|
||||
|
||||
if (aDialog && !presenceFlag)
|
||||
chromeFlags = nsIWebBrowserChrome::CHROME_DEFAULT;
|
||||
|
||||
/* Finally, once all the above normal chrome has been divined, deal
|
||||
with the features that are more operating hints than appearance
|
||||
instructions. (Note modality implies dependence.) */
|
||||
|
||||
if (WinHasOption(aFeatures, "alwaysLowered", 0, nsnull) ||
|
||||
WinHasOption(aFeatures, "z-lock", 0, nsnull))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_LOWERED;
|
||||
else if (WinHasOption(aFeatures, "alwaysRaised", 0, nsnull))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_RAISED;
|
||||
|
||||
chromeFlags |= WinHasOption(aFeatures, "chrome", 0, nsnull) ?
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "centerscreen", 0, nsnull) ?
|
||||
nsIWebBrowserChrome::CHROME_CENTER_SCREEN : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "dependent", 0, nsnull) ?
|
||||
nsIWebBrowserChrome::CHROME_DEPENDENT : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "modal", 0, nsnull) ?
|
||||
(nsIWebBrowserChrome::CHROME_MODAL | nsIWebBrowserChrome::CHROME_DEPENDENT) : 0;
|
||||
chromeFlags |= WinHasOption(aFeatures, "dialog", 0, nsnull) ?
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG : 0;
|
||||
|
||||
/* and dialogs need to have the last word. assume dialogs are dialogs,
|
||||
and opened as chrome, unless explicitly told otherwise. */
|
||||
if (aDialog) {
|
||||
if (!PL_strcasestr(aFeatures, "dialog"))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_DIALOG;
|
||||
if (!PL_strcasestr(aFeatures, "chrome"))
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
|
||||
}
|
||||
|
||||
/* missing
|
||||
chromeFlags->copy_history
|
||||
*/
|
||||
|
||||
/* Allow disabling of commands only if there is no menubar */
|
||||
/*if(!chromeFlags & NS_CHROME_MENU_BAR_ON) {
|
||||
chromeFlags->disable_commands = !WinHasOption(aFeatures, "hotkeys");
|
||||
if(XP_STRCASESTR(aFeatures,"hotkeys")==NULL)
|
||||
chromeFlags->disable_commands = FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
//Check security state for use in determing window dimensions
|
||||
nsCOMPtr<nsIScriptSecurityManager>
|
||||
securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
|
||||
NS_ENSURE_TRUE(securityManager, NS_ERROR_FAILURE);
|
||||
|
||||
PRBool enabled;
|
||||
nsresult res =
|
||||
securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
|
||||
|
||||
res = securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
|
||||
|
||||
if (NS_FAILED(res) || !enabled) {
|
||||
//If priv check fails, set all elements to minimum reqs., else leave them alone.
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
|
||||
chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_LOWERED;
|
||||
chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_RAISED;
|
||||
//XXX Temporarily removing this check to allow modal dialogs to be
|
||||
//raised from script. A more complete security based fix is needed.
|
||||
//chromeFlags &= ~nsIWebBrowserChrome::CHROME_MODAL;
|
||||
}
|
||||
|
||||
return chromeFlags;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GlobalWindowImpl::SizeOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
|
||||
char *aFeatures,
|
||||
PRUint32 aChromeFlags)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocShellItem);
|
||||
|
||||
// Use the current window's sizes as our default
|
||||
PRInt32 chromeX = 0, chromeY = 0, chromeCX = 0, chromeCY = 0;
|
||||
PRInt32 contentCX = 0, contentCY = 0;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> currentTreeOwnerAsWin;
|
||||
GetTreeOwner(getter_AddRefs(currentTreeOwnerAsWin));
|
||||
NS_ENSURE_TRUE(currentTreeOwnerAsWin, NS_ERROR_FAILURE);
|
||||
|
||||
currentTreeOwnerAsWin->GetPositionAndSize(&chromeX, &chromeY, &chromeCX,
|
||||
&chromeCY);
|
||||
|
||||
// if we are content, we may need the content sizes
|
||||
nsCOMPtr<nsIBaseWindow> currentDocShellAsWin(do_QueryInterface(mDocShell));
|
||||
currentDocShellAsWin->GetSize(&contentCX, &contentCY);
|
||||
|
||||
PRBool present = PR_FALSE;
|
||||
PRBool positionSpecified = PR_FALSE;
|
||||
PRInt32 temp;
|
||||
|
||||
if ((temp = WinHasOption(aFeatures, "left", 0, &present)) || present)
|
||||
chromeX = temp;
|
||||
else if ((temp = WinHasOption(aFeatures, "screenX", 0, &present)) || present)
|
||||
chromeX = temp;
|
||||
|
||||
if (present)
|
||||
positionSpecified = PR_TRUE;
|
||||
|
||||
present = PR_FALSE;
|
||||
|
||||
if ((temp = WinHasOption(aFeatures, "top", 0, &present)) || present)
|
||||
chromeY = temp;
|
||||
else if ((temp = WinHasOption(aFeatures, "screenY", 0, &present)) || present)
|
||||
chromeY = temp;
|
||||
|
||||
if (present)
|
||||
positionSpecified = PR_TRUE;
|
||||
|
||||
present = PR_FALSE;
|
||||
|
||||
PRBool sizeChrome = PR_FALSE;
|
||||
PRBool sizeSpecified = PR_FALSE;
|
||||
|
||||
if ((temp = WinHasOption(aFeatures, "outerWidth", chromeCX, &present)) ||
|
||||
present) {
|
||||
chromeCX = temp;
|
||||
sizeChrome = PR_TRUE;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
|
||||
present = PR_FALSE;
|
||||
|
||||
if ((temp = WinHasOption(aFeatures, "outerHeight", chromeCY, &present)) ||
|
||||
present) {
|
||||
chromeCY = temp;
|
||||
sizeChrome = PR_TRUE;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
|
||||
// We haven't switched to chrome sizing so we need to get the content area
|
||||
if (!sizeChrome) {
|
||||
if ((temp = WinHasOption(aFeatures, "width", chromeCX, &present)) ||
|
||||
present) {
|
||||
contentCX = temp;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
else if ((temp = WinHasOption(aFeatures, "innerWidth", chromeCX, &present))
|
||||
|| present) {
|
||||
contentCX = temp;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
|
||||
if ((temp = WinHasOption(aFeatures, "height", chromeCY, &present)) ||
|
||||
present) {
|
||||
contentCY = temp;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
else if ((temp = WinHasOption(aFeatures, "innerHeight", chromeCY, &present))
|
||||
|| present) {
|
||||
contentCY = temp;
|
||||
sizeSpecified = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
PRBool enabled;
|
||||
PRInt32 screenWidth = 0, screenHeight = 0;
|
||||
PRInt32 winWidth, winHeight;
|
||||
|
||||
// Check security state for use in determing window dimensions
|
||||
nsCOMPtr<nsIScriptSecurityManager>
|
||||
securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
|
||||
NS_ENSURE_TRUE(securityManager, NS_ERROR_FAILURE);
|
||||
|
||||
res = securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);
|
||||
if (NS_FAILED(res)) {
|
||||
enabled = PR_FALSE;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
// Security check failed. Ensure all args meet minimum reqs.
|
||||
if (sizeSpecified) {
|
||||
if (sizeChrome) {
|
||||
chromeCX = chromeCX < 100 ? 100 : chromeCX;
|
||||
chromeCY = chromeCY < 100 ? 100 : chromeCY;
|
||||
}
|
||||
else {
|
||||
contentCX = contentCX < 100 ? 100 : contentCX;
|
||||
contentCY = contentCY < 100 ? 100 : contentCY;
|
||||
}
|
||||
}
|
||||
|
||||
if (positionSpecified) {
|
||||
// We'll also need the screen dimensions
|
||||
// XXX This should use nsIScreenManager once its fully fleshed out.
|
||||
nsCOMPtr<nsIDOMScreen> screen;
|
||||
if (NS_SUCCEEDED(GetScreen(getter_AddRefs(screen)))) {
|
||||
screen->GetAvailWidth(&screenWidth);
|
||||
screen->GetAvailHeight(&screenHeight);
|
||||
}
|
||||
|
||||
// This isn't strictly true but close enough
|
||||
winWidth = sizeSpecified ? (sizeChrome ? chromeCX : contentCX) : 100;
|
||||
winHeight = sizeSpecified ? (sizeChrome ? chromeCY : contentCY) : 100;
|
||||
|
||||
chromeX =
|
||||
screenWidth < chromeX + winWidth ? screenWidth - winWidth : chromeX;
|
||||
chromeX = chromeX < 0 ? 0 : chromeX;
|
||||
chromeY = screenHeight < chromeY + winHeight
|
||||
? screenHeight - winHeight
|
||||
: chromeY;
|
||||
chromeY = chromeY < 0 ? 0 : chromeY;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
aDocShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(treeOwner));
|
||||
NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
|
||||
|
||||
if (sizeChrome) {
|
||||
if (positionSpecified && sizeSpecified)
|
||||
treeOwnerAsWin->SetPositionAndSize(chromeX, chromeY, chromeCX,
|
||||
chromeCY, PR_FALSE);
|
||||
else {
|
||||
if (sizeSpecified)
|
||||
treeOwnerAsWin->SetSize(chromeCX, chromeCY, PR_FALSE);
|
||||
if (positionSpecified)
|
||||
treeOwnerAsWin->SetPosition(chromeX, chromeY);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (positionSpecified)
|
||||
treeOwnerAsWin->SetPosition(chromeX, chromeY);
|
||||
if (sizeSpecified)
|
||||
treeOwner->SizeShellTo(aDocShellItem, contentCX, contentCY);
|
||||
}
|
||||
treeOwnerAsWin->SetVisibility(PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Return the nsIDOMWindowInternal corresponding to the given nsIWebShell.
|
||||
// Note this forces the creation of a script context, if one has not already
|
||||
// been created. Note it also sets the window's opener to this -- because
|
||||
// it's just convenient, that's all.
|
||||
NS_IMETHODIMP
|
||||
GlobalWindowImpl::ReadyOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
|
||||
nsIDOMWindowInternal **aDOMWindow)
|
||||
{
|
||||
nsresult res;
|
||||
|
||||
*aDOMWindow = nsnull;
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(aDocShellItem));
|
||||
NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE);
|
||||
res = CallQueryInterface(globalObject.get(), aDOMWindow);
|
||||
globalObject->SetOpenerWindow(this); // damnit
|
||||
return res;
|
||||
}
|
||||
|
||||
// Print out a warning message and return NS_ERROR_FAILURE for illegal window names.
|
||||
NS_IMETHODIMP GlobalWindowImpl::CheckWindowName(JSContext *cx, nsString& aName)
|
||||
{
|
||||
PRUint32 strIndex;
|
||||
PRUnichar mChar;
|
||||
|
||||
for (strIndex = 0; strIndex < aName.Length(); strIndex++) {
|
||||
mChar = aName.CharAt(strIndex);
|
||||
if (!nsCRT::IsAsciiAlpha(mChar) && !nsCRT::IsAsciiDigit(mChar) &&
|
||||
mChar != '_') {
|
||||
// Don't use js_ReportError as this will cause the application
|
||||
// to shut down (JS_ASSERT calls abort()) See bug 32898
|
||||
nsAutoString warn;
|
||||
warn.AssignWithConversion("Illegal character in window name ");
|
||||
warn.Append(aName);
|
||||
char *cp = warn.ToNewCString();
|
||||
NS_WARNING(cp);
|
||||
nsCRT::free(cp);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 GlobalWindowImpl::WinHasOption(char *aOptions, const char *aName,
|
||||
PRInt32 aDefault, PRBool *aPresenceFlag)
|
||||
{
|
||||
if (!aOptions)
|
||||
return 0;
|
||||
char *comma, *equal;
|
||||
PRInt32 found = 0;
|
||||
|
||||
while (PR_TRUE) {
|
||||
while (nsCRT::IsAsciiSpace(*aOptions))
|
||||
aOptions++;
|
||||
|
||||
comma = strchr(aOptions, ',');
|
||||
if (comma)
|
||||
*comma = '\0';
|
||||
equal = strchr(aOptions, '=');
|
||||
if (equal)
|
||||
*equal = '\0';
|
||||
if (nsCRT::strcasecmp(aOptions, aName) == 0) {
|
||||
if (aPresenceFlag)
|
||||
*aPresenceFlag = PR_TRUE;
|
||||
if (equal)
|
||||
if (*(equal + 1) == '*')
|
||||
found = aDefault;
|
||||
else if (nsCRT::strcasecmp(equal + 1, "yes") == 0)
|
||||
found = 1;
|
||||
else
|
||||
found = atoi(equal + 1);
|
||||
else
|
||||
found = 1;
|
||||
}
|
||||
if (equal)
|
||||
*equal = '=';
|
||||
if (comma)
|
||||
*comma = ',';
|
||||
if (found || !comma)
|
||||
break;
|
||||
aOptions = comma + 1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void GlobalWindowImpl::CloseWindow(nsISupports *aWindow)
|
||||
|
@ -198,16 +198,6 @@ protected:
|
||||
// Window Control Functions
|
||||
NS_IMETHOD OpenInternal(JSContext* cx, jsval* argv, PRUint32 argc,
|
||||
PRBool aDialog, nsIDOMWindowInternal** aReturn);
|
||||
NS_IMETHOD AttachArguments(nsIDOMWindowInternal* aWindow, jsval* argv,
|
||||
PRUint32 argc);
|
||||
PRUint32 CalculateChromeFlags(char* aFeatures, PRBool aDialog);
|
||||
NS_IMETHOD SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
|
||||
char* aFeatures, PRUint32 aChromeFlags);
|
||||
NS_IMETHOD ReadyOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
|
||||
nsIDOMWindowInternal** aDOMWindow);
|
||||
NS_IMETHOD CheckWindowName(JSContext* cx, nsString& aName);
|
||||
PRInt32 WinHasOption(char* aOptions, const char* aName, PRInt32 aDefault,
|
||||
PRBool* aPresenceFlag);
|
||||
static void CloseWindow(nsISupports* aWindow);
|
||||
|
||||
// Timeout Functions
|
||||
|
Loading…
Reference in New Issue
Block a user