moving window opening code to WindowWatcher component. bug 67368 r=hyatt,jst

This commit is contained in:
danm%netscape.com 2001-02-26 00:37:55 +00:00
parent f5437ab8bf
commit 48ff9b0878
2 changed files with 13 additions and 720 deletions

View File

@ -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)

View File

@ -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