LCOV - code coverage report
Current view: directory - xpfe/appshell/src - nsAppShellService.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 195 22 11.3 %
Date: 2012-06-02 Functions: 17 7 41.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      24                 :  *   Robert O'Callahan <roc+moz@cs.cmu.edu>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : 
      41                 : #include "nsIAppShellService.h"
      42                 : #include "nsISupportsArray.h"
      43                 : #include "nsIComponentManager.h"
      44                 : #include "nsIURL.h"
      45                 : #include "nsNetUtil.h"
      46                 : #include "nsIServiceManager.h"
      47                 : #include "nsIObserverService.h"
      48                 : #include "nsIObserver.h"
      49                 : #include "nsIXPConnect.h"
      50                 : #include "nsIJSContextStack.h"
      51                 : 
      52                 : #include "nsIWindowMediator.h"
      53                 : #include "nsIWindowWatcher.h"
      54                 : #include "nsPIWindowWatcher.h"
      55                 : #include "nsIDOMWindow.h"
      56                 : #include "nsWebShellWindow.h"
      57                 : 
      58                 : #include "nsIEnumerator.h"
      59                 : #include "nsCRT.h"
      60                 : #include "prprf.h"    
      61                 : 
      62                 : #include "nsWidgetsCID.h"
      63                 : #include "nsIRequestObserver.h"
      64                 : 
      65                 : /* For implementing GetHiddenWindowAndJSContext */
      66                 : #include "nsIScriptGlobalObject.h"
      67                 : #include "nsIScriptContext.h"
      68                 : #include "jsapi.h"
      69                 : 
      70                 : #include "nsAppShellService.h"
      71                 : #include "nsISupportsPrimitives.h"
      72                 : #include "nsIPlatformCharset.h"
      73                 : #include "nsICharsetConverterManager.h"
      74                 : #include "nsIUnicodeDecoder.h"
      75                 : #include "nsIChromeRegistry.h"
      76                 : 
      77                 : #include "mozilla/Preferences.h"
      78                 : #include "mozilla/StartupTimeline.h"
      79                 : 
      80                 : using namespace mozilla;
      81                 : 
      82                 : // Default URL for the hidden window, can be overridden by a pref on Mac
      83                 : #define DEFAULT_HIDDENWINDOW_URL "resource://gre-resources/hiddenWindow.html"
      84                 : 
      85                 : class nsIAppShell;
      86                 : 
      87             101 : nsAppShellService::nsAppShellService() : 
      88                 :   mXPCOMWillShutDown(false),
      89                 :   mXPCOMShuttingDown(false),
      90                 :   mModalWindowCount(0),
      91             101 :   mApplicationProvidedHiddenWindow(false)
      92                 : {
      93                 :   nsCOMPtr<nsIObserverService> obs
      94             202 :     (do_GetService("@mozilla.org/observer-service;1"));
      95                 : 
      96             101 :   if (obs) {
      97             101 :     obs->AddObserver(this, "xpcom-will-shutdown", false);
      98             101 :     obs->AddObserver(this, "xpcom-shutdown", false);
      99                 :   }
     100             101 : }
     101                 : 
     102             101 : nsAppShellService::~nsAppShellService()
     103                 : {
     104             101 : }
     105                 : 
     106                 : 
     107                 : /*
     108                 :  * Implement the nsISupports methods...
     109                 :  */
     110            3109 : NS_IMPL_ISUPPORTS2(nsAppShellService,
     111                 :                    nsIAppShellService,
     112                 :                    nsIObserver)
     113                 : 
     114                 : NS_IMETHODIMP
     115               0 : nsAppShellService::CreateHiddenWindow()
     116                 : {
     117                 :   nsresult rv;
     118               0 :   PRInt32 initialHeight = 100, initialWidth = 100;
     119                 :     
     120                 : #ifdef XP_MACOSX
     121                 :   PRUint32    chromeMask = 0;
     122                 :   nsAdoptingCString prefVal =
     123                 :       Preferences::GetCString("browser.hiddenWindowChromeURL");
     124                 :   const char* hiddenWindowURL = prefVal.get() ? prefVal.get() : DEFAULT_HIDDENWINDOW_URL;
     125                 :   mApplicationProvidedHiddenWindow = prefVal.get() ? true : false;
     126                 : #else
     127                 :   static const char hiddenWindowURL[] = DEFAULT_HIDDENWINDOW_URL;
     128               0 :   PRUint32    chromeMask =  nsIWebBrowserChrome::CHROME_ALL;
     129                 : #endif
     130                 : 
     131               0 :   nsCOMPtr<nsIURI> url;
     132               0 :   rv = NS_NewURI(getter_AddRefs(url), hiddenWindowURL);
     133               0 :   NS_ENSURE_SUCCESS(rv, rv);
     134                 : 
     135               0 :   nsRefPtr<nsWebShellWindow> newWindow;
     136                 :   rv = JustCreateTopWindow(nsnull, url,
     137                 :                            chromeMask, initialWidth, initialHeight,
     138               0 :                            true, getter_AddRefs(newWindow));
     139               0 :   NS_ENSURE_SUCCESS(rv, rv);
     140                 : 
     141               0 :   mHiddenWindow.swap(newWindow);
     142                 : 
     143                 :   // RegisterTopLevelWindow(newWindow); -- Mac only
     144                 : 
     145               0 :   return NS_OK;
     146                 : }
     147                 : 
     148                 : NS_IMETHODIMP
     149               0 : nsAppShellService::DestroyHiddenWindow()
     150                 : {
     151               0 :   if (mHiddenWindow) {
     152               0 :     mHiddenWindow->Destroy();
     153                 : 
     154               0 :     mHiddenWindow = nsnull;
     155                 :   }
     156                 : 
     157               0 :   return NS_OK;
     158                 : }
     159                 : 
     160                 : /*
     161                 :  * Create a new top level window and display the given URL within it...
     162                 :  */
     163                 : NS_IMETHODIMP
     164               0 : nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
     165                 :                                         nsIURI *aUrl, 
     166                 :                                         PRUint32 aChromeMask,
     167                 :                                         PRInt32 aInitialWidth,
     168                 :                                         PRInt32 aInitialHeight,
     169                 :                                         nsIXULWindow **aResult)
     170                 : 
     171                 : {
     172                 :   nsresult rv;
     173                 : 
     174               0 :   StartupTimeline::RecordOnce(StartupTimeline::CREATE_TOP_LEVEL_WINDOW);
     175                 : 
     176               0 :   nsWebShellWindow *newWindow = nsnull;
     177                 :   rv = JustCreateTopWindow(aParent, aUrl,
     178                 :                            aChromeMask, aInitialWidth, aInitialHeight,
     179               0 :                            false, &newWindow);  // addrefs
     180                 : 
     181               0 :   *aResult = newWindow; // transfer ref
     182                 : 
     183               0 :   if (NS_SUCCEEDED(rv)) {
     184                 :     // the addref resulting from this is the owning addref for this window
     185               0 :     RegisterTopLevelWindow(*aResult);
     186               0 :     nsCOMPtr<nsIXULWindow> parent;
     187               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT)
     188               0 :       parent = aParent;
     189               0 :     (*aResult)->SetZLevel(CalculateWindowZLevel(parent, aChromeMask));
     190                 :   }
     191                 : 
     192               0 :   return rv;
     193                 : }
     194                 : 
     195                 : PRUint32
     196               0 : nsAppShellService::CalculateWindowZLevel(nsIXULWindow *aParent,
     197                 :                                          PRUint32      aChromeMask)
     198                 : {
     199                 :   PRUint32 zLevel;
     200                 : 
     201               0 :   zLevel = nsIXULWindow::normalZ;
     202               0 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RAISED)
     203               0 :     zLevel = nsIXULWindow::raisedZ;
     204               0 :   else if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_LOWERED)
     205               0 :     zLevel = nsIXULWindow::loweredZ;
     206                 : 
     207                 : #ifdef XP_MACOSX
     208                 :   /* Platforms on which modal windows are always application-modal, not
     209                 :      window-modal (that's just the Mac, right?) want modal windows to
     210                 :      be stacked on top of everyone else.
     211                 : 
     212                 :      On Mac OS X, bind modality to parent window instead of app (ala Mac OS 9)
     213                 :   */
     214                 :   PRUint32 modalDepMask = nsIWebBrowserChrome::CHROME_MODAL |
     215                 :                           nsIWebBrowserChrome::CHROME_DEPENDENT;
     216                 :   if (aParent && (aChromeMask & modalDepMask)) {
     217                 :     aParent->GetZLevel(&zLevel);
     218                 :   }
     219                 : #else
     220                 :   /* Platforms with native support for dependent windows (that's everyone
     221                 :       but pre-Mac OS X, right?) know how to stack dependent windows. On these
     222                 :       platforms, give the dependent window the same level as its parent,
     223                 :       so we won't try to override the normal platform behaviour. */
     224               0 :   if ((aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT) && aParent)
     225               0 :     aParent->GetZLevel(&zLevel);
     226                 : #endif
     227                 : 
     228               0 :   return zLevel;
     229                 : }
     230                 : 
     231                 : #ifdef XP_WIN
     232                 : /*
     233                 :  * Checks to see if any existing window is currently in fullscreen mode.
     234                 :  */
     235                 : static bool
     236                 : CheckForFullscreenWindow()
     237                 : {
     238                 :   nsCOMPtr<nsIWindowMediator> wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     239                 :   if (!wm)
     240                 :     return false;
     241                 : 
     242                 :   nsCOMPtr<nsISimpleEnumerator> windowList;
     243                 :   wm->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowList));
     244                 :   if (!windowList)
     245                 :     return false;
     246                 : 
     247                 :   for (;;) {
     248                 :     bool more = false;
     249                 :     windowList->HasMoreElements(&more);
     250                 :     if (!more)
     251                 :       return false;
     252                 : 
     253                 :     nsCOMPtr<nsISupports> supportsWindow;
     254                 :     windowList->GetNext(getter_AddRefs(supportsWindow));
     255                 :     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supportsWindow));
     256                 :     if (baseWin) {
     257                 :       PRInt32 sizeMode;
     258                 :       nsCOMPtr<nsIWidget> widget;
     259                 :       baseWin->GetMainWidget(getter_AddRefs(widget));
     260                 :       if (widget && NS_SUCCEEDED(widget->GetSizeMode(&sizeMode)) && 
     261                 :           sizeMode == nsSizeMode_Fullscreen) {
     262                 :         return true;
     263                 :       }
     264                 :     }
     265                 :   }
     266                 :   return false;
     267                 : }
     268                 : #endif
     269                 : 
     270                 : /*
     271                 :  * Just do the window-making part of CreateTopLevelWindow
     272                 :  */
     273                 : nsresult
     274               0 : nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
     275                 :                                        nsIURI *aUrl, 
     276                 :                                        PRUint32 aChromeMask,
     277                 :                                        PRInt32 aInitialWidth,
     278                 :                                        PRInt32 aInitialHeight,
     279                 :                                        bool aIsHiddenWindow,
     280                 :                                        nsWebShellWindow **aResult)
     281                 : {
     282               0 :   *aResult = nsnull;
     283               0 :   NS_ENSURE_STATE(!mXPCOMWillShutDown);
     284                 : 
     285               0 :   nsCOMPtr<nsIXULWindow> parent;
     286               0 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT)
     287               0 :     parent = aParent;
     288                 : 
     289               0 :   nsRefPtr<nsWebShellWindow> window = new nsWebShellWindow(aChromeMask);
     290               0 :   NS_ENSURE_TRUE(window, NS_ERROR_OUT_OF_MEMORY);
     291                 : 
     292                 : #ifdef XP_WIN
     293                 :   // If the parent is currently fullscreen, tell the child to ignore persisted
     294                 :   // full screen states. This way new browser windows open on top of fullscreen
     295                 :   // windows normally.
     296                 :   if (window && CheckForFullscreenWindow())
     297                 :     window->IgnoreXULSizeMode(true);
     298                 : #endif
     299                 : 
     300               0 :   nsWidgetInitData widgetInitData;
     301                 : 
     302               0 :   if (aIsHiddenWindow)
     303               0 :     widgetInitData.mWindowType = eWindowType_invisible;
     304                 :   else
     305                 :     widgetInitData.mWindowType = aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG ?
     306               0 :       eWindowType_dialog : eWindowType_toplevel;
     307                 : 
     308               0 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_POPUP)
     309               0 :     widgetInitData.mWindowType = eWindowType_popup;
     310                 : 
     311               0 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_MAC_SUPPRESS_ANIMATION)
     312               0 :     widgetInitData.mIsAnimationSuppressed = true;
     313                 : 
     314                 : #ifdef XP_MACOSX
     315                 :   // Mac OS X sheet support
     316                 :   // Adding CHROME_OPENAS_CHROME to sheetMask makes modal windows opened from
     317                 :   // nsGlobalWindow::ShowModalDialog() be dialogs (not sheets), while modal
     318                 :   // windows opened from nsPromptService::DoDialog() still are sheets.  This
     319                 :   // fixes bmo bug 395465 (see nsCocoaWindow::StandardCreate() and
     320                 :   // nsCocoaWindow::SetModal()).
     321                 :   PRUint32 sheetMask = nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
     322                 :                        nsIWebBrowserChrome::CHROME_MODAL |
     323                 :                        nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
     324                 :   if (parent && ((aChromeMask & sheetMask) == sheetMask))
     325                 :     widgetInitData.mWindowType = eWindowType_sheet;
     326                 : #endif
     327                 : 
     328                 : #if defined(XP_WIN)
     329                 :   if (widgetInitData.mWindowType == eWindowType_toplevel ||
     330                 :       widgetInitData.mWindowType == eWindowType_dialog)
     331                 :     widgetInitData.clipChildren = true;
     332                 : #endif
     333                 : 
     334                 :   // note default chrome overrides other OS chrome settings, but
     335                 :   // not internal chrome
     336               0 :   if (aChromeMask & nsIWebBrowserChrome::CHROME_DEFAULT)
     337               0 :     widgetInitData.mBorderStyle = eBorderStyle_default;
     338               0 :   else if ((aChromeMask & nsIWebBrowserChrome::CHROME_ALL) == nsIWebBrowserChrome::CHROME_ALL)
     339               0 :     widgetInitData.mBorderStyle = eBorderStyle_all;
     340                 :   else {
     341               0 :     widgetInitData.mBorderStyle = eBorderStyle_none; // assumes none == 0x00
     342               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_BORDERS)
     343               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_border);
     344               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_TITLEBAR)
     345               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_title);
     346               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_CLOSE)
     347               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_close);
     348               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) {
     349               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_resizeh);
     350                 :       // only resizable windows get the maximize button (but not dialogs)
     351               0 :       if (!(aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG))
     352               0 :         widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_maximize);
     353                 :     }
     354                 :     // all windows (except dialogs) get minimize buttons and the system menu
     355               0 :     if (!(aChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_DIALOG))
     356               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_minimize | eBorderStyle_menu);
     357                 :     // but anyone can explicitly ask for a minimize button
     358               0 :     if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_MIN) {
     359               0 :       widgetInitData.mBorderStyle = static_cast<enum nsBorderStyle>(widgetInitData.mBorderStyle | eBorderStyle_minimize);
     360                 :     }  
     361                 :   }
     362                 : 
     363               0 :   if (aInitialWidth == nsIAppShellService::SIZE_TO_CONTENT ||
     364                 :       aInitialHeight == nsIAppShellService::SIZE_TO_CONTENT) {
     365               0 :     aInitialWidth = 1;
     366               0 :     aInitialHeight = 1;
     367               0 :     window->SetIntrinsicallySized(true);
     368                 :   }
     369                 : 
     370               0 :   bool center = aChromeMask & nsIWebBrowserChrome::CHROME_CENTER_SCREEN;
     371                 : 
     372                 :   nsCOMPtr<nsIXULChromeRegistry> reg =
     373               0 :     mozilla::services::GetXULChromeRegistryService();
     374               0 :   if (reg) {
     375               0 :     nsCAutoString package;
     376               0 :     package.AssignLiteral("global");
     377               0 :     bool isRTL = false;
     378               0 :     reg->IsLocaleRTL(package, &isRTL);
     379               0 :     widgetInitData.mRTL = isRTL;
     380                 :   }
     381                 : 
     382                 :   nsresult rv = window->Initialize(parent, center ? aParent : nsnull,
     383                 :                                    aUrl, aInitialWidth, aInitialHeight,
     384               0 :                                    aIsHiddenWindow, widgetInitData);
     385                 :       
     386               0 :   NS_ENSURE_SUCCESS(rv, rv);
     387                 : 
     388               0 :   window.swap(*aResult); // transfer reference
     389               0 :   if (parent)
     390               0 :     parent->AddChildWindow(*aResult);
     391                 : 
     392               0 :   if (center)
     393               0 :     rv = (*aResult)->Center(parent, parent ? false : true, false);
     394                 : 
     395               0 :   return rv;
     396                 : }
     397                 : 
     398                 : NS_IMETHODIMP
     399             280 : nsAppShellService::GetHiddenWindow(nsIXULWindow **aWindow)
     400                 : {
     401             280 :   NS_ENSURE_ARG_POINTER(aWindow);
     402                 : 
     403             280 :   *aWindow = mHiddenWindow;
     404             280 :   NS_IF_ADDREF(*aWindow);
     405             280 :   return *aWindow ? NS_OK : NS_ERROR_FAILURE;
     406                 : }
     407                 : 
     408                 : NS_IMETHODIMP
     409               0 : nsAppShellService::GetHiddenDOMWindow(nsIDOMWindow **aWindow)
     410                 : {
     411                 :   nsresult rv;
     412               0 :   nsCOMPtr<nsIDocShell> docShell;
     413               0 :   NS_ENSURE_TRUE(mHiddenWindow, NS_ERROR_FAILURE);
     414                 : 
     415               0 :   rv = mHiddenWindow->GetDocShell(getter_AddRefs(docShell));
     416               0 :   NS_ENSURE_SUCCESS(rv, rv);
     417                 :   
     418               0 :   nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(do_GetInterface(docShell, &rv));
     419               0 :   NS_ENSURE_SUCCESS(rv, rv);
     420                 : 
     421               0 :   *aWindow = hiddenDOMWindow;
     422               0 :   NS_IF_ADDREF(*aWindow);
     423               0 :   return NS_OK;
     424                 : }
     425                 : 
     426                 : NS_IMETHODIMP
     427               0 : nsAppShellService::GetHiddenWindowAndJSContext(nsIDOMWindow **aWindow,
     428                 :                                                JSContext    **aJSContext)
     429                 : {
     430               0 :     nsresult rv = NS_OK;
     431               0 :     if ( aWindow && aJSContext ) {
     432               0 :         *aWindow    = nsnull;
     433               0 :         *aJSContext = nsnull;
     434                 : 
     435               0 :         if ( mHiddenWindow ) {
     436                 :             // Convert hidden window to nsIDOMWindow and extract its JSContext.
     437                 :             do {
     438                 :                 // 1. Get doc for hidden window.
     439               0 :                 nsCOMPtr<nsIDocShell> docShell;
     440               0 :                 rv = mHiddenWindow->GetDocShell(getter_AddRefs(docShell));
     441               0 :                 if (NS_FAILED(rv)) break;
     442                 : 
     443                 :                 // 2. Convert that to an nsIDOMWindow.
     444               0 :                 nsCOMPtr<nsIDOMWindow> hiddenDOMWindow(do_GetInterface(docShell));
     445               0 :                 if(!hiddenDOMWindow) break;
     446                 : 
     447                 :                 // 3. Get script global object for the window.
     448               0 :                 nsCOMPtr<nsIScriptGlobalObject> sgo;
     449               0 :                 sgo = do_QueryInterface( hiddenDOMWindow );
     450               0 :                 if (!sgo) { rv = NS_ERROR_FAILURE; break; }
     451                 : 
     452                 :                 // 4. Get script context from that.
     453               0 :                 nsIScriptContext *scriptContext = sgo->GetContext();
     454               0 :                 if (!scriptContext) { rv = NS_ERROR_FAILURE; break; }
     455                 : 
     456                 :                 // 5. Get JSContext from the script context.
     457               0 :                 JSContext *jsContext = scriptContext->GetNativeContext();
     458               0 :                 if (!jsContext) { rv = NS_ERROR_FAILURE; break; }
     459                 : 
     460                 :                 // Now, give results to caller.
     461               0 :                 *aWindow    = hiddenDOMWindow.get();
     462               0 :                 NS_IF_ADDREF( *aWindow );
     463               0 :                 *aJSContext = jsContext;
     464                 :             } while (0);
     465                 :         } else {
     466               0 :             rv = NS_ERROR_FAILURE;
     467               0 :         }
     468                 :     } else {
     469               0 :         rv = NS_ERROR_NULL_POINTER;
     470                 :     }
     471               0 :     return rv;
     472                 : }
     473                 : 
     474                 : NS_IMETHODIMP
     475               0 : nsAppShellService::GetApplicationProvidedHiddenWindow(bool* aAPHW)
     476                 : {
     477               0 :     *aAPHW = mApplicationProvidedHiddenWindow;
     478               0 :     return NS_OK;
     479                 : }
     480                 : 
     481                 : /*
     482                 :  * Register a new top level window (created elsewhere)
     483                 :  */
     484                 : NS_IMETHODIMP
     485               0 : nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
     486                 : {
     487                 :   // tell the window mediator about the new window
     488                 :   nsCOMPtr<nsIWindowMediator> mediator
     489               0 :     ( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
     490               0 :   NS_ASSERTION(mediator, "Couldn't get window mediator.");
     491                 : 
     492               0 :   if (mediator)
     493               0 :     mediator->RegisterWindow(aWindow);
     494                 : 
     495                 :   // tell the window watcher about the new window
     496               0 :   nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
     497               0 :   NS_ASSERTION(wwatcher, "No windowwatcher?");
     498               0 :   if (wwatcher) {
     499               0 :     nsCOMPtr<nsIDocShell> docShell;
     500               0 :     aWindow->GetDocShell(getter_AddRefs(docShell));
     501               0 :     NS_ASSERTION(docShell, "Window has no docshell");
     502               0 :     if (docShell) {
     503               0 :       nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docShell));
     504               0 :       NS_ASSERTION(domWindow, "Couldn't get DOM window.");
     505               0 :       if (domWindow)
     506               0 :         wwatcher->AddWindow(domWindow, 0);
     507                 :     }
     508                 :   }
     509                 : 
     510                 :   // an ongoing attempt to quit is stopped by a newly opened window
     511                 :   nsCOMPtr<nsIObserverService> obssvc =
     512               0 :     do_GetService("@mozilla.org/observer-service;1");
     513               0 :   NS_ASSERTION(obssvc, "Couldn't get observer service.");
     514                 : 
     515               0 :   if (obssvc)
     516               0 :     obssvc->NotifyObservers(aWindow, "xul-window-registered", nsnull);
     517                 : 
     518               0 :   return NS_OK;
     519                 : }
     520                 : 
     521                 : 
     522                 : NS_IMETHODIMP
     523               0 : nsAppShellService::UnregisterTopLevelWindow(nsIXULWindow* aWindow)
     524                 : {
     525               0 :   if (mXPCOMShuttingDown) {
     526                 :     /* return an error code in order to:
     527                 :        - avoid doing anything with other member variables while we are in
     528                 :          the destructor
     529                 :        - notify the caller not to release the AppShellService after
     530                 :          unregistering the window
     531                 :          (we don't want to be deleted twice consecutively to
     532                 :          mHiddenWindow->Destroy() in our destructor)
     533                 :     */
     534               0 :     return NS_ERROR_FAILURE;
     535                 :   }
     536                 :   
     537               0 :   NS_ENSURE_ARG_POINTER(aWindow);
     538                 : 
     539               0 :   if (aWindow == mHiddenWindow) {
     540                 :     // CreateHiddenWindow() does not register the window, so we're done.
     541               0 :     return NS_OK;
     542                 :   }
     543                 : 
     544                 :   // tell the window mediator
     545                 :   nsCOMPtr<nsIWindowMediator> mediator
     546               0 :     ( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
     547               0 :   NS_ASSERTION(mediator, "Couldn't get window mediator. Doing xpcom shutdown?");
     548                 : 
     549               0 :   if (mediator)
     550               0 :     mediator->UnregisterWindow(aWindow);
     551                 :         
     552                 :   // tell the window watcher
     553               0 :   nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
     554               0 :   NS_ASSERTION(wwatcher, "Couldn't get windowwatcher, doing xpcom shutdown?");
     555               0 :   if (wwatcher) {
     556               0 :     nsCOMPtr<nsIDocShell> docShell;
     557               0 :     aWindow->GetDocShell(getter_AddRefs(docShell));
     558               0 :     if (docShell) {
     559               0 :       nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docShell));
     560               0 :       if (domWindow)
     561               0 :         wwatcher->RemoveWindow(domWindow);
     562                 :     }
     563                 :   }
     564                 : 
     565               0 :   return NS_OK;
     566                 : }
     567                 : 
     568                 : 
     569                 : NS_IMETHODIMP
     570             200 : nsAppShellService::Observe(nsISupports* aSubject, const char *aTopic,
     571                 :                            const PRUnichar *aData)
     572                 : {
     573             200 :   if (!strcmp(aTopic, "xpcom-will-shutdown")) {
     574             100 :     mXPCOMWillShutDown = true;
     575             100 :   } else if (!strcmp(aTopic, "xpcom-shutdown")) {
     576             100 :     mXPCOMShuttingDown = true;
     577             100 :     if (mHiddenWindow) {
     578               0 :       mHiddenWindow->Destroy();
     579                 :     }
     580                 :   } else {
     581               0 :     NS_ERROR("Unexpected observer topic!");
     582                 :   }
     583                 : 
     584             200 :   return NS_OK;
     585                 : }

Generated by: LCOV version 1.7