Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | Friends
nsWindowWatcher Class Reference

#include <nsWindowWatcher.h>

Inheritance diagram for nsWindowWatcher:
Inheritance graph
[legend]
Collaboration diagram for nsWindowWatcher:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsWindowWatcher ()
virtual ~nsWindowWatcher ()
nsresult Init ()
nsIDOMWindow openWindow (in nsIDOMWindow aParent, in string aUrl, in string aName, in string aFeatures, in nsISupports aArguments)
 Create a new window.
void registerNotification (in nsIObserver aObserver)
 Clients of this service can register themselves to be notified when a window is opened or closed (added to or removed from this service).
void unregisterNotification (in nsIObserver aObserver)
 Clients of this service can register themselves to be notified when a window is opened or closed (added to or removed from this service).
nsISimpleEnumerator getWindowEnumerator ()
 Get an iterator for currently open windows in the order they were opened, guaranteeing that each will be visited exactly once.
nsIPrompt getNewPrompter (in nsIDOMWindow aParent)
 Return a newly created nsIPrompt implementation.
nsIAuthPrompt getNewAuthPrompter (in nsIDOMWindow aParent)
 Return a newly created nsIAuthPrompt implementation.
void setWindowCreator (in nsIWindowCreator creator)
 Set the window creator callback.
nsIWebBrowserChrome getChromeForWindow (in nsIDOMWindow aWindow)
 Retrieve the chrome window mapped to the given DOM window.
nsIDOMWindow getWindowByName (in wstring aTargetName, in nsIDOMWindow aCurrentWindow)
 Retrieve an existing window (or frame).
void addWindow (in nsIDOMWindow aWindow, in nsIWebBrowserChrome aChrome)
 A window has been created.
void removeWindow (in nsIDOMWindow aWindow)
 A window has been closed.
nsIDOMWindow openWindowJS (in nsIDOMWindow aParent, in string aUrl, in string aName, in string aFeatures, in boolean aDialog, in PRUint32 argc, in jsvalptr argv)
 Like the public interface's open(), but can deal with openDialog style arguments.
nsIDocShellTreeItem findItemWithName (in wstring aName, in nsIDocShellTreeItem aRequestor, in nsIDocShellTreeItem aOriginalRequestor)
 Find a named docshell tree item amongst all windows registered with the window watcher.

Public Attributes

attribute nsIDOMWindow activeWindow
 The Watcher serves as a global storage facility for the current active (frontmost non-floating-palette-type) window, storing and returning it on demand.

Private Member Functions

PRBool AddEnumerator (nsWatcherWindowEnumerator *inEnumerator)
PRBool RemoveEnumerator (nsWatcherWindowEnumerator *inEnumerator)
nsWatcherWindowEntryFindWindowEntry (nsIDOMWindow *aWindow)
nsresult RemoveWindow (nsWatcherWindowEntry *inInfo)
already_AddRefed
< nsIDocShellTreeItem
GetCallerTreeItem (nsIDocShellTreeItem *aParentItem)
nsresult SafeGetWindowByName (const nsAString &aName, nsIDOMWindow *aCurrentWindow, nsIDOMWindow **aResult)
nsresult OpenWindowJSInternal (nsIDOMWindow *aParent, const char *aUrl, const char *aName, const char *aFeatures, PRBool aDialog, PRUint32 argc, jsval *argv, PRBool aCalledFromJS, nsIDOMWindow **_retval)

Static Private Member Functions

static JSContextGetJSContextFromWindow (nsIDOMWindow *aWindow)
static JSContextGetJSContextFromCallStack ()
static nsresult URIfromURL (const char *aURL, nsIDOMWindow *aParent, nsIURI **aURI)
static PRUint32 CalculateChromeFlags (const char *aFeatures, PRBool aFeaturesSpecified, PRBool aDialog, PRBool aChromeURL, PRBool aHasChromeParent)
 Calculate the chrome bitmask from a string list of features.
static PRInt32 WinHasOption (const char *aOptions, const char *aName, PRInt32 aDefault, PRBool *aPresenceFlag)
static void CalcSizeSpec (const char *aFeatures, SizeSpec &aResult)
static nsresult ReadyOpenedDocShellItem (nsIDocShellTreeItem *aOpenedItem, nsIDOMWindow *aParent, PRBool aWindowIsNew, nsIDOMWindow **aOpenedWindow)
static void SizeOpenedDocShellItem (nsIDocShellTreeItem *aDocShellItem, nsIDOMWindow *aParent, const SizeSpec &aSizeSpec)
static nsresult AttachArguments (nsIDOMWindow *aWindow, PRUint32 argc, jsval *argv)
static nsresult ConvertSupportsTojsvals (nsIDOMWindow *aWindow, nsISupports *aArgs, PRUint32 *aArgc, jsval **aArgv, JSContext **aUsedContext, void **aMarkp, nsIScriptContext **aScriptContext)
static nsresult AddSupportsTojsvals (nsISupports *aArg, JSContext *cx, jsval *aArgv)
static nsresult AddInterfaceTojsvals (nsISupports *aArg, JSContext *cx, jsval *aArgv)
static void GetWindowTreeItem (nsIDOMWindow *inWindow, nsIDocShellTreeItem **outTreeItem)
static void GetWindowTreeOwner (nsIDOMWindow *inWindow, nsIDocShellTreeOwner **outTreeOwner)

Private Attributes

nsVoidArray mEnumeratorList
nsWatcherWindowEntrymOldestWindow
nsIDOMWindowmActiveWindow
PRLockmListLock
nsCOMPtr< nsIWindowCreatormWindowCreator

Friends

class nsWatcherWindowEnumerator

Detailed Description

Definition at line 65 of file nsWindowWatcher.h.


Constructor & Destructor Documentation

Definition at line 428 of file nsWindowWatcher.cpp.

Definition at line 436 of file nsWindowWatcher.cpp.

Here is the call graph for this function:


Member Function Documentation

Definition at line 1287 of file nsWindowWatcher.cpp.

{
  // (requires a lock; assumes it's called by someone holding the lock)
  return mEnumeratorList.AppendElement(inEnumerator);
}
nsresult nsWindowWatcher::AddInterfaceTojsvals ( nsISupports *  aArg,
JSContext cx,
jsval aArgv 
) [static, private]

Definition at line 2086 of file nsWindowWatcher.cpp.

{
  nsresult rv;
  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
  rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), aArg,
              NS_GET_IID(nsISupports), getter_AddRefs(wrapper));
  NS_ENSURE_SUCCESS(rv, rv);

  JSObject *obj;
  rv = wrapper->GetJSObject(&obj);
  NS_ENSURE_SUCCESS(rv, rv);

  *aArgv = OBJECT_TO_JSVAL(obj);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsWindowWatcher::AddSupportsTojsvals ( nsISupports *  aArg,
JSContext cx,
jsval aArgv 
) [static, private]

Definition at line 2108 of file nsWindowWatcher.cpp.

{
  if (!aArg) {
    *aArgv = JSVAL_NULL;
    return NS_OK;
  }

  nsCOMPtr<nsISupportsPrimitive> argPrimitive(do_QueryInterface(aArg));
  if (!argPrimitive)
    return AddInterfaceTojsvals(aArg, cx, aArgv);

  PRUint16 type;
  argPrimitive->GetType(&type);

  switch(type) {
    case nsISupportsPrimitive::TYPE_CSTRING : {
      nsCOMPtr<nsISupportsCString> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      nsCAutoString data;

      p->GetData(data);

      
      JSString *str = ::JS_NewStringCopyN(cx, data.get(), data.Length());
      NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);

      *aArgv = STRING_TO_JSVAL(str);

      break;
    }
    case nsISupportsPrimitive::TYPE_STRING : {
      nsCOMPtr<nsISupportsString> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      nsAutoString data;

      p->GetData(data);

      // cast is probably safe since wchar_t and jschar are expected
      // to be equivalent; both unsigned 16-bit entities
      JSString *str =
        ::JS_NewUCStringCopyN(cx,
                              NS_REINTERPRET_CAST(const jschar *,data.get()),
                              data.Length());
      NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);

      *aArgv = STRING_TO_JSVAL(str);
      break;
    }
    case nsISupportsPrimitive::TYPE_PRBOOL : {
      nsCOMPtr<nsISupportsPRBool> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRBool data;

      p->GetData(&data);

      *aArgv = BOOLEAN_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_PRUINT8 : {
      nsCOMPtr<nsISupportsPRUint8> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRUint8 data;

      p->GetData(&data);

      *aArgv = INT_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_PRUINT16 : {
      nsCOMPtr<nsISupportsPRUint16> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRUint16 data;

      p->GetData(&data);

      *aArgv = INT_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_PRUINT32 : {
      nsCOMPtr<nsISupportsPRUint32> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRUint32 data;

      p->GetData(&data);

      *aArgv = INT_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_CHAR : {
      nsCOMPtr<nsISupportsChar> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      char data;

      p->GetData(&data);

      JSString *str = ::JS_NewStringCopyN(cx, &data, 1);
      NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);

      *aArgv = STRING_TO_JSVAL(str);

      break;
    }
    case nsISupportsPrimitive::TYPE_PRINT16 : {
      nsCOMPtr<nsISupportsPRInt16> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRInt16 data;

      p->GetData(&data);

      *aArgv = INT_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_PRINT32 : {
      nsCOMPtr<nsISupportsPRInt32> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      PRInt32 data;

      p->GetData(&data);

      *aArgv = INT_TO_JSVAL(data);

      break;
    }
    case nsISupportsPrimitive::TYPE_FLOAT : {
      nsCOMPtr<nsISupportsFloat> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      float data;

      p->GetData(&data);

      jsdouble *d = ::JS_NewDouble(cx, data);

      *aArgv = DOUBLE_TO_JSVAL(d);

      break;
    }
    case nsISupportsPrimitive::TYPE_DOUBLE : {
      nsCOMPtr<nsISupportsDouble> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      double data;

      p->GetData(&data);

      jsdouble *d = ::JS_NewDouble(cx, data);

      *aArgv = DOUBLE_TO_JSVAL(d);

      break;
    }
    case nsISupportsPrimitive::TYPE_INTERFACE_POINTER : {
      nsCOMPtr<nsISupportsInterfacePointer> p(do_QueryInterface(argPrimitive));
      NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);

      nsCOMPtr<nsISupports> data;
      nsIID *iid = nsnull;

      p->GetData(getter_AddRefs(data));
      p->GetDataIID(&iid);
      NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED);

      AutoFree iidGuard(iid); // Free iid upon destruction.

      nsresult rv;
      nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
      rv = xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), data,
                           *iid, getter_AddRefs(wrapper));
      NS_ENSURE_SUCCESS(rv, rv);

      JSObject *obj;
      rv = wrapper->GetJSObject(&obj);
      NS_ENSURE_SUCCESS(rv, rv);

      *aArgv = OBJECT_TO_JSVAL(obj);

      break;
    }
    case nsISupportsPrimitive::TYPE_ID :
    case nsISupportsPrimitive::TYPE_PRUINT64 :
    case nsISupportsPrimitive::TYPE_PRINT64 :
    case nsISupportsPrimitive::TYPE_PRTIME :
    case nsISupportsPrimitive::TYPE_VOID : {
      NS_WARNING("Unsupported primitive type used");
      *aArgv = JSVAL_NULL;
      break;
    }
    default : {
      NS_WARNING("Unknown primitive type used");
      *aArgv = JSVAL_NULL;
      break;
    }
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsPIWindowWatcher::addWindow ( in nsIDOMWindow  aWindow,
in nsIWebBrowserChrome  aChrome 
) [inherited]

A window has been created.

Add it to our list.

Parameters:
aWindowthe window to add
aChromethe corresponding chrome window. The DOM window and chrome will be mapped together, and the corresponding chrome can be retrieved using the (not private) method getChromeForWindow. If null, any extant mapping will be cleared.
nsresult nsWindowWatcher::AttachArguments ( nsIDOMWindow aWindow,
PRUint32  argc,
jsval argv 
) [static, private]

Definition at line 1998 of file nsWindowWatcher.cpp.

{
  if (argc == 0)
    return NS_OK;

  nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_QueryInterface(aWindow));
  NS_ENSURE_TRUE(scriptGlobal, NS_ERROR_UNEXPECTED);

  // Just ask the global to attach the args for us
  return scriptGlobal->SetNewArguments(argc, NS_STATIC_CAST(void*, argv));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsWindowWatcher::CalcSizeSpec ( const char *  aFeatures,
SizeSpec aResult 
) [static, private]

Definition at line 1753 of file nsWindowWatcher.cpp.

{
  // Parse position spec, if any, from aFeatures
  PRBool  present;
  PRInt32 temp;

  present = PR_FALSE;
  if ((temp = WinHasOption(aFeatures, "left", 0, &present)) || present)
    aResult.mLeft = temp;
  else if ((temp = WinHasOption(aFeatures, "screenX", 0, &present)) || present)
    aResult.mLeft = temp;
  aResult.mLeftSpecified = present;

  present = PR_FALSE;
  if ((temp = WinHasOption(aFeatures, "top", 0, &present)) || present)
    aResult.mTop = temp;
  else if ((temp = WinHasOption(aFeatures, "screenY", 0, &present)) || present)
    aResult.mTop = temp;
  aResult.mTopSpecified = present;

  // Parse size spec, if any. Chrome size overrides content size.
  if ((temp = WinHasOption(aFeatures, "outerWidth", PR_INT32_MIN, nsnull))) {
    if (temp == PR_INT32_MIN) {
      aResult.mUseDefaultWidth = PR_TRUE;
    }
    else {
      aResult.mOuterWidth = temp;
    }
    aResult.mOuterWidthSpecified = PR_TRUE;
  } else if ((temp = WinHasOption(aFeatures, "width", PR_INT32_MIN, nsnull)) ||
             (temp = WinHasOption(aFeatures, "innerWidth", PR_INT32_MIN,
                                  nsnull))) {
    if (temp == PR_INT32_MIN) {
      aResult.mUseDefaultWidth = PR_TRUE;
    } else {
      aResult.mInnerWidth = temp;
    }
    aResult.mInnerWidthSpecified = PR_TRUE;
  }

  if ((temp = WinHasOption(aFeatures, "outerHeight", PR_INT32_MIN, nsnull))) {
    if (temp == PR_INT32_MIN) {
      aResult.mUseDefaultHeight = PR_TRUE;
    }
    else {
      aResult.mOuterHeight = temp;
    }
    aResult.mOuterHeightSpecified = PR_TRUE;
  } else if ((temp = WinHasOption(aFeatures, "height", PR_INT32_MIN,
                                  nsnull)) ||
             (temp = WinHasOption(aFeatures, "innerHeight", PR_INT32_MIN,
                                  nsnull))) {
    if (temp == PR_INT32_MIN) {
      aResult.mUseDefaultHeight = PR_TRUE;
    } else {
      aResult.mInnerHeight = temp;
    }
    aResult.mInnerHeightSpecified = PR_TRUE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint32 nsWindowWatcher::CalculateChromeFlags ( const char *  aFeatures,
PRBool  aFeaturesSpecified,
PRBool  aDialog,
PRBool  aChromeURL,
PRBool  aHasChromeParent 
) [static, private]

Calculate the chrome bitmask from a string list of features.

Parameters:
aFeaturesa string containing a list of named chrome features
aNullFeaturestrue if aFeatures was a null pointer (which fact is lost by its conversion to a string in the caller)
aDialogaffects the assumptions made about unnamed features
Returns:
the chrome bitmask

Definition at line 1386 of file nsWindowWatcher.cpp.

{
   if(!aFeaturesSpecified || !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 */

  nsCOMPtr<nsIScriptSecurityManager>
    securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  NS_ENSURE_TRUE(securityManager, NS_ERROR_FAILURE);

  PRBool isChrome = PR_FALSE;
  securityManager->SubjectPrincipalIsSystem(&isChrome);

  nsCOMPtr<nsIPrefBranch> prefBranch;
  nsresult rv;
  nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, PR_TRUE);

  rv = prefs->GetBranch("dom.disable_window_open_feature.", getter_AddRefs(prefBranch));
  NS_ENSURE_SUCCESS(rv, PR_TRUE);

  PRBool forceEnable = PR_FALSE;

  NS_CALCULATE_CHROME_FLAG_FOR("titlebar",
                               nsIWebBrowserChrome::CHROME_TITLEBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("close",
                               nsIWebBrowserChrome::CHROME_WINDOW_CLOSE);
  NS_CALCULATE_CHROME_FLAG_FOR("toolbar",
                               nsIWebBrowserChrome::CHROME_TOOLBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("location",
                               nsIWebBrowserChrome::CHROME_LOCATIONBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("directories",
                               nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("personalbar",
                               nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("status",
                               nsIWebBrowserChrome::CHROME_STATUSBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("menubar",
                               nsIWebBrowserChrome::CHROME_MENUBAR);
  NS_CALCULATE_CHROME_FLAG_FOR("scrollbars",
                               nsIWebBrowserChrome::CHROME_SCROLLBARS);
  NS_CALCULATE_CHROME_FLAG_FOR("resizable",
                               nsIWebBrowserChrome::CHROME_WINDOW_RESIZE);
  NS_CALCULATE_CHROME_FLAG_FOR("minimizable",
                               nsIWebBrowserChrome::CHROME_WINDOW_MIN);

  chromeFlags |= WinHasOption(aFeatures, "popup", 0, &presenceFlag)
                 ? nsIWebBrowserChrome::CHROME_WINDOW_POPUP : 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, "extrachrome", 0, nsnull) ?
    nsIWebBrowserChrome::CHROME_EXTRA : 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
   */

  // Check security state for use in determing window dimensions
  PRBool enabled;
  nsresult res =
    securityManager->IsCapabilityEnabled("UniversalBrowserWrite", &enabled);

  if (NS_FAILED(res) || !enabled || (isChrome && !aHasChromeParent)) {
    // If priv check fails (or if we're called from chrome, but the
    // parent is not a chrome window), set all elements to minimum
    // reqs., else leave them alone.
    chromeFlags |= nsIWebBrowserChrome::CHROME_TITLEBAR;
    chromeFlags |= nsIWebBrowserChrome::CHROME_WINDOW_CLOSE;
    chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_LOWERED;
    chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_RAISED;
    chromeFlags &= ~nsIWebBrowserChrome::CHROME_WINDOW_POPUP;
    /* Untrusted script is allowed to pose modal windows with a chrome
       scheme. This check could stand to be better. But it effectively
       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);
  }

  if (!(chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
    // Remove the dependent flag if we're not opening as chrome
    chromeFlags &= ~nsIWebBrowserChrome::CHROME_DEPENDENT;
  }

  return chromeFlags;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsWindowWatcher::ConvertSupportsTojsvals ( nsIDOMWindow aWindow,
nsISupports *  aArgs,
PRUint32 aArgc,
jsval **  aArgv,
JSContext **  aUsedContext,
void **  aMarkp,
nsIScriptContext **  aScriptContext 
) [static, private]

Definition at line 2012 of file nsWindowWatcher.cpp.

{
  nsresult rv = NS_OK;

  *aArgv = nsnull;
  *aArgc = 0;

  // copy the elements in aArgsArray into the JS array
  // window.arguments in the new window

  if (!aArgs)
    return NS_OK;

  PRUint32 argCtr, argCount;
  nsCOMPtr<nsISupportsArray> argsArray(do_QueryInterface(aArgs));

  if (argsArray) {
    argsArray->Count(&argCount);
    if (argCount == 0)
      return NS_OK;
  } else
    argCount = 1; // the nsISupports which is not an array

  JSContext           *cx;
  JSContextAutoPopper  contextGuard;

  cx = GetJSContextFromWindow(aWindow);
  if (cx) {
    // Our caller needs to hold a strong ref to keep this context alive.
    *aScriptContext = GetScriptContextFromJSContext(cx);
    NS_ASSERTION(*aScriptContext,
                 "The window's context doesn't have a script context?");
    NS_ADDREF(*aScriptContext);
  } else {
    *aScriptContext = nsnull;
  }
  if (!cx)
    cx = GetJSContextFromCallStack();
  if (!cx) {
    rv = contextGuard.Push();
    if (NS_FAILED(rv))
      return rv;
    cx = contextGuard.get();
  }

  jsval *argv = js_AllocStack(cx, argCount, aMarkp);
  NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY);

  if (argsArray)
    for (argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) {
      nsCOMPtr<nsISupports> s(dont_AddRef(argsArray->ElementAt(argCtr)));
      rv = AddSupportsTojsvals(s, cx, argv + argCtr);
    }
  else
    rv = AddSupportsTojsvals(aArgs, cx, argv);

  if (NS_FAILED(rv)) {
    js_FreeStack(cx, *aMarkp);

    return rv;
  }

  *aUsedContext = cx;
  *aArgv = argv;
  *aArgc = argCount;
  return NS_OK;
}

Here is the call graph for this function:

nsIDocShellTreeItem nsPIWindowWatcher::findItemWithName ( in wstring  aName,
in nsIDocShellTreeItem  aRequestor,
in nsIDocShellTreeItem  aOriginalRequestor 
) [inherited]

Find a named docshell tree item amongst all windows registered with the window watcher.

This may be a subframe in some window, for example.

Parameters:
aNamethe name of the window. Must not be null.
aRequestorthe tree item immediately making the request. We should make sure to not recurse down into its findItemWithName method.
aOriginalRequestorthe original treeitem that made the request. Used for security checks.
Returns:
the tree item with aName as the name, or null if there isn't one. "Special" names, like _self, _top, etc, will be treated specially only if aRequestor is null; in that case they will be resolved relative to the first window the windowwatcher knows about.
See also:
findItemWithName methods on nsIDocShellTreeItem and nsIDocShellTreeOwner

Definition at line 1155 of file nsWindowWatcher.cpp.

{
  // find the corresponding nsWatcherWindowEntry
  nsWatcherWindowEntry *info,
                       *listEnd;
#ifdef USEWEAKREFS
  nsresult    rv;
  PRBool      found;
#endif

  info = mOldestWindow;
  listEnd = 0;
#ifdef USEWEAKREFS
  rv = NS_OK;
  found = PR_FALSE;
  while (info != listEnd && NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIDOMWindow> infoWindow(do_QueryReferent(info->mWindow));
    if (!infoWindow) { // clean up dangling reference, while we're here
      rv = RemoveWindow(info);
    }
    else if (infoWindow.get() == aWindow)
      return info;

    info = info->mYounger;
    listEnd = mOldestWindow;
  }
  return 0;
#else
  while (info != listEnd) {
    if (info->mWindow == aWindow)
      return info;
    info = info->mYounger;
    listEnd = mOldestWindow;
  }
  return 0;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1659 of file nsWindowWatcher.cpp.

{
  nsCOMPtr<nsIJSContextStack> stack =
    do_GetService(sJSStackContractID);

  JSContext *cx = nsnull;

  if (stack) {
    stack->Peek(&cx);
  }

  nsIDocShellTreeItem* callerItem = nsnull;

  if (cx) {
    nsCOMPtr<nsIWebNavigation> callerWebNav =
      do_GetInterface(nsWWJSUtils::GetDynamicScriptGlobal(cx));

    if (callerWebNav) {
      CallQueryInterface(callerWebNav, &callerItem);
    }
  }

  if (!callerItem) {
    NS_IF_ADDREF(callerItem = aParentItem);
  }

  return callerItem;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Retrieve the chrome window mapped to the given DOM window.

Window Watcher keeps a list of all top-level DOM windows currently open, along with their corresponding chrome interfaces. Since DOM Windows lack a (public) means of retrieving their corresponding chrome, this method will do that.

Parameters:
aWindowthe DOM window whose chrome window the caller needs
Returns:
the corresponding chrome window

Definition at line 2349 of file nsWindowWatcher.cpp.

{
  JSContext *cx = 0;

  nsCOMPtr<nsIThreadJSContextStack> cxStack(do_GetService(sJSStackContractID));
  if (cxStack)
    cxStack->Peek(&cx);

  return cx;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2361 of file nsWindowWatcher.cpp.

{
  JSContext *cx = 0;

  if (aWindow) {
    nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aWindow));
    if (sgo) {
      nsIScriptContext *scx = sgo->GetContext();
      if (scx)
        cx = (JSContext *) scx->GetNativeContext();
    }
    /* (off-topic note:) the nsIScriptContext can be retrieved by
    nsCOMPtr<nsIScriptContext> scx;
    nsJSUtils::GetDynamicScriptContext(cx, getter_AddRefs(scx));
    */
  }

  return cx;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return a newly created nsIAuthPrompt implementation.

Parameters:
aParentthe parent window used for posing alerts. can be null.
Returns:
a new nsIAuthPrompt object

Return a newly created nsIPrompt implementation.

Parameters:
aParentthe parent window used for posing alerts. can be null.
Returns:
a new nsIPrompt object
nsIDOMWindow nsIWindowWatcher::getWindowByName ( in wstring  aTargetName,
in nsIDOMWindow  aCurrentWindow 
) [inherited]

Retrieve an existing window (or frame).

Parameters:
aTargetNamethe window name
aCurrentWindowa starting point in the window hierarchy to begin the search. If null, each toplevel window will be searched.

Note: This method will search all open windows for any window or frame with the given window name. Make sure you understand the security implications of this before using this method!

Get an iterator for currently open windows in the order they were opened, guaranteeing that each will be visited exactly once.

Returns:
an enumerator which will itself return nsISupports objects which can be QIed to an nsIDOMWindow
void nsWindowWatcher::GetWindowTreeItem ( nsIDOMWindow inWindow,
nsIDocShellTreeItem **  outTreeItem 
) [static, private]

Definition at line 2323 of file nsWindowWatcher.cpp.

{
  *outTreeItem = 0;

  nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(inWindow));
  if (sgo) {
    nsIDocShell *docshell = sgo->GetDocShell();
    if (docshell)
      CallQueryInterface(docshell, outTreeItem);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsWindowWatcher::GetWindowTreeOwner ( nsIDOMWindow inWindow,
nsIDocShellTreeOwner **  outTreeOwner 
) [static, private]

Definition at line 2337 of file nsWindowWatcher.cpp.

{
  *outTreeOwner = 0;

  nsCOMPtr<nsIDocShellTreeItem> treeItem;
  GetWindowTreeItem(inWindow, getter_AddRefs(treeItem));
  if (treeItem)
    treeItem->GetTreeOwner(outTreeOwner);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 447 of file nsWindowWatcher.cpp.

Here is the call graph for this function:

nsIDOMWindow nsIWindowWatcher::openWindow ( in nsIDOMWindow  aParent,
in string  aUrl,
in string  aName,
in string  aFeatures,
in nsISupports  aArguments 
) [inherited]

Create a new window.

It will automatically be added to our list (via addWindow()).

Parameters:
aParentparent 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.
aURLurl to which to open the new window. Must already be escaped, if applicable. can be null.
aNamewindow name from JS window.open. can be null. If a window with this name already exists, the openWindow call may just load aUrl in it (if aUrl is not null) and return it.
aFeatureswindow features from JS window.open. can be null.
aArgumentsextra argument(s) to the new window, to be attached as the |arguments| property. An nsISupportsArray will be unwound into multiple arguments (but not recursively!). can be null.
Returns:
the new window
Note:
This method may examine the JS context stack for purposes of determining the security context to use for the search for a given window named aName.
This method should try to set the default charset for the new window to the default charset of aParent. This is not guaranteed, however.
This method may dispatch a "toplevel-window-ready" notification via nsIObserverService if the window did not already exist.
nsIDOMWindow nsPIWindowWatcher::openWindowJS ( in nsIDOMWindow  aParent,
in string  aUrl,
in string  aName,
in string  aFeatures,
in boolean  aDialog,
in PRUint32  argc,
in jsvalptr  argv 
) [inherited]

Like the public interface's open(), but can deal with openDialog style arguments.

Parameters:
aParentparent 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.
aURLurl to which to open the new window. Must already be escaped, if applicable. can be null.
aNamewindow name from JS window.open. can be null. If a window with this name already exists, the openWindow call may just load aUrl in it (if aUrl is not null) and return it.
aFeatureswindow features from JS window.open. can be null.
aDialoguse dialog defaults (see nsIDOMWindowInternal::openDialog)
argccount of argv arguments
argvextra JS arguments, if any (see nsIDOMWindowInternal::openDialog)
Returns:
the new window
Note:
This method may examine the JS context stack for purposes of determining the security context to use for the search for a given window named aName.
This method should try to set the default charset for the new window to the default charset of the document in the calling window (which is determined based on the JS stack and the value of aParent). This is not guaranteed, however.
nsresult nsWindowWatcher::OpenWindowJSInternal ( nsIDOMWindow aParent,
const char *  aUrl,
const char *  aName,
const char *  aFeatures,
PRBool  aDialog,
PRUint32  argc,
jsval argv,
PRBool  aCalledFromJS,
nsIDOMWindow **  _retval 
) [private]

Definition at line 544 of file nsWindowWatcher.cpp.

{
  nsresult                        rv = NS_OK;
  PRBool                          nameSpecified,
                                  featuresSpecified,
                                  isNewToplevelWindow = PR_FALSE,
                                  windowIsNew = PR_FALSE,
                                  windowNeedsName = PR_FALSE,
                                  windowIsModal = PR_FALSE,
                                  uriToLoadIsChrome = PR_FALSE;
  PRUint32                        chromeFlags;
  nsAutoString                    name;             // string version of aName
  nsCAutoString                   features;         // string version of aFeatures
  nsCOMPtr<nsIURI>                uriToLoad;        // from aUrl, if any
  nsCOMPtr<nsIDocShellTreeOwner>  parentTreeOwner;  // from the parent window, if any
  nsCOMPtr<nsIDocShellTreeItem>   newDocShellItem;  // from the new window
  EventQueueAutoPopper            queueGuard;
  JSContextAutoPopper             callerContextGuard;

  NS_ENSURE_ARG_POINTER(_retval);
  *_retval = 0;

  GetWindowTreeOwner(aParent, getter_AddRefs(parentTreeOwner));

  if (aUrl) {
    rv = URIfromURL(aUrl, aParent, getter_AddRefs(uriToLoad));
    if (NS_FAILED(rv))
      return rv;
    uriToLoad->SchemeIs("chrome", &uriToLoadIsChrome);
  }

  nameSpecified = PR_FALSE;
  if (aName) {
    CopyUTF8toUTF16(aName, name);
#ifdef DEBUG
    CheckWindowName(name);
#endif
    nameSpecified = PR_TRUE;
  }

  featuresSpecified = PR_FALSE;
  if (aFeatures) {
    features.Assign(aFeatures);
    featuresSpecified = PR_TRUE;
    features.StripWhitespace();
  }

  // try to find an extant window with the given name
  nsCOMPtr<nsIDOMWindow> foundWindow;
  SafeGetWindowByName(name, aParent, getter_AddRefs(foundWindow));
  GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem));

  // no extant window? make a new one.

  nsCOMPtr<nsIDOMChromeWindow> chromeParent(do_QueryInterface(aParent));

  // 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
  // security checks.
  chromeFlags = CalculateChromeFlags(features.get(), featuresSpecified,
                                     aDialog, uriToLoadIsChrome,
                                     !aParent || chromeParent);

  SizeSpec sizeSpec;
  CalcSizeSpec(features.get(), sizeSpec);

  PRBool isCallerChrome = PR_FALSE;
  nsCOMPtr<nsIScriptSecurityManager>
    sm(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  if (sm)
    sm->SubjectPrincipalIsSystem(&isCallerChrome);

  JSContext *cx = GetJSContextFromWindow(aParent);

  if (isCallerChrome && !chromeParent && cx) {
    // open() is called from chrome on a non-chrome window, push
    // the context of the callee onto the context stack to
    // prevent the caller's priveleges from leaking into code
    // that runs while opening the new window.

    callerContextGuard.Push(cx);
  }

  if (!newDocShellItem) {
    // We're going to either open up a new window ourselves or ask a
    // nsIWindowProvider for one.  In either case, we'll want to set the right
    // name on it.
    windowNeedsName = PR_TRUE;

    // Now check whether it's ok to ask a window provider for a window.  Don't
    // do it if we're opening a dialog or if our parent is a chrome window or
    // if we're opening something that has modal, dialog, or chrome flags set.
    nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(aParent);
    if (!aDialog && !chromeWin &&
        !(chromeFlags & (nsIWebBrowserChrome::CHROME_MODAL         |
                         nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | 
                         nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
      nsCOMPtr<nsIWindowProvider> provider = do_GetInterface(parentTreeOwner);
      if (provider) {
        NS_ASSERTION(aParent, "We've _got_ to have a parent here!");

        nsCOMPtr<nsIDOMWindow> newWindow;
        rv = provider->ProvideWindow(aParent, chromeFlags,
                                     sizeSpec.PositionSpecified(),
                                     sizeSpec.SizeSpecified(),
                                     uriToLoad, name, features, &windowIsNew,
                                     getter_AddRefs(newWindow));
        if (NS_SUCCEEDED(rv)) {
          GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
          if (windowIsNew && newDocShellItem) {
            // Make sure to stop any loads happening in this window that the
            // window provider might have started.  Otherwise if our caller
            // manipulates the window it just opened and then the load
            // completes their stuff will get blown away.
            nsCOMPtr<nsIWebNavigation> webNav =
              do_QueryInterface(newDocShellItem);
            webNav->Stop(nsIWebNavigation::STOP_NETWORK);
          }
        }
      }
    }
  }
  
  if (!newDocShellItem) {
    windowIsNew = PR_TRUE;
    isNewToplevelWindow = PR_TRUE;

    nsCOMPtr<nsIWebBrowserChrome> parentChrome(do_GetInterface(parentTreeOwner));

    // is the parent (if any) modal? if so, we must be, too.
    PRBool weAreModal = (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL) != 0;
    if (!weAreModal && parentChrome)
      parentChrome->IsWindowModal(&weAreModal);

    if (weAreModal) {
      rv = queueGuard.Push();
      if (NS_SUCCEEDED(rv)) {
        windowIsModal = PR_TRUE;
        // in case we added this because weAreModal
        chromeFlags |= nsIWebBrowserChrome::CHROME_MODAL |
          nsIWebBrowserChrome::CHROME_DEPENDENT;
      }
    }

    NS_ASSERTION(mWindowCreator,
                 "attempted to open a new window with no WindowCreator");
    rv = NS_ERROR_FAILURE;
    if (mWindowCreator) {
      nsCOMPtr<nsIWebBrowserChrome> newChrome;

      /* If the window creator is an nsIWindowCreator2, we can give it
         some hints. The only hint at this time is whether the opening window
         is in a situation that's likely to mean this is an unrequested
         popup window we're creating. However we're not completely honest:
         we clear that indicator if the opener is chrome, so that the
         downstream consumer can treat the indicator to mean simply
         that the new window is subject to popup control. */
      nsCOMPtr<nsIWindowCreator2> windowCreator2(do_QueryInterface(mWindowCreator));
      if (windowCreator2) {
        PRUint32 contextFlags = 0;
        PRBool popupConditions = PR_FALSE;

        // is the parent under popup conditions?
        nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(aParent));
        if (piWindow)
          popupConditions = piWindow->IsLoadingOrRunningTimeout();

        // chrome is always allowed, so clear the flag if the opener is chrome
        if (popupConditions) {
          PRBool isChrome = PR_FALSE;
          if (sm)
            sm->SubjectPrincipalIsSystem(&isChrome);
          popupConditions = !isChrome;
        }

        if (popupConditions)
          contextFlags |= nsIWindowCreator2::PARENT_IS_LOADING_OR_RUNNING_TIMEOUT;

        PRBool cancel = PR_FALSE;
        rv = windowCreator2->CreateChromeWindow2(parentChrome, chromeFlags,
                               contextFlags, uriToLoad, &cancel,
                               getter_AddRefs(newChrome));
        if (NS_SUCCEEDED(rv) && cancel) {
          newChrome = 0; // just in case
          rv = NS_ERROR_ABORT;
        }
      }
      else
        rv = mWindowCreator->CreateChromeWindow(parentChrome, chromeFlags,
                               getter_AddRefs(newChrome));
      if (newChrome) {
        /* It might be a chrome nsXULWindow, in which case it won't have
            an nsIDOMWindow (primary content shell). But in that case, it'll
            be able to hand over an nsIDocShellTreeItem directly. */
        nsCOMPtr<nsIDOMWindow> newWindow(do_GetInterface(newChrome));
        if (newWindow)
          GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
        if (!newDocShellItem)
          newDocShellItem = do_GetInterface(newChrome);
        if (!newDocShellItem)
          rv = NS_ERROR_FAILURE;
      }
    }
  }

  // better have a window to use by this point
  if (!newDocShellItem)
    return rv;

  nsCOMPtr<nsIDocShell> newDocShell(do_QueryInterface(newDocShellItem));
  NS_ENSURE_TRUE(newDocShell, NS_ERROR_UNEXPECTED);
  
  rv = ReadyOpenedDocShellItem(newDocShellItem, aParent, windowIsNew, _retval);
  if (NS_FAILED(rv))
    return rv;

  /* disable persistence of size/position in popups (determined by
     determining whether the features parameter specifies width or height
     in any way). We consider any overriding of the window's size or position
     in the open call as disabling persistence of those attributes.
     Popup windows (which should not persist size or position) generally set
     the size. */
  if (isNewToplevelWindow) {
    /* at the moment, the strings "height=" or "width=" never happen
       outside a size specification, so we can do this the Q&D way. */

    if (PL_strcasestr(features.get(), "width=") || PL_strcasestr(features.get(), "height=")) {

      nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
      newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
      if (newTreeOwner)
        newTreeOwner->SetPersistence(PR_FALSE, PR_FALSE, PR_FALSE);
    }
  }

  if (aDialog && argc > 0) {
    rv = AttachArguments(*_retval, argc, argv);

    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  /* allow a window that we found by name to keep its name (important for cases
     like _self where the given name is different (and invalid)).  Also, _blank
     and _new are not window names. */
  if (windowNeedsName)
    newDocShellItem->SetName(nameSpecified &&
                             !name.LowerCaseEqualsLiteral("_blank") &&
                             !name.LowerCaseEqualsLiteral("_new") ?
                             name.get() : nsnull);


  // Inherit the right character set into the new window to use as a fallback
  // in the event the document being loaded does not specify a charset.  When
  // aCalledFromJS is true, we want to use the character set of the document in
  // the caller; otherwise we want to use the character set of aParent's
  // docshell. Failing to set this charset is not fatal, so we want to continue
  // in the face of errors.
  nsCOMPtr<nsIContentViewer> newCV;
  newDocShell->GetContentViewer(getter_AddRefs(newCV));
  nsCOMPtr<nsIMarkupDocumentViewer> newMuCV = do_QueryInterface(newCV);
  if (newMuCV) {
    nsCOMPtr<nsIDocShellTreeItem> parentItem;
    GetWindowTreeItem(aParent, getter_AddRefs(parentItem));

    if (aCalledFromJS) {
      nsCOMPtr<nsIDocShellTreeItem> callerItem = GetCallerTreeItem(parentItem);
      nsCOMPtr<nsPIDOMWindow> callerWin = do_GetInterface(callerItem);
      if (callerWin) {
        nsCOMPtr<nsIDocument> doc =
          do_QueryInterface(callerWin->GetExtantDocument());
        if (doc) {
          newMuCV->SetDefaultCharacterSet(doc->GetDocumentCharacterSet());
        }
      }
    }
    else {
      nsCOMPtr<nsIDocShell> parentDocshell = do_QueryInterface(parentItem);
      // parentDocshell may be null if the parent got closed in the meantime
      if (parentDocshell) {
        nsCOMPtr<nsIContentViewer> parentCV;
        parentDocshell->GetContentViewer(getter_AddRefs(parentCV));
        nsCOMPtr<nsIMarkupDocumentViewer> parentMuCV =
          do_QueryInterface(parentCV);
        if (parentMuCV) {
          nsCAutoString charset;
          nsresult res = parentMuCV->GetDefaultCharacterSet(charset);
          if (NS_SUCCEEDED(res)) {
            newMuCV->SetDefaultCharacterSet(charset);
          }
          res = parentMuCV->GetPrevDocCharacterSet(charset);
          if (NS_SUCCEEDED(res)) {
            newMuCV->SetPrevDocCharacterSet(charset);
          }
        }
      }
    }
  }

  if (isNewToplevelWindow) {
    // Notify observers that the window is open and ready.
    // The window has not yet started to load a document.
    nsCOMPtr<nsIObserverService> obsSvc =
      do_GetService("@mozilla.org/observer-service;1");
    if (obsSvc) {
      obsSvc->NotifyObservers(*_retval, "toplevel-window-ready", nsnull);
    }
  }

  // Now we have to set the right opener principal on the new window.  Note
  // that we have to do this _before_ starting any URI loads, thanks to the
  // sync nature of javascript: loads.  Since this is the only place where we
  // set said opener principal, we need to do it for all URIs, including
  // chrome ones.  So to deal with the mess that is bug 79775, just press on in
  // a reasonable way even if GetSubjectPrincipal fails.  In that case, just
  // use a null subjectPrincipal.
  nsCOMPtr<nsIPrincipal> subjectPrincipal;
  if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)))) {
    subjectPrincipal = nsnull;
  }

  if (windowIsNew) {
    // Now set the opener principal on the new window.  Note that we need to do
    // this no matter whether we were opened from JS; if there is nothing on
    // the JS stack, just use the principal of our parent window.  In those
    // cases we do _not_ set the parent window principal as the owner of the
    // load--since we really don't know who the owner is, just leave it null.
    nsIPrincipal* newWindowPrincipal = subjectPrincipal;
    if (!newWindowPrincipal && aParent) {
      nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aParent));
      if (sop) {
        newWindowPrincipal = sop->GetPrincipal();
      }
    }

    nsCOMPtr<nsIPrincipal> systemPrincipal;
    sm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
    if (newWindowPrincipal == systemPrincipal) {
      // Don't pass this principal along to content windows
      PRInt32 itemType;
      rv = newDocShellItem->GetItemType(&itemType);
      if (NS_FAILED(rv) || itemType != nsIDocShellTreeItem::typeChrome) {
        newWindowPrincipal = nsnull;        
      }
    }

    nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH2> newWindow =
      do_QueryInterface(*_retval);
#ifdef DEBUG
    nsCOMPtr<nsPIDOMWindow> newDebugWindow = do_GetInterface(newDocShell);
    NS_ASSERTION(newWindow == newDebugWindow, "Different windows??");
#endif
    if (newWindow) {
      newWindow->SetOpenerScriptPrincipal(newWindowPrincipal);
    }
  }

  if (uriToLoad) { // get the script principal and pass it to docshell
    JSContextAutoPopper contextGuard;

    cx = GetJSContextFromCallStack();

    // get the security manager
    if (!cx)
      cx = GetJSContextFromWindow(aParent);
    if (!cx) {
      rv = contextGuard.Push();
      if (NS_FAILED(rv))
        return rv;
      cx = contextGuard.get();
    }

    nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
    newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
    NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);

    if (subjectPrincipal) {
      loadInfo->SetOwner(subjectPrincipal);
    }

    // Set the new window's referrer from the calling context's document:

    // get the calling context off the JS context stack
    nsCOMPtr<nsIJSContextStack> stack = do_GetService(sJSStackContractID);

    JSContext* ccx = nsnull;

    // get its document, if any
    if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
      nsIScriptGlobalObject *sgo = nsWWJSUtils::GetDynamicScriptGlobal(ccx);

      nsCOMPtr<nsPIDOMWindow> w(do_QueryInterface(sgo));
      if (w) {
        /* use the URL from the *extant* document, if any. The usual accessor
           GetDocument will synchronously create an about:blank document if
           it has no better answer, and we only care about a real document.
           Also using GetDocument to force document creation seems to
           screw up focus in the hidden window; see bug 36016.
        */
        nsCOMPtr<nsIDocument> doc(do_QueryInterface(w->GetExtantDocument()));
        if (doc) { 
          // Set the referrer
          loadInfo->SetReferrer(doc->GetDocumentURI());
        }
      }
    }

    newDocShell->LoadURI(uriToLoad, loadInfo,
      windowIsNew ? nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD :
                    nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
  }

  if (isNewToplevelWindow)
    SizeOpenedDocShellItem(newDocShellItem, aParent, sizeSpec);

  if (windowIsModal) {
    nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
    newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
    nsCOMPtr<nsIWebBrowserChrome> newChrome(do_GetInterface(newTreeOwner));
    if (newChrome)
      newChrome->ShowAsModal();
    NS_ASSERTION(newChrome, "show modal window failed: no available chrome");
  }

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsWindowWatcher::ReadyOpenedDocShellItem ( nsIDocShellTreeItem aOpenedItem,
nsIDOMWindow aParent,
PRBool  aWindowIsNew,
nsIDOMWindow **  aOpenedWindow 
) [static, private]

Definition at line 1723 of file nsWindowWatcher.cpp.

{
  nsresult rv = NS_ERROR_FAILURE;

  *aOpenedWindow = 0;
  nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(aOpenedItem));
  if (globalObject) {
    if (aParent) {
      nsCOMPtr<nsIDOMWindowInternal> internalParent(do_QueryInterface(aParent));
      nsCOMPtr<nsPIDOMWindow_MOZILLA_1_8_BRANCH> branchWindow =
        do_QueryInterface(globalObject);
      branchWindow->SetOpenerWindow(internalParent, aWindowIsNew); // damnit

      if (aWindowIsNew) {
        nsCOMPtr<nsIDocument_MOZILLA_1_8_BRANCH2> doc =
          do_QueryInterface(branchWindow->GetExtantDocument());
        if (doc) {
          doc->SetIsInitialDocument(PR_TRUE);
        }
      }
    }
    rv = CallQueryInterface(globalObject, aOpenedWindow);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Clients of this service can register themselves to be notified when a window is opened or closed (added to or removed from this service).

This method adds an aObserver to the list of objects to be notified.

Parameters:
aObserverthe object to be notified when windows are opened or closed. Its Observe method will be called with the following parameters:

aObserver::Observe interprets its parameters so: aSubject the window being opened or closed, sent as an nsISupports which can be QIed to an nsIDOMWindow. aTopic a wstring, either "domwindowopened" or "domwindowclosed". someData not used.

Definition at line 1294 of file nsWindowWatcher.cpp.

{
  // (requires a lock; assumes it's called by someone holding the lock)
  return mEnumeratorList.RemoveElement(inEnumerator);
}

Here is the caller graph for this function:

A window has been closed.

Remove it from our list.

Parameters:
aWindowthe window to remove

Definition at line 1138 of file nsWindowWatcher.cpp.

{
  // find the corresponding nsWatcherWindowEntry, remove it

  if (!aWindow)
    return NS_ERROR_INVALID_ARG;

  nsWatcherWindowEntry *info = FindWindowEntry(aWindow);
  if (info) {
    RemoveWindow(info);
    return NS_OK;
  }
  NS_WARNING("requested removal of nonexistent window\n");
  return NS_ERROR_INVALID_ARG;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsWindowWatcher::SafeGetWindowByName ( const nsAString &  aName,
nsIDOMWindow aCurrentWindow,
nsIDOMWindow **  aResult 
) [private]

Definition at line 1689 of file nsWindowWatcher.cpp.

{
  *aResult = nsnull;
  
  nsCOMPtr<nsIDocShellTreeItem> startItem;
  GetWindowTreeItem(aCurrentWindow, getter_AddRefs(startItem));

  nsCOMPtr<nsIDocShellTreeItem> callerItem = GetCallerTreeItem(startItem);

  const nsAFlatString& flatName = PromiseFlatString(aName);

  nsCOMPtr<nsIDocShellTreeItem> foundItem;
  if (startItem) {
    startItem->FindItemWithName(flatName.get(), nsnull, callerItem,
                                getter_AddRefs(foundItem));
  }
  else {
    FindItemWithName(flatName.get(), nsnull, callerItem,
                     getter_AddRefs(foundItem));
  }

  nsCOMPtr<nsIDOMWindow> foundWin = do_GetInterface(foundItem);
  foundWin.swap(*aResult);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Set the window creator callback.

It must be filled in by the app. openWindow will use it to create new windows.

Parameters:
creatorthe callback. if null, the callback will be cleared and window creation capabilities lost.
void nsWindowWatcher::SizeOpenedDocShellItem ( nsIDocShellTreeItem aDocShellItem,
nsIDOMWindow aParent,
const SizeSpec aSizeSpec 
) [static, private]

Definition at line 1820 of file nsWindowWatcher.cpp.

{
  // position and size of window
  PRInt32 left = 0,
          top = 0,
          width = 100,
          height = 100;
  // difference between chrome and content size
  PRInt32 chromeWidth = 0,
          chromeHeight = 0;
  // whether the window size spec refers to chrome or content
  PRBool  sizeChromeWidth = PR_TRUE,
          sizeChromeHeight = PR_TRUE;

  // get various interfaces for aDocShellItem, used throughout this method
  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
  aDocShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
  nsCOMPtr<nsIBaseWindow> treeOwnerAsWin(do_QueryInterface(treeOwner));
  if (!treeOwnerAsWin) // we'll need this to actually size the docshell
    return;

  /* The current position and size will be unchanged if not specified
     (and they fit entirely onscreen). Also, calculate the difference
     between chrome and content sizes on aDocShellItem's window.
     This latter point becomes important if chrome and content
     specifications are mixed in aFeatures, and when bringing the window
     back from too far off the right or bottom edges of the screen. */

  treeOwnerAsWin->GetPositionAndSize(&left, &top, &width, &height);
  { // scope shellWindow why not
    nsCOMPtr<nsIBaseWindow> shellWindow(do_QueryInterface(aDocShellItem));
    if (shellWindow) {
      PRInt32 cox, coy;
      shellWindow->GetSize(&cox, &coy);
      chromeWidth = width - cox;
      chromeHeight = height - coy;
    }
  }

  // Set up left/top
  if (aSizeSpec.mLeftSpecified) {
    left = aSizeSpec.mLeft;
  }

  if (aSizeSpec.mTopSpecified) {
    top = aSizeSpec.mTop;
  }

  // Set up width
  if (aSizeSpec.mOuterWidthSpecified) {
    if (!aSizeSpec.mUseDefaultWidth) {
      width = aSizeSpec.mOuterWidth;
    } // Else specified to default; just use our existing width
  }
  else if (aSizeSpec.mInnerWidthSpecified) {
    sizeChromeWidth = PR_FALSE;
    if (aSizeSpec.mUseDefaultWidth) {
      width = width - chromeWidth;
    } else {
      width = aSizeSpec.mInnerWidth;
    }
  }

  // Set up height
  if (aSizeSpec.mOuterHeightSpecified) {
    if (!aSizeSpec.mUseDefaultHeight) {
      height = aSizeSpec.mOuterHeight;
    } // Else specified to default; just use our existing height
  }
  else if (aSizeSpec.mInnerHeightSpecified) {
    sizeChromeHeight = PR_FALSE;
    if (aSizeSpec.mUseDefaultHeight) {
      height = height - chromeHeight;
    } else {
      height = aSizeSpec.mInnerHeight;
    }
  }

  PRBool positionSpecified = aSizeSpec.PositionSpecified();
  
  nsresult res;
  PRBool enabled = PR_FALSE;

  // Check security state for use in determing window dimensions
  nsCOMPtr<nsIScriptSecurityManager>
    securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  if (securityManager) {
    res = securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
                                               &enabled);
    if (NS_FAILED(res))
      enabled = PR_FALSE;
    else if (enabled && aParent) {
      nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(aParent));

      PRBool isChrome = PR_FALSE;
      securityManager->SubjectPrincipalIsSystem(&isChrome);

      // Only enable special priveleges for chrome when chrome calls
      // open() on a chrome window
      enabled = !(isChrome && chromeWin == nsnull);
    }
  }

  if (!enabled) {

    // Security check failed.  Ensure all args meet minimum reqs.

    PRInt32 oldTop = top,
            oldLeft = left;

    // We'll also need the screen dimensions
    nsCOMPtr<nsIScreen> screen;
    nsCOMPtr<nsIScreenManager> screenMgr(do_GetService(
                                         "@mozilla.org/gfx/screenmanager;1"));
    if (screenMgr)
      screenMgr->ScreenForRect(left, top, width, height,
                               getter_AddRefs(screen));
    if (screen) {
      PRInt32 screenLeft, screenTop, screenWidth, screenHeight;
      PRInt32 winWidth = width + (sizeChromeWidth ? 0 : chromeWidth),
              winHeight = height + (sizeChromeHeight ? 0 : chromeHeight);

      screen->GetAvailRect(&screenLeft, &screenTop,
                           &screenWidth, &screenHeight);

      if (aSizeSpec.SizeSpecified()) {
        /* Unlike position, force size out-of-bounds check only if
           size actually was specified. Otherwise, intrinsically sized
           windows are broken. */
        if (height < 100)
          height = 100;
        if (winHeight > screenHeight)
          height = screenHeight - (sizeChromeHeight ? 0 : chromeHeight);
        if (width < 100)
          width = 100;
        if (winWidth > screenWidth)
          width = screenWidth - (sizeChromeWidth ? 0 : chromeWidth);
      }

      if (left+winWidth > screenLeft+screenWidth)
        left = screenLeft+screenWidth - winWidth;
      if (left < screenLeft)
        left = screenLeft;
      if (top+winHeight > screenTop+screenHeight)
        top = screenTop+screenHeight - winHeight;
      if (top < screenTop)
        top = screenTop;
      if (top != oldTop || left != oldLeft)
        positionSpecified = PR_TRUE;
    }
  }

  // size and position the window

  if (positionSpecified)
    treeOwnerAsWin->SetPosition(left, top);
  if (aSizeSpec.SizeSpecified()) {
    /* Prefer to trust the interfaces, which think in terms of pure
       chrome or content sizes. If we have a mix, use the chrome size
       adjusted by the chrome/content differences calculated earlier. */
    if (!sizeChromeWidth && !sizeChromeHeight)
      treeOwner->SizeShellTo(aDocShellItem, width, height);
    else {
      if (!sizeChromeWidth)
        width += chromeWidth;
      if (!sizeChromeHeight)
        height += chromeHeight;
      treeOwnerAsWin->SetSize(width, height, PR_FALSE);
    }
  }
  treeOwnerAsWin->SetVisibility(PR_TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Clients of this service can register themselves to be notified when a window is opened or closed (added to or removed from this service).

This method removes an aObserver from the list of objects to be notified.

Parameters:
aObserverthe observer to be removed.
nsresult nsWindowWatcher::URIfromURL ( const char *  aURL,
nsIDOMWindow aParent,
nsIURI **  aURI 
) [static, private]

Definition at line 1301 of file nsWindowWatcher.cpp.

{
  nsCOMPtr<nsIDOMWindow> baseWindow;

  /* build the URI relative to the calling JS Context, if any.
     (note this is the same context used to make the security check
     in nsGlobalWindow.cpp.) */
  JSContext *cx = GetJSContextFromCallStack();
  if (cx) {
    nsIScriptContext *scriptcx = nsWWJSUtils::GetDynamicScriptContext(cx);
    if (scriptcx) {
      baseWindow = do_QueryInterface(scriptcx->GetGlobalObject());
    }
  }

  // failing that, build it relative to the parent window, if possible
  if (!baseWindow)
    baseWindow = aParent;

  // failing that, use the given URL unmodified. It had better not be relative.

  nsIURI *baseURI = nsnull;

  // get baseWindow's document URI
  if (baseWindow) {
    nsCOMPtr<nsIDOMDocument> domDoc;
    baseWindow->GetDocument(getter_AddRefs(domDoc));
    if (domDoc) {
      nsCOMPtr<nsIDocument> doc;
      doc = do_QueryInterface(domDoc);
      if (doc) {
        baseURI = doc->GetBaseURI();
      }
    }
  }

  // build and return the absolute URI
  return NS_NewURI(aURI, aURL, baseURI);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsWindowWatcher::WinHasOption ( const char *  aOptions,
const char *  aName,
PRInt32  aDefault,
PRBool aPresenceFlag 
) [static, private]

Definition at line 1544 of file nsWindowWatcher.cpp.

{
  if (!aOptions)
    return 0;

  char *comma, *equal;
  PRInt32 found = 0;

#ifdef DEBUG
    nsCAutoString options(aOptions);
    NS_ASSERTION(options.FindCharInSet(" \n\r\t") == kNotFound, 
                  "There should be no whitespace in this string!");
#endif

  while (PR_TRUE) {
    comma = PL_strchr(aOptions, ',');
    if (comma)
      *comma = '\0';
    equal = PL_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;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class nsWatcherWindowEnumerator [friend]

Definition at line 69 of file nsWindowWatcher.h.


Member Data Documentation

The Watcher serves as a global storage facility for the current active (frontmost non-floating-palette-type) window, storing and returning it on demand.

Users must keep this attribute current, including after the topmost window is closed. This attribute obviously can return null if no windows are open, but should otherwise always return a valid window.

Definition at line 191 of file nsIWindowWatcher.idl.

Definition at line 156 of file nsWindowWatcher.h.

Definition at line 154 of file nsWindowWatcher.h.

Definition at line 157 of file nsWindowWatcher.h.

Definition at line 155 of file nsWindowWatcher.h.

Definition at line 159 of file nsWindowWatcher.h.


The documentation for this class was generated from the following files: