LCOV - code coverage report
Current view: directory - dom/base - nsGlobalWindow.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 4610 35 0.8 %
Date: 2012-07-07 Functions: 427 7 1.6 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim: set sw=2 ts=2 et tw=78: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is mozilla.org code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Netscape Communications Corporation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Travis Bogard <travis@netscape.com>
      25                 :  *   Brendan Eich <brendan@mozilla.org>
      26                 :  *   David Hyatt (hyatt@netscape.com)
      27                 :  *   Dan Rosen <dr@netscape.com>
      28                 :  *   Vidur Apparao <vidur@netscape.com>
      29                 :  *   Johnny Stenback <jst@netscape.com>
      30                 :  *   Mark Hammond <mhammond@skippinet.com.au>
      31                 :  *   Ryan Jones <sciguyryan@gmail.com>
      32                 :  *   Jeff Walden <jwalden+code@mit.edu>
      33                 :  *   Ben Bucksch <ben.bucksch  beonex.com>
      34                 :  *   Emanuele Costa <emanuele.costa@gmail.com>
      35                 :  *
      36                 :  * Alternatively, the contents of this file may be used under the terms of
      37                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      38                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      39                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      40                 :  * of those above. If you wish to allow use of your version of this file only
      41                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      42                 :  * use your version of this file under the terms of the MPL, indicate your
      43                 :  * decision by deleting the provisions above and replace them with the notice
      44                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      45                 :  * the provisions above, a recipient may use your version of this file under
      46                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      47                 :  *
      48                 :  * ***** END LICENSE BLOCK ***** */
      49                 : 
      50                 : #include "base/basictypes.h"
      51                 : 
      52                 : /* This must occur *after* base/basictypes.h to avoid typedefs conflicts. */
      53                 : #include "mozilla/Util.h"
      54                 : 
      55                 : // Local Includes
      56                 : #include "nsGlobalWindow.h"
      57                 : #include "Navigator.h"
      58                 : #include "nsScreen.h"
      59                 : #include "nsHistory.h"
      60                 : #include "nsPerformance.h"
      61                 : #include "nsDOMNavigationTiming.h"
      62                 : #include "nsBarProps.h"
      63                 : #include "nsDOMStorage.h"
      64                 : #include "nsDOMOfflineResourceList.h"
      65                 : #include "nsDOMError.h"
      66                 : 
      67                 : // Helper Classes
      68                 : #include "nsXPIDLString.h"
      69                 : #include "nsJSUtils.h"
      70                 : #include "prmem.h"
      71                 : #include "jsapi.h"              // for JSAutoRequest
      72                 : #include "jsdbgapi.h"           // for JS_ClearWatchPointsForObject
      73                 : #include "jsfriendapi.h"        // for JS_GetGlobalForFrame
      74                 : #include "nsReadableUtils.h"
      75                 : #include "nsDOMClassInfo.h"
      76                 : #include "nsJSEnvironment.h"
      77                 : #include "nsCharSeparatedTokenizer.h" // for Accept-Language parsing
      78                 : #include "nsUnicharUtils.h"
      79                 : #include "mozilla/Preferences.h"
      80                 : 
      81                 : // Other Classes
      82                 : #include "nsEventListenerManager.h"
      83                 : #include "nsEscape.h"
      84                 : #include "nsStyleCoord.h"
      85                 : #include "nsMimeTypeArray.h"
      86                 : #include "nsNetUtil.h"
      87                 : #include "nsICachingChannel.h"
      88                 : #include "nsPluginArray.h"
      89                 : #include "nsIPluginHost.h"
      90                 : #include "nsPluginHost.h"
      91                 : #include "nsIPluginInstanceOwner.h"
      92                 : #include "nsGeolocation.h"
      93                 : #include "nsDesktopNotification.h"
      94                 : #include "nsContentCID.h"
      95                 : #include "nsLayoutStatics.h"
      96                 : #include "nsCycleCollector.h"
      97                 : #include "nsCCUncollectableMarker.h"
      98                 : #include "nsAutoJSValHolder.h"
      99                 : #include "nsDOMMediaQueryList.h"
     100                 : #include "mozilla/dom/workers/Workers.h"
     101                 : 
     102                 : // Interfaces Needed
     103                 : #include "nsIFrame.h"
     104                 : #include "nsCanvasFrame.h"
     105                 : #include "nsIWidget.h"
     106                 : #include "nsIBaseWindow.h"
     107                 : #include "nsDeviceMotion.h"
     108                 : #include "nsIContent.h"
     109                 : #include "nsIContentViewerEdit.h"
     110                 : #include "nsIDocShell.h"
     111                 : #include "nsIDocShellLoadInfo.h"
     112                 : #include "nsIDocShellTreeItem.h"
     113                 : #include "nsIDocShellTreeNode.h"
     114                 : #include "nsIEditorDocShell.h"
     115                 : #include "nsIDocCharset.h"
     116                 : #include "nsIDocument.h"
     117                 : #include "nsIHTMLDocument.h"
     118                 : #include "nsIDOMHTMLDocument.h"
     119                 : #include "nsIDOMHTMLElement.h"
     120                 : #ifndef MOZ_DISABLE_DOMCRYPTO
     121                 : #include "nsIDOMCrypto.h"
     122                 : #endif
     123                 : #include "nsIDOMDocument.h"
     124                 : #include "nsIDOMElement.h"
     125                 : #include "nsIDOMEvent.h"
     126                 : #include "nsIDOMHTMLAnchorElement.h"
     127                 : #include "nsIDOMKeyEvent.h"
     128                 : #include "nsIDOMMessageEvent.h"
     129                 : #include "nsIDOMPopupBlockedEvent.h"
     130                 : #include "nsIDOMPopStateEvent.h"
     131                 : #include "nsIDOMHashChangeEvent.h"
     132                 : #include "nsIDOMOfflineResourceList.h"
     133                 : #include "nsIDOMGeoGeolocation.h"
     134                 : #include "nsIDOMDesktopNotification.h"
     135                 : #include "nsPIDOMStorage.h"
     136                 : #include "nsDOMString.h"
     137                 : #include "nsIEmbeddingSiteWindow2.h"
     138                 : #include "nsThreadUtils.h"
     139                 : #include "nsEventStateManager.h"
     140                 : #include "nsIHttpProtocolHandler.h"
     141                 : #include "nsIJSContextStack.h"
     142                 : #include "nsIJSRuntimeService.h"
     143                 : #include "nsIMarkupDocumentViewer.h"
     144                 : #include "nsIPrefBranch.h"
     145                 : #include "nsIPresShell.h"
     146                 : #include "nsIPrivateDOMEvent.h"
     147                 : #include "nsIProgrammingLanguage.h"
     148                 : #include "nsIServiceManager.h"
     149                 : #include "nsIScriptGlobalObjectOwner.h"
     150                 : #include "nsIScriptSecurityManager.h"
     151                 : #include "nsIScrollableFrame.h"
     152                 : #include "nsIView.h"
     153                 : #include "nsIViewManager.h"
     154                 : #include "nsISelectionController.h"
     155                 : #include "nsISelection.h"
     156                 : #include "nsIPrompt.h"
     157                 : #include "nsIPromptService.h"
     158                 : #include "nsIPromptFactory.h"
     159                 : #include "nsIWritablePropertyBag2.h"
     160                 : #include "nsIWebNavigation.h"
     161                 : #include "nsIWebBrowser.h"
     162                 : #include "nsIWebBrowserChrome.h"
     163                 : #include "nsIWebBrowserFind.h"  // For window.find()
     164                 : #include "nsIWebContentHandlerRegistrar.h"
     165                 : #include "nsIWindowMediator.h"  // For window.find()
     166                 : #include "nsComputedDOMStyle.h"
     167                 : #include "nsIEntropyCollector.h"
     168                 : #include "nsDOMCID.h"
     169                 : #include "nsDOMError.h"
     170                 : #include "nsDOMWindowUtils.h"
     171                 : #include "nsIWindowWatcher.h"
     172                 : #include "nsPIWindowWatcher.h"
     173                 : #include "nsIContentViewer.h"
     174                 : #include "nsIJSNativeInitializer.h"
     175                 : #include "nsIScriptError.h"
     176                 : #include "nsIConsoleService.h"
     177                 : #include "nsIControllers.h"
     178                 : #include "nsIControllerContext.h"
     179                 : #include "nsGlobalWindowCommands.h"
     180                 : #include "nsAutoPtr.h"
     181                 : #include "nsContentUtils.h"
     182                 : #include "nsCSSProps.h"
     183                 : #include "nsBlobProtocolHandler.h"
     184                 : #include "nsIDOMFile.h"
     185                 : #include "nsIDOMFileList.h"
     186                 : #include "nsIURIFixup.h"
     187                 : #include "mozilla/FunctionTimer.h"
     188                 : #include "nsCDefaultURIFixup.h"
     189                 : #include "nsEventDispatcher.h"
     190                 : #include "nsIObserverService.h"
     191                 : #include "nsIXULAppInfo.h"
     192                 : #include "nsNetUtil.h"
     193                 : #include "nsFocusManager.h"
     194                 : #include "nsIXULWindow.h"
     195                 : #include "nsEventStateManager.h"
     196                 : #include "nsITimedChannel.h"
     197                 : #include "nsICookiePermission.h"
     198                 : #include "nsServiceManagerUtils.h"
     199                 : #ifdef MOZ_XUL
     200                 : #include "nsXULPopupManager.h"
     201                 : #include "nsIDOMXULControlElement.h"
     202                 : #include "nsMenuPopupFrame.h"
     203                 : #endif
     204                 : 
     205                 : #include "xpcprivate.h"
     206                 : 
     207                 : #ifdef NS_PRINTING
     208                 : #include "nsIPrintSettings.h"
     209                 : #include "nsIPrintSettingsService.h"
     210                 : #include "nsIWebBrowserPrint.h"
     211                 : #endif
     212                 : 
     213                 : #include "nsWindowRoot.h"
     214                 : #include "nsNetCID.h"
     215                 : #include "nsIArray.h"
     216                 : #include "nsIScriptRuntime.h"
     217                 : 
     218                 : // XXX An unfortunate dependency exists here (two XUL files).
     219                 : #include "nsIDOMXULDocument.h"
     220                 : #include "nsIDOMXULCommandDispatcher.h"
     221                 : 
     222                 : #include "nsBindingManager.h"
     223                 : #include "nsIXBLService.h"
     224                 : 
     225                 : // used for popup blocking, needs to be converted to something
     226                 : // belonging to the back-end like nsIContentPolicy
     227                 : #include "nsIPopupWindowManager.h"
     228                 : 
     229                 : #include "nsIDragService.h"
     230                 : #include "mozilla/dom/Element.h"
     231                 : #include "nsFrameLoader.h"
     232                 : #include "nsISupportsPrimitives.h"
     233                 : #include "nsXPCOMCID.h"
     234                 : 
     235                 : #include "mozilla/FunctionTimer.h"
     236                 : #include "mozIThirdPartyUtil.h"
     237                 : 
     238                 : #ifdef MOZ_LOGGING
     239                 : // so we can get logging even in release builds
     240                 : #define FORCE_PR_LOG 1
     241                 : #endif
     242                 : #include "prlog.h"
     243                 : #include "prenv.h"
     244                 : 
     245                 : #include "mozilla/dom/indexedDB/IDBFactory.h"
     246                 : #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
     247                 : 
     248                 : #include "mozilla/dom/StructuredCloneTags.h"
     249                 : 
     250                 : #include "nsRefreshDriver.h"
     251                 : #include "mozAutoDocUpdate.h"
     252                 : 
     253                 : #include "mozilla/Telemetry.h"
     254                 : #include "nsLocation.h"
     255                 : #include "nsWrapperCacheInlines.h"
     256                 : #include "nsDOMEventTargetHelper.h"
     257                 : 
     258                 : #ifdef ANDROID
     259                 : #include <android/log.h>
     260                 : #endif
     261                 : 
     262                 : #ifdef PR_LOGGING
     263                 : static PRLogModuleInfo* gDOMLeakPRLog;
     264                 : #endif
     265                 : 
     266                 : static const char kStorageEnabled[] = "dom.storage.enabled";
     267                 : 
     268                 : using namespace mozilla;
     269                 : using namespace mozilla::dom;
     270                 : using mozilla::TimeStamp;
     271                 : using mozilla::TimeDuration;
     272                 : 
     273                 : nsIDOMStorageList *nsGlobalWindow::sGlobalStorageList  = nsnull;
     274                 : nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sWindowsById = nsnull;
     275                 : bool nsGlobalWindow::sWarnedAboutWindowInternal = false;
     276                 : 
     277                 : static nsIEntropyCollector *gEntropyCollector          = nsnull;
     278                 : static PRInt32              gRefCnt                    = 0;
     279                 : static PRInt32              gOpenPopupSpamCount        = 0;
     280                 : static PopupControlState    gPopupControlState         = openAbused;
     281                 : static PRInt32              gRunningTimeoutDepth       = 0;
     282                 : static bool                 gMouseDown                 = false;
     283                 : static bool                 gDragServiceDisabled       = false;
     284                 : static FILE                *gDumpFile                  = nsnull;
     285                 : static PRUint64             gNextWindowID              = 0;
     286                 : static PRUint32             gSerialCounter             = 0;
     287                 : static PRUint32             gTimeoutsRecentlySet       = 0;
     288            1464 : static TimeStamp            gLastRecordedRecentTimeouts;
     289                 : #define STATISTICS_INTERVAL (30 * PR_MSEC_PER_SEC)
     290                 : 
     291                 : #ifdef DEBUG_jst
     292                 : PRInt32 gTimeoutCnt                                    = 0;
     293                 : #endif
     294                 : 
     295                 : #if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
     296                 : static bool                 gDOMWindowDumpEnabled      = false;
     297                 : #endif
     298                 : 
     299                 : #if defined(DEBUG_bryner) || defined(DEBUG_chb)
     300                 : #define DEBUG_PAGE_CACHE
     301                 : #endif
     302                 : 
     303                 : #define DOM_TOUCH_LISTENER_ADDED "dom-touch-listener-added"
     304                 : 
     305                 : // The default shortest interval/timeout we permit
     306                 : #define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
     307                 : #define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms
     308                 : static PRInt32 gMinTimeoutValue;
     309                 : static PRInt32 gMinBackgroundTimeoutValue;
     310                 : inline PRInt32
     311               0 : nsGlobalWindow::DOMMinTimeoutValue() const {
     312               0 :   bool isBackground = !mOuterWindow || mOuterWindow->IsBackground();
     313                 :   return
     314               0 :     NS_MAX(isBackground ? gMinBackgroundTimeoutValue : gMinTimeoutValue, 0);
     315                 : }
     316                 : 
     317                 : // The number of nested timeouts before we start clamping. HTML5 says 1, WebKit
     318                 : // uses 5.
     319                 : #define DOM_CLAMP_TIMEOUT_NESTING_LEVEL 5
     320                 : 
     321                 : // The longest interval (as PRIntervalTime) we permit, or that our
     322                 : // timer code can handle, really. See DELAY_INTERVAL_LIMIT in
     323                 : // nsTimerImpl.h for details.
     324                 : #define DOM_MAX_TIMEOUT_VALUE    DELAY_INTERVAL_LIMIT
     325                 : 
     326                 : #define FORWARD_TO_OUTER(method, args, err_rval)                              \
     327                 :   PR_BEGIN_MACRO                                                              \
     328                 :   if (IsInnerWindow()) {                                                      \
     329                 :     nsGlobalWindow *outer = GetOuterWindowInternal();                         \
     330                 :     if (!outer) {                                                             \
     331                 :       NS_WARNING("No outer window available!");                               \
     332                 :       return err_rval;                                                        \
     333                 :     }                                                                         \
     334                 :     return outer->method args;                                                \
     335                 :   }                                                                           \
     336                 :   PR_END_MACRO
     337                 : 
     338                 : #define FORWARD_TO_OUTER_VOID(method, args)                                   \
     339                 :   PR_BEGIN_MACRO                                                              \
     340                 :   if (IsInnerWindow()) {                                                      \
     341                 :     nsGlobalWindow *outer = GetOuterWindowInternal();                         \
     342                 :     if (!outer) {                                                             \
     343                 :       NS_WARNING("No outer window available!");                               \
     344                 :       return;                                                                 \
     345                 :     }                                                                         \
     346                 :     outer->method args;                                                       \
     347                 :     return;                                                                   \
     348                 :   }                                                                           \
     349                 :   PR_END_MACRO
     350                 : 
     351                 : #define FORWARD_TO_OUTER_CHROME(method, args, err_rval)                       \
     352                 :   PR_BEGIN_MACRO                                                              \
     353                 :   if (IsInnerWindow()) {                                                      \
     354                 :     nsGlobalWindow *outer = GetOuterWindowInternal();                         \
     355                 :     if (!outer) {                                                             \
     356                 :       NS_WARNING("No outer window available!");                               \
     357                 :       return err_rval;                                                        \
     358                 :     }                                                                         \
     359                 :     return ((nsGlobalChromeWindow *)outer)->method args;                      \
     360                 :   }                                                                           \
     361                 :   PR_END_MACRO
     362                 : 
     363                 : #define FORWARD_TO_INNER_CHROME(method, args, err_rval)                       \
     364                 :   PR_BEGIN_MACRO                                                              \
     365                 :   if (IsOuterWindow()) {                                                      \
     366                 :     if (!mInnerWindow) {                                                      \
     367                 :       NS_WARNING("No inner window available!");                               \
     368                 :       return err_rval;                                                        \
     369                 :     }                                                                         \
     370                 :     return ((nsGlobalChromeWindow *)mInnerWindow)->method args;               \
     371                 :   }                                                                           \
     372                 :   PR_END_MACRO
     373                 : 
     374                 : #define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
     375                 :   PR_BEGIN_MACRO                                                              \
     376                 :   if (IsInnerWindow()) {                                                      \
     377                 :     nsGlobalWindow *outer = GetOuterWindowInternal();                         \
     378                 :     if (!outer) {                                                             \
     379                 :       NS_WARNING("No outer window available!");                               \
     380                 :       return err_rval;                                                        \
     381                 :     }                                                                         \
     382                 :     return ((nsGlobalModalWindow *)outer)->method args;                       \
     383                 :   }                                                                           \
     384                 :   PR_END_MACRO
     385                 : 
     386                 : #define FORWARD_TO_INNER(method, args, err_rval)                              \
     387                 :   PR_BEGIN_MACRO                                                              \
     388                 :   if (IsOuterWindow()) {                                                      \
     389                 :     if (!mInnerWindow) {                                                      \
     390                 :       NS_WARNING("No inner window available!");                               \
     391                 :       return err_rval;                                                        \
     392                 :     }                                                                         \
     393                 :     return GetCurrentInnerWindowInternal()->method args;                      \
     394                 :   }                                                                           \
     395                 :   PR_END_MACRO
     396                 : 
     397                 : #define FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(method, args, err_rval)         \
     398                 :   PR_BEGIN_MACRO                                                              \
     399                 :   if (IsOuterWindow()) {                                                      \
     400                 :     if (!mInnerWindow) {                                                      \
     401                 :       NS_WARNING("No inner window available!");                               \
     402                 :       return err_rval;                                                        \
     403                 :     }                                                                         \
     404                 :     return ((nsGlobalModalWindow*)GetCurrentInnerWindowInternal())->method args; \
     405                 :   }                                                                           \
     406                 :   PR_END_MACRO
     407                 : 
     408                 : #define FORWARD_TO_INNER_VOID(method, args)                                   \
     409                 :   PR_BEGIN_MACRO                                                              \
     410                 :   if (IsOuterWindow()) {                                                      \
     411                 :     if (!mInnerWindow) {                                                      \
     412                 :       NS_WARNING("No inner window available!");                               \
     413                 :       return;                                                                 \
     414                 :     }                                                                         \
     415                 :     GetCurrentInnerWindowInternal()->method args;                             \
     416                 :     return;                                                                   \
     417                 :   }                                                                           \
     418                 :   PR_END_MACRO
     419                 : 
     420                 : // Same as FORWARD_TO_INNER, but this will create a fresh inner if an
     421                 : // inner doesn't already exists.
     422                 : #define FORWARD_TO_INNER_CREATE(method, args, err_rval)                       \
     423                 :   PR_BEGIN_MACRO                                                              \
     424                 :   if (IsOuterWindow()) {                                                      \
     425                 :     if (!mInnerWindow) {                                                      \
     426                 :       if (mIsClosed) {                                                        \
     427                 :         return err_rval;                                                      \
     428                 :       }                                                                       \
     429                 :       nsCOMPtr<nsIDOMDocument> doc;                                           \
     430                 :       nsresult fwdic_nr = GetDocument(getter_AddRefs(doc));                   \
     431                 :       NS_ENSURE_SUCCESS(fwdic_nr, err_rval);                                  \
     432                 :       if (!mInnerWindow) {                                                    \
     433                 :         return err_rval;                                                      \
     434                 :       }                                                                       \
     435                 :     }                                                                         \
     436                 :     return GetCurrentInnerWindowInternal()->method args;                      \
     437                 :   }                                                                           \
     438                 :   PR_END_MACRO
     439                 : 
     440                 : // CIDs
     441                 : static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
     442                 : 
     443                 : static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
     444                 : #ifndef MOZ_DISABLE_DOMCRYPTO
     445                 : static const char kCryptoContractID[] = NS_CRYPTO_CONTRACTID;
     446                 : static const char kPkcs11ContractID[] = NS_PKCS11_CONTRACTID;
     447                 : #endif
     448                 : static const char sPopStatePrefStr[] = "browser.history.allowPopState";
     449                 : 
     450                 : class nsDummyJavaPluginOwner : public nsIPluginInstanceOwner
     451               0 : {
     452                 : public:
     453               0 :   nsDummyJavaPluginOwner(nsIDocument *aDocument)
     454               0 :     : mDocument(aDocument)
     455                 :   {
     456               0 :   }
     457                 : 
     458                 :   void Destroy();
     459                 : 
     460               0 :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     461                 :   NS_DECL_NSIPLUGININSTANCEOWNER
     462                 : 
     463                 :   NS_IMETHOD GetURL(const char *aURL, const char *aTarget,
     464                 :                     nsIInputStream *aPostStream,
     465                 :                     void *aHeadersData, PRUint32 aHeadersDataLen);
     466                 :   NS_IMETHOD ShowStatus(const PRUnichar *aStatusMsg);
     467                 :   NPError ShowNativeContextMenu(NPMenu* menu, void* event);
     468                 :   NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
     469                 :                       double *destX, double *destY, NPCoordinateSpace destSpace);
     470                 :   void SendIdleEvent();
     471                 :   
     472               0 :   NPError InitAsyncSurface(NPSize *size, NPImageFormat format,
     473                 :                            void *initData, NPAsyncSurface *surface)
     474               0 :   { return NPERR_GENERIC_ERROR; }
     475                 : 
     476               0 :   NPError FinalizeAsyncSurface(NPAsyncSurface *surface) { return NPERR_GENERIC_ERROR; }
     477               0 :   void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) { return; }
     478                 : 
     479            1464 :   NS_DECL_CYCLE_COLLECTION_CLASS(nsDummyJavaPluginOwner)
     480                 : 
     481                 : private:
     482                 :   nsRefPtr<nsNPAPIPluginInstance> mInstance;
     483                 :   nsCOMPtr<nsIDocument> mDocument;
     484                 : };
     485                 : 
     486            1464 : NS_IMPL_CYCLE_COLLECTION_2(nsDummyJavaPluginOwner, mDocument, mInstance)
     487                 : 
     488                 : // QueryInterface implementation for nsDummyJavaPluginOwner
     489               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDummyJavaPluginOwner)
     490               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     491               0 :   NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner)
     492               0 : NS_INTERFACE_MAP_END
     493                 : 
     494               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDummyJavaPluginOwner)
     495               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDummyJavaPluginOwner)
     496                 : 
     497                 : 
     498                 : void
     499               0 : nsDummyJavaPluginOwner::Destroy()
     500                 : {
     501                 :   // If we have a plugin instance, stop it and destroy it now.
     502               0 :   if (mInstance) {
     503               0 :     mInstance->Stop();
     504               0 :     mInstance->InvalidateOwner();
     505               0 :     mInstance = nsnull;
     506                 :   }
     507                 : 
     508               0 :   mDocument = nsnull;
     509               0 : }
     510                 : 
     511                 : NS_IMETHODIMP
     512               0 : nsDummyJavaPluginOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
     513                 : {
     514                 :   // If we're going to null out mInstance after use, be sure to call
     515                 :   // mInstance->InvalidateOwner() here, since it now won't be called
     516                 :   // from nsDummyJavaPluginOwner::Destroy().
     517               0 :   if (mInstance && !aInstance)
     518               0 :     mInstance->InvalidateOwner();
     519                 : 
     520               0 :   mInstance = aInstance;
     521                 : 
     522               0 :   return NS_OK;
     523                 : }
     524                 : 
     525                 : NS_IMETHODIMP
     526               0 : nsDummyJavaPluginOwner::GetInstance(nsNPAPIPluginInstance **aInstance)
     527                 : {
     528               0 :   *aInstance = mInstance;
     529               0 :   NS_IF_ADDREF(*aInstance);
     530                 : 
     531               0 :   return NS_OK;
     532                 : }
     533                 : 
     534                 : NS_IMETHODIMP
     535               0 : nsDummyJavaPluginOwner::GetWindow(NPWindow *&aWindow)
     536                 : {
     537               0 :   aWindow = nsnull;
     538                 : 
     539               0 :   return NS_OK;
     540                 : }
     541                 : 
     542                 : NS_IMETHODIMP
     543               0 : nsDummyJavaPluginOwner::CallSetWindow()
     544                 : {
     545               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     546                 : }
     547                 : 
     548                 : NS_IMETHODIMP
     549               0 : nsDummyJavaPluginOwner::GetMode(PRInt32 *aMode)
     550                 : {
     551                 :   // This is wrong, but there's no better alternative.
     552               0 :   *aMode = NP_EMBED;
     553                 : 
     554               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     555                 : }
     556                 : 
     557                 : NS_IMETHODIMP
     558               0 : nsDummyJavaPluginOwner::CreateWidget(void)
     559                 : {
     560               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     561                 : }
     562                 : 
     563                 : NS_IMETHODIMP
     564               0 : nsDummyJavaPluginOwner::GetURL(const char *aURL, const char *aTarget,
     565                 :                                nsIInputStream *aPostStream,
     566                 :                                void *aHeadersData, PRUint32 aHeadersDataLen)
     567                 : {
     568               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     569                 : }
     570                 : 
     571                 : NS_IMETHODIMP
     572               0 : nsDummyJavaPluginOwner::ShowStatus(const char *aStatusMsg)
     573                 : {
     574               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     575                 : }
     576                 : 
     577                 : NS_IMETHODIMP
     578               0 : nsDummyJavaPluginOwner::ShowStatus(const PRUnichar *aStatusMsg)
     579                 : {
     580               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     581                 : }
     582                 : 
     583                 : NPError
     584               0 : nsDummyJavaPluginOwner::ShowNativeContextMenu(NPMenu* menu, void* event)
     585                 : {
     586               0 :   return NPERR_GENERIC_ERROR;
     587                 : }
     588                 : 
     589                 : NPBool
     590               0 : nsDummyJavaPluginOwner::ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
     591                 :                                      double *destX, double *destY, NPCoordinateSpace destSpace)
     592                 : {
     593               0 :   return false;
     594                 : }
     595                 : 
     596                 : NS_IMETHODIMP
     597               0 : nsDummyJavaPluginOwner::GetDocument(nsIDocument **aDocument)
     598                 : {
     599               0 :   NS_IF_ADDREF(*aDocument = mDocument);
     600                 : 
     601               0 :   return NS_OK;
     602                 : }
     603                 : 
     604                 : NS_IMETHODIMP
     605               0 : nsDummyJavaPluginOwner::InvalidateRect(NPRect *invalidRect)
     606                 : {
     607               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     608                 : }
     609                 : 
     610                 : NS_IMETHODIMP
     611               0 : nsDummyJavaPluginOwner::InvalidateRegion(NPRegion invalidRegion)
     612                 : {
     613               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     614                 : }
     615                 : 
     616                 : NS_IMETHODIMP
     617               0 : nsDummyJavaPluginOwner::RedrawPlugin()
     618                 : {
     619               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     620                 : }
     621                 : 
     622                 : NS_IMETHODIMP
     623               0 : nsDummyJavaPluginOwner::GetNetscapeWindow(void *value)
     624                 : {
     625               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     626                 : }
     627                 : 
     628                 : NS_IMETHODIMP
     629               0 : nsDummyJavaPluginOwner::SetEventModel(PRInt32 eventModel)
     630                 : {
     631               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     632                 : }
     633                 : 
     634                 : void
     635               0 : nsDummyJavaPluginOwner::SendIdleEvent()
     636                 : {
     637               0 : }
     638                 : 
     639                 : /**
     640                 :  * An object implementing the window.URL property.
     641                 :  */
     642                 : class nsDOMMozURLProperty : public nsIDOMMozURLProperty
     643                 : {
     644                 : public:
     645               0 :   nsDOMMozURLProperty(nsGlobalWindow* aWindow)
     646               0 :     : mWindow(aWindow)
     647                 :   {
     648               0 :   }
     649                 : 
     650                 :   NS_DECL_ISUPPORTS
     651                 :   NS_DECL_NSIDOMMOZURLPROPERTY
     652                 : 
     653               0 :   void ClearWindowReference() {
     654               0 :     mWindow = nsnull;
     655               0 :   }
     656                 : private:
     657                 :   nsGlobalWindow* mWindow;
     658                 : };
     659                 : 
     660                 : DOMCI_DATA(MozURLProperty, nsDOMMozURLProperty)
     661               0 : NS_IMPL_ADDREF(nsDOMMozURLProperty)
     662               0 : NS_IMPL_RELEASE(nsDOMMozURLProperty)
     663               0 : NS_INTERFACE_MAP_BEGIN(nsDOMMozURLProperty)
     664               0 :     NS_INTERFACE_MAP_ENTRY(nsIDOMMozURLProperty)
     665               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozURLProperty)
     666               0 :     NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozURLProperty)
     667               0 : NS_INTERFACE_MAP_END
     668                 : 
     669                 : NS_IMETHODIMP
     670               0 : nsDOMMozURLProperty::CreateObjectURL(nsIDOMBlob* aBlob, nsAString& aURL)
     671                 : {
     672               0 :   NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(),
     673                 :                   "Should be inner window");
     674                 : 
     675               0 :   NS_ENSURE_STATE(mWindow && mWindow->mDoc);
     676               0 :   NS_ENSURE_ARG_POINTER(aBlob);
     677                 : 
     678               0 :   nsIDocument* doc = mWindow->mDoc;
     679                 : 
     680               0 :   nsresult rv = aBlob->GetInternalUrl(doc->NodePrincipal(), aURL);
     681               0 :   NS_ENSURE_SUCCESS(rv, rv);
     682                 : 
     683               0 :   doc->RegisterFileDataUri(NS_LossyConvertUTF16toASCII(aURL));
     684                 : 
     685               0 :   return NS_OK;
     686                 : }
     687                 : 
     688                 : NS_IMETHODIMP
     689               0 : nsDOMMozURLProperty::RevokeObjectURL(const nsAString& aURL)
     690                 : {
     691               0 :   NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(),
     692                 :                   "Should be inner window");
     693                 : 
     694               0 :   NS_ENSURE_STATE(mWindow);
     695                 : 
     696               0 :   NS_LossyConvertUTF16toASCII asciiurl(aURL);
     697                 : 
     698               0 :   nsIPrincipal* winPrincipal = mWindow->GetPrincipal();
     699               0 :   if (!winPrincipal) {
     700               0 :     return NS_OK;
     701                 :   }
     702                 : 
     703                 :   nsIPrincipal* principal =
     704               0 :     nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl);
     705                 :   bool subsumes;
     706               0 :   if (principal && winPrincipal &&
     707               0 :       NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) &&
     708                 :       subsumes) {
     709               0 :     if (mWindow->mDoc) {
     710               0 :       mWindow->mDoc->UnregisterFileDataUri(asciiurl);
     711                 :     }
     712               0 :     nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl);
     713                 :   }
     714                 : 
     715               0 :   return NS_OK;
     716                 : }
     717                 : 
     718                 : /**
     719                 :  * An indirect observer object that means we don't have to implement nsIObserver
     720                 :  * on nsGlobalWindow, where any script could see it.
     721                 :  */
     722                 : class nsGlobalWindowObserver : public nsIObserver {
     723                 : public:
     724               0 :   nsGlobalWindowObserver(nsGlobalWindow* aWindow) : mWindow(aWindow) {}
     725                 :   NS_DECL_ISUPPORTS
     726               0 :   NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData)
     727                 :   {
     728               0 :     if (!mWindow)
     729               0 :       return NS_OK;
     730               0 :     return mWindow->Observe(aSubject, aTopic, aData);
     731                 :   }
     732               0 :   void Forget() { mWindow = nsnull; }
     733                 : private:
     734                 :   nsGlobalWindow* mWindow;
     735                 : };
     736                 : 
     737               0 : NS_IMPL_ISUPPORTS1(nsGlobalWindowObserver, nsIObserver)
     738                 : 
     739               0 : nsTimeout::nsTimeout()
     740                 : {
     741                 : #ifdef DEBUG_jst
     742                 :   {
     743                 :     extern int gTimeoutCnt;
     744                 : 
     745                 :     ++gTimeoutCnt;
     746                 :   }
     747                 : #endif
     748                 : 
     749               0 :   memset(this, 0, sizeof(*this));
     750                 : 
     751               0 :   MOZ_COUNT_CTOR(nsTimeout);
     752               0 : }
     753                 : 
     754               0 : nsTimeout::~nsTimeout()
     755                 : {
     756                 : #ifdef DEBUG_jst
     757                 :   {
     758                 :     extern int gTimeoutCnt;
     759                 : 
     760                 :     --gTimeoutCnt;
     761                 :   }
     762                 : #endif
     763                 : 
     764               0 :   MOZ_COUNT_DTOR(nsTimeout);
     765               0 : }
     766                 : 
     767            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsTimeout)
     768               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsTimeout)
     769               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsTimeout)
     770               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow,
     771                 :                                                        nsIScriptGlobalObject)
     772               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
     773               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptHandler)
     774               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     775               0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsTimeout, AddRef)
     776               0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsTimeout, Release)
     777                 : 
     778               0 : nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
     779                 : : mFrameElement(nsnull), mDocShell(nsnull), mModalStateDepth(0),
     780                 :   mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(false),
     781                 :   mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nsnull),
     782                 :   mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
     783                 :   mMayHaveMouseEnterLeaveEventListener(false),
     784                 :   mIsModalContentWindow(false),
     785                 :   mIsActive(false), mIsBackground(false),
     786                 :   mInnerWindow(nsnull), mOuterWindow(aOuterWindow),
     787                 :   // Make sure no actual window ends up with mWindowID == 0
     788               0 :   mWindowID(++gNextWindowID), mHasNotifiedGlobalCreated(false)
     789               0 :  {}
     790                 : 
     791               0 : nsPIDOMWindow::~nsPIDOMWindow() {}
     792                 : 
     793                 : //*****************************************************************************
     794                 : // nsOuterWindowProxy: Outer Window Proxy
     795                 : //*****************************************************************************
     796                 : 
     797                 : JSString *
     798               0 : nsOuterWindowProxy::obj_toString(JSContext *cx, JSObject *proxy)
     799                 : {
     800               0 :     JS_ASSERT(js::IsProxy(proxy));
     801                 : 
     802               0 :     return JS_NewStringCopyZ(cx, "[object Window]");
     803                 : }
     804                 : 
     805                 : void
     806               0 : nsOuterWindowProxy::finalize(JSContext *cx, JSObject *proxy)
     807                 : {
     808                 :   nsISupports *global =
     809               0 :     static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate());
     810               0 :   if (global) {
     811                 :     nsWrapperCache *cache;
     812               0 :     CallQueryInterface(global, &cache);
     813               0 :     cache->ClearWrapperIfProxy();
     814                 :   }
     815               0 : }
     816                 : 
     817                 : nsOuterWindowProxy
     818            1464 : nsOuterWindowProxy::singleton;
     819                 : 
     820                 : JSObject *
     821               0 : NS_NewOuterWindowProxy(JSContext *cx, JSObject *parent)
     822                 : {
     823               0 :   JSAutoEnterCompartment ac;
     824               0 :   if (!ac.enter(cx, parent)) {
     825               0 :     return nsnull;
     826                 :   }
     827                 : 
     828                 :   JSObject *obj = js::Wrapper::New(cx, parent, js::GetObjectProto(parent), parent,
     829               0 :                                    &nsOuterWindowProxy::singleton);
     830               0 :   NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject, "bad class");
     831               0 :   return obj;
     832                 : }
     833                 : 
     834                 : //*****************************************************************************
     835                 : //***    nsGlobalWindow: Object Management
     836                 : //*****************************************************************************
     837                 : 
     838               0 : nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
     839                 :   : nsPIDOMWindow(aOuterWindow),
     840                 :     mIsFrozen(false),
     841                 :     mDidInitJavaProperties(false),
     842                 :     mFullScreen(false),
     843                 :     mIsClosed(false), 
     844                 :     mInClose(false), 
     845                 :     mHavePendingClose(false),
     846                 :     mHadOriginalOpener(false),
     847                 :     mIsPopupSpam(false),
     848                 :     mBlockScriptedClosingFlag(false),
     849                 :     mFireOfflineStatusChangeEventOnThaw(false),
     850                 :     mCreatingInnerWindow(false),
     851                 :     mIsChrome(false),
     852                 :     mCleanMessageManager(false),
     853                 :     mNeedsFocus(true),
     854                 :     mHasFocus(false),
     855                 : #if defined(XP_MACOSX)
     856                 :     mShowAccelerators(false),
     857                 :     mShowFocusRings(false),
     858                 : #else
     859                 :     mShowAccelerators(true),
     860                 :     mShowFocusRings(true),
     861                 : #endif
     862                 :     mShowFocusRingForContent(false),
     863                 :     mFocusByKeyOccurred(false),
     864                 :     mHasDeviceMotion(false),
     865                 :     mNotifiedIDDestroyed(false),
     866                 :     mTimeoutInsertionPoint(nsnull),
     867                 :     mTimeoutPublicIdCounter(1),
     868                 :     mTimeoutFiringDepth(0),
     869                 :     mJSObject(nsnull),
     870                 :     mPendingStorageEventsObsolete(nsnull),
     871                 :     mTimeoutsSuspendDepth(0),
     872                 :     mFocusMethod(0),
     873                 :     mSerial(0),
     874                 : #ifdef DEBUG
     875                 :     mSetOpenerWindowCalled(false),
     876                 : #endif
     877                 :     mCleanedUp(false),
     878                 :     mCallCleanUpAfterModalDialogCloses(false),
     879                 :     mDialogAbuseCount(0),
     880               0 :     mDialogDisabled(false)
     881                 : {
     882               0 :   nsLayoutStatics::AddRef();
     883                 : 
     884                 :   // Initialize the PRCList (this).
     885               0 :   PR_INIT_CLIST(this);
     886                 : 
     887                 :   // Initialize timeout storage
     888               0 :   PR_INIT_CLIST(&mTimeouts);
     889                 : 
     890               0 :   if (aOuterWindow) {
     891                 :     // |this| is an inner window, add this inner window to the outer
     892                 :     // window list of inners.
     893               0 :     PR_INSERT_AFTER(this, aOuterWindow);
     894                 : 
     895               0 :     mObserver = new nsGlobalWindowObserver(this);
     896               0 :     if (mObserver) {
     897               0 :       NS_ADDREF(mObserver);
     898               0 :       nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     899               0 :       if (os) {
     900                 :         // Watch for online/offline status changes so we can fire events. Use
     901                 :         // a strong reference.
     902               0 :         os->AddObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC,
     903               0 :                         false);
     904                 : 
     905                 :         // Watch for dom-storage-changed so we can fire storage
     906                 :         // events. Use a strong reference.
     907               0 :         os->AddObserver(mObserver, "dom-storage2-changed", false);
     908               0 :         os->AddObserver(mObserver, "dom-storage-changed", false);
     909                 :       }
     910                 :     }
     911                 :   } else {
     912                 :     // |this| is an outer window. Outer windows start out frozen and
     913                 :     // remain frozen until they get an inner window, so freeze this
     914                 :     // outer window here.
     915               0 :     Freeze();
     916                 : 
     917               0 :     mObserver = nsnull;
     918               0 :     SetIsProxy();
     919                 :   }
     920                 : 
     921                 :   // We could have failed the first time through trying
     922                 :   // to create the entropy collector, so we should
     923                 :   // try to get one until we succeed.
     924                 : 
     925               0 :   gRefCnt++;
     926                 : 
     927               0 :   if (gRefCnt == 1) {
     928                 : #if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
     929                 :     Preferences::AddBoolVarCache(&gDOMWindowDumpEnabled,
     930                 :                                  "browser.dom.window.dump.enabled");
     931                 : #endif
     932                 :     Preferences::AddIntVarCache(&gMinTimeoutValue,
     933                 :                                 "dom.min_timeout_value",
     934               0 :                                 DEFAULT_MIN_TIMEOUT_VALUE);
     935                 :     Preferences::AddIntVarCache(&gMinBackgroundTimeoutValue,
     936                 :                                 "dom.min_background_timeout_value",
     937               0 :                                 DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE);
     938                 :   }
     939                 : 
     940               0 :   if (gDumpFile == nsnull) {
     941                 :     const nsAdoptingCString& fname =
     942               0 :       Preferences::GetCString("browser.dom.window.dump.file");
     943               0 :     if (!fname.IsEmpty()) {
     944                 :       // if this fails to open, Dump() knows to just go to stdout
     945                 :       // on null.
     946               0 :       gDumpFile = fopen(fname, "wb+");
     947                 :     } else {
     948               0 :       gDumpFile = stdout;
     949                 :     }
     950                 :   }
     951                 : 
     952               0 :   mSerial = ++gSerialCounter;
     953                 : 
     954                 : #ifdef DEBUG
     955               0 :   if (!PR_GetEnv("MOZ_QUIET")) {
     956                 :     printf("++DOMWINDOW == %d (%p) [serial = %d] [outer = %p]\n", gRefCnt,
     957                 :            static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
     958               0 :            gSerialCounter, static_cast<void*>(aOuterWindow));
     959                 :   }
     960                 : #endif
     961                 : 
     962                 : #ifdef PR_LOGGING
     963               0 :   if (gDOMLeakPRLog)
     964               0 :     PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
     965                 :            ("DOMWINDOW %p created outer=%p", this, aOuterWindow));
     966                 : #endif
     967                 : 
     968               0 :   NS_ASSERTION(sWindowsById, "Windows hash table must be created!");
     969               0 :   NS_ASSERTION(!sWindowsById->Get(mWindowID),
     970                 :                "This window shouldn't be in the hash table yet!");
     971               0 :   sWindowsById->Put(mWindowID, this);
     972                 : 
     973               0 :   mEventTargetObjects.Init();
     974               0 : }
     975                 : 
     976                 : /* static */
     977                 : void
     978            1404 : nsGlobalWindow::Init()
     979                 : {
     980            1404 :   CallGetService(NS_ENTROPYCOLLECTOR_CONTRACTID, &gEntropyCollector);
     981            1404 :   NS_ASSERTION(gEntropyCollector,
     982                 :                "gEntropyCollector should have been initialized!");
     983                 : 
     984                 : #ifdef PR_LOGGING
     985            1404 :   gDOMLeakPRLog = PR_NewLogModule("DOMLeak");
     986            1404 :   NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!");
     987                 : #endif
     988                 : 
     989            1404 :   sWindowsById = new WindowByIdTable();
     990                 :   // There are two reasons to have Init() failing: if we were not able to
     991                 :   // alloc the memory or if the size we want to init is too high. None of them
     992                 :   // should happen.
     993                 : #ifdef DEBUG
     994            1404 :   NS_ASSERTION(sWindowsById->Init(), "Init() should not fail!");
     995                 : #else
     996                 :   sWindowsById->Init();
     997                 : #endif
     998            1404 : }
     999                 : 
    1000                 : static PLDHashOperator
    1001               0 : DisconnectEventTargetObjects(nsPtrHashKey<nsDOMEventTargetHelper>* aKey,
    1002                 :                              void* aClosure)
    1003                 : {
    1004               0 :   nsRefPtr<nsDOMEventTargetHelper> target = aKey->GetKey();
    1005               0 :   target->DisconnectFromOwner();
    1006               0 :   return PL_DHASH_NEXT;
    1007                 : }
    1008                 : 
    1009               0 : nsGlobalWindow::~nsGlobalWindow()
    1010                 : {
    1011               0 :   mEventTargetObjects.EnumerateEntries(DisconnectEventTargetObjects, nsnull);
    1012               0 :   mEventTargetObjects.Clear();
    1013                 : 
    1014                 :   // We have to check if sWindowsById isn't null because ::Shutdown might have
    1015                 :   // been called.
    1016               0 :   if (sWindowsById) {
    1017               0 :     NS_ASSERTION(sWindowsById->Get(mWindowID),
    1018                 :                  "This window should be in the hash table");
    1019               0 :     sWindowsById->Remove(mWindowID);
    1020                 :   }
    1021                 : 
    1022               0 :   --gRefCnt;
    1023                 : 
    1024                 : #ifdef DEBUG
    1025               0 :   if (!PR_GetEnv("MOZ_QUIET")) {
    1026               0 :     nsCAutoString url;
    1027               0 :     if (mLastOpenedURI) {
    1028               0 :       mLastOpenedURI->GetSpec(url);
    1029                 :     }
    1030                 : 
    1031                 :     printf("--DOMWINDOW == %d (%p) [serial = %d] [outer = %p] [url = %s]\n",
    1032                 :            gRefCnt, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
    1033               0 :            mSerial, static_cast<void*>(mOuterWindow.get()), url.get());
    1034                 :   }
    1035                 : #endif
    1036                 : 
    1037                 : #ifdef PR_LOGGING
    1038               0 :   if (gDOMLeakPRLog)
    1039               0 :     PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
    1040                 :            ("DOMWINDOW %p destroyed", this));
    1041                 : #endif
    1042                 : 
    1043               0 :   if (IsOuterWindow()) {
    1044               0 :     JSObject *proxy = GetWrapperPreserveColor();
    1045               0 :     if (proxy) {
    1046               0 :       js::SetProxyExtra(proxy, 0, js::PrivateValue(NULL));
    1047                 :     }
    1048                 : 
    1049                 :     // An outer window is destroyed with inner windows still possibly
    1050                 :     // alive, iterate through the inner windows and null out their
    1051                 :     // back pointer to this outer, and pull them out of the list of
    1052                 :     // inner windows.
    1053                 : 
    1054                 :     nsGlobalWindow *w;
    1055               0 :     while ((w = (nsGlobalWindow *)PR_LIST_HEAD(this)) != this) {
    1056               0 :       PR_REMOVE_AND_INIT_LINK(w);
    1057                 :     }
    1058                 :   } else {
    1059                 :     Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
    1060               0 :                           mMutationBits ? 1 : 0);
    1061                 : 
    1062               0 :     if (mListenerManager) {
    1063               0 :       mListenerManager->Disconnect();
    1064               0 :       mListenerManager = nsnull;
    1065                 :     }
    1066                 : 
    1067                 :     // An inner window is destroyed, pull it out of the outer window's
    1068                 :     // list if inner windows.
    1069                 : 
    1070               0 :     PR_REMOVE_LINK(this);
    1071                 : 
    1072                 :     // If our outer window's inner window is this window, null out the
    1073                 :     // outer window's reference to this window that's being deleted.
    1074               0 :     nsGlobalWindow *outer = GetOuterWindowInternal();
    1075               0 :     if (outer && outer->mInnerWindow == this) {
    1076               0 :       outer->mInnerWindow = nsnull;
    1077                 :     }
    1078                 :   }
    1079                 : 
    1080               0 :   mDocument = nsnull;           // Forces Release
    1081               0 :   mDoc = nsnull;
    1082                 : 
    1083               0 :   NS_ASSERTION(!mArguments, "mArguments wasn't cleaned up properly!");
    1084                 : 
    1085               0 :   CleanUp(true);
    1086                 : 
    1087                 : #ifdef DEBUG
    1088               0 :   nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this));
    1089                 : #endif
    1090                 : 
    1091               0 :   if (mURLProperty) {
    1092               0 :     mURLProperty->ClearWindowReference();
    1093                 :   }
    1094                 : 
    1095               0 :   DisableDeviceMotionUpdates();
    1096               0 :   mHasDeviceMotion = false;
    1097                 : 
    1098               0 :   nsLayoutStatics::Release();
    1099               0 : }
    1100                 : 
    1101                 : void
    1102               0 : nsGlobalWindow::AddEventTargetObject(nsDOMEventTargetHelper* aObject)
    1103                 : {
    1104               0 :   mEventTargetObjects.PutEntry(aObject);
    1105               0 : }
    1106                 : 
    1107                 : void
    1108               0 : nsGlobalWindow::RemoveEventTargetObject(nsDOMEventTargetHelper* aObject)
    1109                 : {
    1110               0 :   mEventTargetObjects.RemoveEntry(aObject);
    1111               0 : }
    1112                 : 
    1113                 : // static
    1114                 : void
    1115            1453 : nsGlobalWindow::ShutDown()
    1116                 : {
    1117            1453 :   NS_IF_RELEASE(sGlobalStorageList);
    1118                 : 
    1119            1453 :   if (gDumpFile && gDumpFile != stdout) {
    1120               0 :     fclose(gDumpFile);
    1121                 :   }
    1122            1453 :   gDumpFile = nsnull;
    1123                 : 
    1124            1453 :   NS_IF_RELEASE(gEntropyCollector);
    1125                 : 
    1126            1453 :   delete sWindowsById;
    1127            1453 :   sWindowsById = nsnull;
    1128            1453 : }
    1129                 : 
    1130                 : // static
    1131                 : void
    1132               0 : nsGlobalWindow::CleanupCachedXBLHandlers(nsGlobalWindow* aWindow)
    1133                 : {
    1134               0 :   if (aWindow->mCachedXBLPrototypeHandlers.IsInitialized() &&
    1135               0 :       aWindow->mCachedXBLPrototypeHandlers.Count() > 0) {
    1136               0 :     aWindow->mCachedXBLPrototypeHandlers.Clear();
    1137                 : 
    1138                 :     nsISupports* supports;
    1139                 :     aWindow->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
    1140               0 :                             reinterpret_cast<void**>(&supports));
    1141               0 :     NS_ASSERTION(supports, "Failed to QI to nsCycleCollectionISupports?!");
    1142                 : 
    1143               0 :     nsContentUtils::DropJSObjects(supports);
    1144                 :   }
    1145               0 : }
    1146                 : 
    1147                 : void
    1148               0 : nsGlobalWindow::MaybeForgiveSpamCount()
    1149                 : {
    1150               0 :   if (IsOuterWindow() &&
    1151               0 :       IsPopupSpamWindow())
    1152                 :   {
    1153               0 :     SetPopupSpamWindow(false);
    1154               0 :     --gOpenPopupSpamCount;
    1155               0 :     NS_ASSERTION(gOpenPopupSpamCount >= 0,
    1156                 :                  "Unbalanced decrement of gOpenPopupSpamCount");
    1157                 :   }
    1158               0 : }
    1159                 : 
    1160                 : void
    1161               0 : nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
    1162                 : {
    1163               0 :   if (IsOuterWindow() && !aIgnoreModalDialog) {
    1164               0 :     nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
    1165               0 :     nsCOMPtr<nsIDOMModalContentWindow> dlg(do_QueryObject(inner));
    1166               0 :     if (dlg) {
    1167                 :       // The window we're trying to clean up is the outer window of a
    1168                 :       // modal dialog.  Defer cleanup until the window closes, and let
    1169                 :       // ShowModalDialog take care of calling CleanUp.
    1170               0 :       mCallCleanUpAfterModalDialogCloses = true;
    1171                 :       return;
    1172                 :     }
    1173                 :   }
    1174                 : 
    1175                 :   // Guarantee idempotence.
    1176               0 :   if (mCleanedUp)
    1177               0 :     return;
    1178               0 :   mCleanedUp = true;
    1179                 :   
    1180               0 :   mEventTargetObjects.EnumerateEntries(DisconnectEventTargetObjects, nsnull);
    1181               0 :   mEventTargetObjects.Clear();
    1182                 : 
    1183               0 :   if (mObserver) {
    1184               0 :     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
    1185               0 :     if (os) {
    1186               0 :       os->RemoveObserver(mObserver, NS_IOSERVICE_OFFLINE_STATUS_TOPIC);
    1187               0 :       os->RemoveObserver(mObserver, "dom-storage2-changed");
    1188               0 :       os->RemoveObserver(mObserver, "dom-storage-changed");
    1189                 :     }
    1190                 : 
    1191                 :     // Drop its reference to this dying window, in case for some bogus reason
    1192                 :     // the object stays around.
    1193               0 :     mObserver->Forget();
    1194               0 :     NS_RELEASE(mObserver);
    1195                 :   }
    1196                 : 
    1197               0 :   mNavigator = nsnull;
    1198               0 :   mScreen = nsnull;
    1199               0 :   mMenubar = nsnull;
    1200               0 :   mToolbar = nsnull;
    1201               0 :   mLocationbar = nsnull;
    1202               0 :   mPersonalbar = nsnull;
    1203               0 :   mStatusbar = nsnull;
    1204               0 :   mScrollbars = nsnull;
    1205               0 :   mLocation = nsnull;
    1206               0 :   mHistory = nsnull;
    1207               0 :   mFrames = nsnull;
    1208               0 :   mApplicationCache = nsnull;
    1209               0 :   mIndexedDB = nsnull;
    1210               0 :   mPendingStorageEventsObsolete = nsnull;
    1211                 : 
    1212               0 :   mPerformance = nsnull;
    1213                 : 
    1214               0 :   ClearControllers();
    1215                 : 
    1216               0 :   mOpener = nsnull;             // Forces Release
    1217               0 :   if (mContext) {
    1218                 : #ifdef DEBUG
    1219               0 :     nsCycleCollector_DEBUG_shouldBeFreed(mContext);
    1220                 : #endif
    1221               0 :     mContext = nsnull;            // Forces Release
    1222                 :   }
    1223               0 :   mChromeEventHandler = nsnull; // Forces Release
    1224               0 :   mParentTarget = nsnull;
    1225                 : 
    1226               0 :   nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
    1227                 : 
    1228               0 :   if (inner) {
    1229               0 :     inner->CleanUp(aIgnoreModalDialog);
    1230                 :   }
    1231                 : 
    1232               0 :   if (mCleanMessageManager) {
    1233               0 :     NS_ABORT_IF_FALSE(mIsChrome, "only chrome should have msg manager cleaned");
    1234               0 :     nsGlobalChromeWindow *asChrome = static_cast<nsGlobalChromeWindow*>(this);
    1235               0 :     if (asChrome->mMessageManager) {
    1236                 :       static_cast<nsFrameMessageManager*>(
    1237               0 :         asChrome->mMessageManager.get())->Disconnect();
    1238                 :     }
    1239                 :   }
    1240                 : 
    1241               0 :   mInnerWindowHolder = nsnull;
    1242               0 :   mArguments = nsnull;
    1243               0 :   mArgumentsLast = nsnull;
    1244               0 :   mArgumentsOrigin = nsnull;
    1245                 : 
    1246               0 :   CleanupCachedXBLHandlers(this);
    1247                 : 
    1248                 : #ifdef DEBUG
    1249               0 :   nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
    1250                 : #endif
    1251                 : }
    1252                 : 
    1253                 : void
    1254               0 : nsGlobalWindow::ClearControllers()
    1255                 : {
    1256               0 :   if (mControllers) {
    1257                 :     PRUint32 count;
    1258               0 :     mControllers->GetControllerCount(&count);
    1259                 : 
    1260               0 :     while (count--) {
    1261               0 :       nsCOMPtr<nsIController> controller;
    1262               0 :       mControllers->GetControllerAt(count, getter_AddRefs(controller));
    1263                 : 
    1264               0 :       nsCOMPtr<nsIControllerContext> context = do_QueryInterface(controller);
    1265               0 :       if (context)
    1266               0 :         context->SetCommandContext(nsnull);
    1267                 :     }
    1268                 : 
    1269               0 :     mControllers = nsnull;
    1270                 :   }
    1271               0 : }
    1272                 : 
    1273                 : void
    1274               0 : nsGlobalWindow::FreeInnerObjects()
    1275                 : {
    1276               0 :   NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
    1277                 : 
    1278                 :   // Make sure that this is called before we null out the document and
    1279                 :   // other members that the window destroyed observers could
    1280                 :   // re-create.
    1281               0 :   NotifyDOMWindowDestroyed(this);
    1282                 : 
    1283                 :   // Kill all of the workers for this window.
    1284               0 :   nsIScriptContext *scx = GetContextInternal();
    1285               0 :   JSContext *cx = scx ? scx->GetNativeContext() : nsnull;
    1286               0 :   mozilla::dom::workers::CancelWorkersForWindow(cx, this);
    1287                 : 
    1288                 :   // Close all IndexedDB databases for this window.
    1289                 :   indexedDB::IndexedDatabaseManager* idbManager =
    1290               0 :     indexedDB::IndexedDatabaseManager::Get();
    1291               0 :   if (idbManager) {
    1292               0 :     idbManager->AbortCloseDatabasesForWindow(this);
    1293                 :   }
    1294                 : 
    1295               0 :   ClearAllTimeouts();
    1296                 : 
    1297               0 :   mChromeEventHandler = nsnull;
    1298                 : 
    1299               0 :   if (mListenerManager) {
    1300               0 :     mListenerManager->Disconnect();
    1301               0 :     mListenerManager = nsnull;
    1302                 :   }
    1303                 : 
    1304               0 :   mLocation = nsnull;
    1305               0 :   mHistory = nsnull;
    1306                 : 
    1307               0 :   if (mNavigator) {
    1308               0 :     mNavigator->Invalidate();
    1309               0 :     mNavigator = nsnull;
    1310                 :   }
    1311                 : 
    1312               0 :   if (mDocument) {
    1313               0 :     NS_ASSERTION(mDoc, "Why is mDoc null?");
    1314                 : 
    1315                 :     // Remember the document's principal.
    1316               0 :     mDocumentPrincipal = mDoc->NodePrincipal();
    1317                 :   }
    1318                 : 
    1319                 : #ifdef DEBUG
    1320               0 :   if (mDocument)
    1321               0 :     nsCycleCollector_DEBUG_shouldBeFreed(nsCOMPtr<nsISupports>(do_QueryInterface(mDocument)));
    1322                 : #endif
    1323                 : 
    1324                 :   // Remove our reference to the document and the document principal.
    1325               0 :   mDocument = nsnull;
    1326               0 :   mDoc = nsnull;
    1327               0 :   mFocusedNode = nsnull;
    1328                 : 
    1329               0 :   if (mApplicationCache) {
    1330               0 :     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->Disconnect();
    1331               0 :     mApplicationCache = nsnull;
    1332                 :   }
    1333                 : 
    1334               0 :   mIndexedDB = nsnull;
    1335                 : 
    1336               0 :   NotifyWindowIDDestroyed("inner-window-destroyed");
    1337                 : 
    1338               0 :   if (mDummyJavaPluginOwner) {
    1339                 :     // Tear down the dummy java plugin.
    1340                 : 
    1341                 :     // XXXjst: On a general note, should windows with java stuff in
    1342                 :     // them ever even make it into the fast-back cache?
    1343                 : 
    1344               0 :     mDummyJavaPluginOwner->Destroy();
    1345               0 :     mDummyJavaPluginOwner = nsnull;
    1346               0 :     mDidInitJavaProperties = false;
    1347                 :   }
    1348                 : 
    1349               0 :   CleanupCachedXBLHandlers(this);
    1350                 : 
    1351                 : #ifdef DEBUG
    1352               0 :   nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
    1353                 : #endif
    1354               0 : }
    1355                 : 
    1356                 : //*****************************************************************************
    1357                 : // nsGlobalWindow::nsISupports
    1358                 : //*****************************************************************************
    1359                 : 
    1360                 : #define OUTER_WINDOW_ONLY                                                     \
    1361                 :   if (IsOuterWindow()) {
    1362                 : 
    1363                 : #define END_OUTER_WINDOW_ONLY                                                 \
    1364                 :     foundInterface = 0;                                                       \
    1365                 :   } else
    1366                 : 
    1367            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalWindow)
    1368                 : 
    1369                 : DOMCI_DATA(Window, nsGlobalWindow)
    1370                 : 
    1371                 : // QueryInterface implementation for nsGlobalWindow
    1372               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
    1373                 :   // Make sure this matches the cast in nsGlobalWindow::FromWrapper()
    1374               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
    1375               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
    1376               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow_globalStorage)
    1377               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
    1378               0 :   if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
    1379               0 :     foundInterface = static_cast<nsIDOMWindowInternal*>(this);
    1380               0 :     if (!sWarnedAboutWindowInternal) {
    1381               0 :       sWarnedAboutWindowInternal = true;
    1382                 :       nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
    1383                 :                                       "Extensions", mDoc,
    1384                 :                                       nsContentUtils::eDOM_PROPERTIES,
    1385               0 :                                       "nsIDOMWindowInternalWarning");
    1386                 :     }
    1387                 :   } else
    1388               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
    1389               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
    1390               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
    1391               0 :   NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
    1392               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMStorageIndexedDB)
    1393               0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    1394               0 :   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
    1395               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowPerformance)
    1396               0 :   NS_INTERFACE_MAP_ENTRY(nsITouchEventReceiver)
    1397               0 :   NS_INTERFACE_MAP_ENTRY(nsIInlineEventHandlers)
    1398               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Window)
    1399               0 :   OUTER_WINDOW_ONLY
    1400               0 :     NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    1401               0 :   END_OUTER_WINDOW_ONLY
    1402               0 : NS_INTERFACE_MAP_END
    1403                 : 
    1404                 : 
    1405               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindow)
    1406               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindow)
    1407                 : 
    1408                 : static PLDHashOperator
    1409               0 : MarkXBLHandlers(const void* aKey, JSObject* aData, void* aClosure)
    1410                 : {
    1411               0 :   xpc_UnmarkGrayObject(aData);
    1412               0 :   return PL_DHASH_NEXT;
    1413                 : }
    1414                 : 
    1415               0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGlobalWindow)
    1416               0 :   if (tmp->IsBlackForCC()) {
    1417               0 :     if (tmp->mCachedXBLPrototypeHandlers.IsInitialized()) {
    1418               0 :       tmp->mCachedXBLPrototypeHandlers.EnumerateRead(MarkXBLHandlers, nsnull);
    1419                 :     }
    1420               0 :     return true;
    1421                 :   }
    1422               0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
    1423                 : 
    1424               0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsGlobalWindow)
    1425               0 :   return tmp->IsBlackForCC();
    1426                 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
    1427                 : 
    1428               0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsGlobalWindow)
    1429               0 :   return tmp->IsBlackForCC();
    1430                 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
    1431                 : 
    1432               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalWindow)
    1433               0 :   if (!cb.WantAllTraces() && tmp->IsBlackForCC()) {
    1434               0 :     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
    1435                 :   }
    1436                 : 
    1437               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
    1438                 : 
    1439               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mControllers)
    1440               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArguments)
    1441               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArgumentsLast)
    1442                 : 
    1443               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInnerWindowHolder)
    1444               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOuterWindow)
    1445                 : 
    1446               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOpenerScriptPrincipal)
    1447               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
    1448                 :                                                   nsEventListenerManager)
    1449                 : 
    1450               0 :   for (nsTimeout* timeout = tmp->FirstTimeout();
    1451               0 :        tmp->IsTimeout(timeout);
    1452                 :        timeout = timeout->Next()) {
    1453               0 :     cb.NoteNativeChild(timeout, &NS_CYCLE_COLLECTION_NAME(nsTimeout));
    1454                 :   }
    1455                 : 
    1456               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSessionStorage)
    1457               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mApplicationCache)
    1458               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocumentPrincipal)
    1459               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDoc)
    1460                 : 
    1461                 :   // Traverse stuff from nsPIDOMWindow
    1462               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChromeEventHandler)
    1463               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParentTarget)
    1464               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
    1465               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFrameElement)
    1466                 : 
    1467                 :   // Traverse mDummyJavaPluginOwner
    1468               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDummyJavaPluginOwner)
    1469                 : 
    1470               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFocusedNode)
    1471                 : 
    1472               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPendingStorageEvents)
    1473                 : 
    1474               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    1475                 : 
    1476               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
    1477               0 :   nsGlobalWindow::CleanupCachedXBLHandlers(tmp);
    1478                 : 
    1479               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
    1480                 : 
    1481               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mControllers)
    1482               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mArguments)
    1483               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mArgumentsLast)
    1484                 : 
    1485               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInnerWindowHolder)
    1486               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOuterWindow)
    1487                 : 
    1488               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOpenerScriptPrincipal)
    1489               0 :   if (tmp->mListenerManager) {
    1490               0 :     tmp->mListenerManager->Disconnect();
    1491               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
    1492                 :   }
    1493               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSessionStorage)
    1494               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mApplicationCache)
    1495               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocumentPrincipal)
    1496               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDoc)
    1497                 : 
    1498                 :   // Unlink stuff from nsPIDOMWindow
    1499               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChromeEventHandler)
    1500               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParentTarget)
    1501               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
    1502               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFrameElement)
    1503                 : 
    1504                 :   // Unlink mDummyJavaPluginOwner
    1505               0 :   if (tmp->mDummyJavaPluginOwner) {
    1506               0 :     tmp->mDummyJavaPluginOwner->Destroy();
    1507               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDummyJavaPluginOwner)
    1508               0 :     tmp->mDidInitJavaProperties = false;
    1509                 :   }
    1510                 : 
    1511               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFocusedNode)
    1512                 : 
    1513               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPendingStorageEvents)
    1514                 : 
    1515               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    1516                 : 
    1517                 : struct TraceData
    1518                 : {
    1519               0 :   TraceData(TraceCallback& aCallback, void* aClosure) :
    1520               0 :     callback(aCallback), closure(aClosure) {}
    1521                 : 
    1522                 :   TraceCallback& callback;
    1523                 :   void* closure;
    1524                 : };
    1525                 : 
    1526                 : static PLDHashOperator
    1527               0 : TraceXBLHandlers(const void* aKey, JSObject* aData, void* aClosure)
    1528                 : {
    1529               0 :   TraceData* data = static_cast<TraceData*>(aClosure);
    1530                 :   data->callback(nsIProgrammingLanguage::JAVASCRIPT, aData,
    1531               0 :                  "Cached XBL prototype handler", data->closure);
    1532               0 :   return PL_DHASH_NEXT;
    1533                 : }
    1534                 : 
    1535               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
    1536               0 :   if (tmp->mCachedXBLPrototypeHandlers.IsInitialized()) {
    1537               0 :     TraceData data(aCallback, aClosure);
    1538               0 :     tmp->mCachedXBLPrototypeHandlers.EnumerateRead(TraceXBLHandlers, &data);
    1539                 :   }
    1540               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
    1541                 : 
    1542                 : bool
    1543               0 : nsGlobalWindow::IsBlackForCC()
    1544                 : {
    1545                 :   return
    1546                 :     (mDoc &&
    1547               0 :      nsCCUncollectableMarker::InGeneration(mDoc->GetMarkedCCGeneration())) ||
    1548               0 :     (nsCCUncollectableMarker::sGeneration && IsBlack());
    1549                 : }
    1550                 : 
    1551                 : void
    1552               0 : nsGlobalWindow::UnmarkGrayTimers()
    1553                 : {
    1554               0 :   for (nsTimeout* timeout = FirstTimeout();
    1555               0 :        timeout && IsTimeout(timeout);
    1556                 :        timeout = timeout->Next()) {
    1557               0 :     if (timeout->mScriptHandler) {
    1558               0 :       JSObject* o = timeout->mScriptHandler->GetScriptObject();
    1559               0 :       xpc_UnmarkGrayObject(o);
    1560                 :     }
    1561                 :   }
    1562               0 : }
    1563                 : 
    1564                 : //*****************************************************************************
    1565                 : // nsGlobalWindow::nsIScriptGlobalObject
    1566                 : //*****************************************************************************
    1567                 : 
    1568                 : nsresult
    1569               0 : nsGlobalWindow::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aScriptContext)
    1570                 : {
    1571               0 :   NS_ASSERTION(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
    1572                 :                "We don't support this language ID");
    1573               0 :   NS_ASSERTION(IsOuterWindow(), "Uh, SetScriptContext() called on inner window!");
    1574                 : 
    1575               0 :   NS_ASSERTION(!aScriptContext || !mContext, "Bad call to SetContext()!");
    1576                 : 
    1577               0 :   if (aScriptContext) {
    1578                 :     // should probably assert the context is clean???
    1579               0 :     aScriptContext->WillInitializeContext();
    1580                 : 
    1581               0 :     nsresult rv = aScriptContext->InitContext();
    1582               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1583                 : 
    1584               0 :     if (IsFrame()) {
    1585                 :       // This window is a [i]frame, don't bother GC'ing when the
    1586                 :       // frame's context is destroyed since a GC will happen when the
    1587                 :       // frameset or host document is destroyed anyway.
    1588                 : 
    1589               0 :       aScriptContext->SetGCOnDestruction(false);
    1590                 :     }
    1591                 :   }
    1592                 : 
    1593               0 :   mContext = aScriptContext;
    1594               0 :   return NS_OK;
    1595                 : }
    1596                 : 
    1597                 : nsresult
    1598               0 : nsGlobalWindow::EnsureScriptEnvironment(PRUint32 aLangID)
    1599                 : {
    1600               0 :   NS_ASSERTION(aLangID == nsIProgrammingLanguage::JAVASCRIPT,
    1601                 :                "We don't support this language ID");
    1602               0 :   FORWARD_TO_OUTER(EnsureScriptEnvironment, (aLangID), NS_ERROR_NOT_INITIALIZED);
    1603                 : 
    1604               0 :   if (mJSObject)
    1605               0 :       return NS_OK;
    1606                 : 
    1607               0 :   NS_ASSERTION(!GetCurrentInnerWindowInternal(),
    1608                 :                "mJSObject is null, but we have an inner window?");
    1609                 : 
    1610               0 :   nsCOMPtr<nsIScriptRuntime> scriptRuntime;
    1611               0 :   nsresult rv = NS_GetScriptRuntimeByID(aLangID, getter_AddRefs(scriptRuntime));
    1612               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1613                 : 
    1614               0 :   nsCOMPtr<nsIScriptContext> context = scriptRuntime->CreateContext();
    1615               0 :   return SetScriptContext(aLangID, context);
    1616                 : }
    1617                 : 
    1618                 : nsIScriptContext *
    1619               0 : nsGlobalWindow::GetScriptContext(PRUint32 lang)
    1620                 : {
    1621               0 :   NS_ASSERTION(lang == nsIProgrammingLanguage::JAVASCRIPT,
    1622                 :                "We don't support this language ID");
    1623                 : 
    1624               0 :   FORWARD_TO_OUTER(GetScriptContext, (lang), nsnull);
    1625               0 :   return mContext;
    1626                 : }
    1627                 : 
    1628                 : nsIScriptContext *
    1629               0 : nsGlobalWindow::GetContext()
    1630                 : {
    1631               0 :   FORWARD_TO_OUTER(GetContext, (), nsnull);
    1632                 : 
    1633                 :   // check GetContext is indeed identical to GetScriptContext()
    1634               0 :   NS_ASSERTION(mContext == GetScriptContext(nsIProgrammingLanguage::JAVASCRIPT),
    1635                 :                "GetContext confused?");
    1636               0 :   return mContext;
    1637                 : }
    1638                 : 
    1639                 : JSObject *
    1640               0 : nsGlobalWindow::GetGlobalJSObject()
    1641                 : {
    1642               0 :   return FastGetGlobalJSObject();
    1643                 : }
    1644                 : 
    1645                 : bool
    1646               0 : nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
    1647                 : {
    1648                 :   // We reuse the inner window when:
    1649                 :   // a. We are currently at our original document.
    1650                 :   // b. At least one of the following conditions are true:
    1651                 :   // -- We are not currently a content window (i.e., we're currently a chrome
    1652                 :   //    window).
    1653                 :   // -- The new document is the same as the old document. This means that we're
    1654                 :   //    getting called from document.open().
    1655                 :   // -- The new document has the same origin as what we have loaded right now.
    1656                 : 
    1657               0 :   if (!mDoc || !aNewDocument) {
    1658               0 :     return false;
    1659                 :   }
    1660                 : 
    1661               0 :   if (!mDoc->IsInitialDocument()) {
    1662               0 :     return false;
    1663                 :   }
    1664                 :   
    1665               0 :   NS_ASSERTION(NS_IsAboutBlank(mDoc->GetDocumentURI()),
    1666                 :                "How'd this happen?");
    1667                 :   
    1668                 :   // Great, we're the original document, check for one of the other
    1669                 :   // conditions.
    1670               0 :   if (mDoc == aNewDocument) {
    1671               0 :     return true;
    1672                 :   }
    1673                 : 
    1674                 :   bool equal;
    1675               0 :   if (NS_SUCCEEDED(mDoc->NodePrincipal()->Equals(aNewDocument->NodePrincipal(),
    1676                 :                                                  &equal)) &&
    1677                 :       equal) {
    1678                 :     // The origin is the same.
    1679               0 :     return true;
    1680                 :   }
    1681                 : 
    1682               0 :   nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(mDocShell));
    1683                 : 
    1684               0 :   if (treeItem) {
    1685               0 :     PRInt32 itemType = nsIDocShellTreeItem::typeContent;
    1686               0 :     treeItem->GetItemType(&itemType);
    1687                 : 
    1688                 :     // If we're a chrome window, then we want to reuse the inner window.
    1689               0 :     return itemType == nsIDocShellTreeItem::typeChrome;
    1690                 :   }
    1691                 : 
    1692                 :   // No treeItem: don't reuse the current inner window.
    1693               0 :   return false;
    1694                 : }
    1695                 : 
    1696                 : void
    1697               0 : nsGlobalWindow::SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal)
    1698                 : {
    1699               0 :   FORWARD_TO_OUTER_VOID(SetOpenerScriptPrincipal, (aPrincipal));
    1700                 : 
    1701               0 :   if (mDoc) {
    1702               0 :     if (!mDoc->IsInitialDocument()) {
    1703                 :       // We have a document already, and it's not the original one.  Bail out.
    1704                 :       // Do NOT set mOpenerScriptPrincipal in this case, just to be safe.
    1705               0 :       return;
    1706                 :     }
    1707                 : 
    1708                 : #ifdef DEBUG
    1709                 :     // We better have an about:blank document loaded at this point.  Otherwise,
    1710                 :     // something is really weird.
    1711               0 :     nsCOMPtr<nsIURI> uri;
    1712               0 :     mDoc->NodePrincipal()->GetURI(getter_AddRefs(uri));
    1713               0 :     NS_ASSERTION(uri && NS_IsAboutBlank(uri) &&
    1714                 :                  NS_IsAboutBlank(mDoc->GetDocumentURI()),
    1715                 :                  "Unexpected original document");
    1716                 : #endif
    1717                 : 
    1718               0 :     GetDocShell()->CreateAboutBlankContentViewer(aPrincipal);
    1719               0 :     mDoc->SetIsInitialDocument(true);
    1720                 : 
    1721               0 :     nsCOMPtr<nsIPresShell> shell;
    1722               0 :     GetDocShell()->GetPresShell(getter_AddRefs(shell));
    1723                 : 
    1724               0 :     if (shell && !shell->DidInitialReflow()) {
    1725                 :       // Ensure that if someone plays with this document they will get
    1726                 :       // layout happening.
    1727               0 :       nsRect r = shell->GetPresContext()->GetVisibleArea();
    1728               0 :       shell->InitialReflow(r.width, r.height);
    1729                 :     }
    1730                 :   }
    1731                 : }
    1732                 : 
    1733                 : nsIPrincipal*
    1734               0 : nsGlobalWindow::GetOpenerScriptPrincipal()
    1735                 : {
    1736               0 :   FORWARD_TO_OUTER(GetOpenerScriptPrincipal, (), nsnull);
    1737                 : 
    1738               0 :   return mOpenerScriptPrincipal;
    1739                 : }
    1740                 : 
    1741                 : PopupControlState
    1742            8230 : PushPopupControlState(PopupControlState aState, bool aForce)
    1743                 : {
    1744            8230 :   PopupControlState oldState = gPopupControlState;
    1745                 : 
    1746            8230 :   if (aState < gPopupControlState || aForce) {
    1747               0 :     gPopupControlState = aState;
    1748                 :   }
    1749                 : 
    1750            8230 :   return oldState;
    1751                 : }
    1752                 : 
    1753                 : void
    1754            8230 : PopPopupControlState(PopupControlState aState)
    1755                 : {
    1756            8230 :   gPopupControlState = aState;
    1757            8230 : }
    1758                 : 
    1759                 : PopupControlState
    1760               0 : nsGlobalWindow::PushPopupControlState(PopupControlState aState,
    1761                 :                                       bool aForce) const
    1762                 : {
    1763               0 :   return ::PushPopupControlState(aState, aForce);
    1764                 : }
    1765                 : 
    1766                 : void
    1767               0 : nsGlobalWindow::PopPopupControlState(PopupControlState aState) const
    1768                 : {
    1769               0 :   ::PopPopupControlState(aState);
    1770               0 : }
    1771                 : 
    1772                 : PopupControlState
    1773               0 : nsGlobalWindow::GetPopupControlState() const
    1774                 : {
    1775               0 :   return gPopupControlState;
    1776                 : }
    1777                 : 
    1778                 : #define WINDOWSTATEHOLDER_IID \
    1779                 : {0x0b917c3e, 0xbd50, 0x4683, {0xaf, 0xc9, 0xc7, 0x81, 0x07, 0xae, 0x33, 0x26}}
    1780                 : 
    1781                 : class WindowStateHolder : public nsISupports
    1782                 : {
    1783                 : public:
    1784                 :   NS_DECLARE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID)
    1785                 :   NS_DECL_ISUPPORTS
    1786                 : 
    1787                 :   WindowStateHolder(nsGlobalWindow *aWindow,
    1788                 :                     nsIXPConnectJSObjectHolder *aHolder,
    1789                 :                     nsIXPConnectJSObjectHolder *aOuterProto,
    1790                 :                     nsIXPConnectJSObjectHolder *aOuterRealProto);
    1791                 : 
    1792               0 :   nsGlobalWindow* GetInnerWindow() { return mInnerWindow; }
    1793               0 :   nsIXPConnectJSObjectHolder *GetInnerWindowHolder()
    1794               0 :   { return mInnerWindowHolder; }
    1795                 : 
    1796                 :   nsIXPConnectJSObjectHolder* GetOuterProto() { return mOuterProto; }
    1797               0 :   nsIXPConnectJSObjectHolder* GetOuterRealProto() { return mOuterRealProto; }
    1798                 : 
    1799               0 :   void DidRestoreWindow()
    1800                 :   {
    1801               0 :     mInnerWindow = nsnull;
    1802                 : 
    1803               0 :     mInnerWindowHolder = nsnull;
    1804               0 :     mOuterProto = nsnull;
    1805               0 :     mOuterRealProto = nsnull;
    1806               0 :   }
    1807                 : 
    1808                 : protected:
    1809                 :   ~WindowStateHolder();
    1810                 : 
    1811                 :   nsGlobalWindow *mInnerWindow;
    1812                 :   // We hold onto this to make sure the inner window doesn't go away. The outer
    1813                 :   // window ends up recalculating it anyway.
    1814                 :   nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
    1815                 :   nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterProto;
    1816                 :   nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterRealProto;
    1817                 : };
    1818                 : 
    1819                 : NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID)
    1820                 : 
    1821               0 : WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow,
    1822                 :                                      nsIXPConnectJSObjectHolder *aHolder,
    1823                 :                                      nsIXPConnectJSObjectHolder *aOuterProto,
    1824                 :                                      nsIXPConnectJSObjectHolder *aOuterRealProto)
    1825                 :   : mInnerWindow(aWindow),
    1826                 :     mOuterProto(aOuterProto),
    1827               0 :     mOuterRealProto(aOuterRealProto)
    1828                 : {
    1829               0 :   NS_PRECONDITION(aWindow, "null window");
    1830               0 :   NS_PRECONDITION(aWindow->IsInnerWindow(), "Saving an outer window");
    1831                 : 
    1832               0 :   mInnerWindowHolder = aHolder;
    1833                 : 
    1834               0 :   aWindow->SuspendTimeouts();
    1835               0 : }
    1836                 : 
    1837               0 : WindowStateHolder::~WindowStateHolder()
    1838                 : {
    1839               0 :   if (mInnerWindow) {
    1840                 :     // This window was left in the bfcache and is now going away. We need to
    1841                 :     // free it up.
    1842                 :     // Note that FreeInnerObjects may already have been called on the
    1843                 :     // inner window if its outer has already had SetDocShell(null)
    1844                 :     // called.
    1845               0 :     mInnerWindow->FreeInnerObjects();
    1846                 :   }
    1847               0 : }
    1848                 : 
    1849               0 : NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
    1850                 : 
    1851                 : 
    1852                 : struct ReparentWaiverClosure
    1853                 : {
    1854                 :   JSContext *mCx;
    1855                 :   JSObject *mNewInner;
    1856                 : };
    1857                 : 
    1858                 : static JSDHashOperator
    1859               0 : ReparentWaiverWrappers(JSDHashTable *table, JSDHashEntryHdr *hdr,
    1860                 :                        uint32 number, void *arg)
    1861                 : {
    1862               0 :     ReparentWaiverClosure *closure = static_cast<ReparentWaiverClosure*>(arg);
    1863               0 :     JSObject *value = static_cast<JSObject2JSObjectMap::Entry *>(hdr)->value;
    1864                 : 
    1865                 :     // We reparent wrappers that have as their parent an inner window whose
    1866                 :     // outer has the new inner window as its current inner.
    1867               0 :     JSObject *parent = JS_GetParent(value);
    1868               0 :     JSObject *outer = JS_ObjectToOuterObject(closure->mCx, parent);
    1869               0 :     if (outer) {
    1870               0 :       JSObject *inner = JS_ObjectToInnerObject(closure->mCx, outer);
    1871               0 :       if (inner == closure->mNewInner && inner != parent)
    1872               0 :         JS_SetParent(closure->mCx, value, closure->mNewInner);
    1873                 :     } else {
    1874               0 :       JS_ClearPendingException(closure->mCx);
    1875                 :     }
    1876               0 :     return JS_DHASH_NEXT;
    1877                 : }
    1878                 : 
    1879                 : nsresult
    1880               0 : nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
    1881                 :                                nsISupports* aState,
    1882                 :                                bool aForceReuseInnerWindow)
    1883                 : {
    1884                 :   NS_TIME_FUNCTION;
    1885                 : 
    1886               0 :   NS_PRECONDITION(mDocumentPrincipal == nsnull,
    1887                 :                   "mDocumentPrincipal prematurely set!");
    1888                 : 
    1889               0 :   if (!aDocument) {
    1890               0 :     NS_ERROR("SetNewDocument(null) called!");
    1891                 : 
    1892               0 :     return NS_ERROR_INVALID_ARG;
    1893                 :   }
    1894                 : 
    1895               0 :   if (IsInnerWindow()) {
    1896               0 :     if (!mOuterWindow) {
    1897               0 :       return NS_ERROR_NOT_INITIALIZED;
    1898                 :     }
    1899                 : 
    1900                 :     // Refuse to set a new document if the call came from an inner
    1901                 :     // window that's not the current inner window.
    1902               0 :     if (mOuterWindow->GetCurrentInnerWindow() != this) {
    1903               0 :       return NS_ERROR_NOT_AVAILABLE;
    1904                 :     }
    1905                 : 
    1906               0 :     return GetOuterWindowInternal()->SetNewDocument(aDocument, aState,
    1907               0 :                                                     aForceReuseInnerWindow);
    1908                 :   }
    1909                 : 
    1910               0 :   NS_PRECONDITION(IsOuterWindow(), "Must only be called on outer windows");
    1911                 : 
    1912               0 :   if (IsFrozen()) {
    1913                 :     // This outer is now getting its first inner, thaw the outer now
    1914                 :     // that it's ready and is getting an inner window.
    1915                 : 
    1916               0 :     Thaw();
    1917                 :   }
    1918                 : 
    1919               0 :   NS_ASSERTION(!GetCurrentInnerWindow() ||
    1920                 :                GetCurrentInnerWindow()->GetExtantDocument() == mDocument,
    1921                 :                "Uh, mDocument doesn't match the current inner window "
    1922                 :                "document!");
    1923                 : 
    1924               0 :   bool wouldReuseInnerWindow = WouldReuseInnerWindow(aDocument);
    1925               0 :   if (aForceReuseInnerWindow &&
    1926               0 :       !wouldReuseInnerWindow &&
    1927               0 :       mDoc &&
    1928               0 :       mDoc->NodePrincipal() != aDocument->NodePrincipal()) {
    1929               0 :     NS_ERROR("Attempted forced inner window reuse while changing principal");
    1930               0 :     return NS_ERROR_UNEXPECTED;
    1931                 :   }
    1932                 : 
    1933               0 :   nsCOMPtr<nsIDocument> oldDoc(do_QueryInterface(mDocument));
    1934                 : 
    1935               0 :   nsIScriptContext *scx = GetContextInternal();
    1936               0 :   NS_ENSURE_TRUE(scx, NS_ERROR_NOT_INITIALIZED);
    1937                 : 
    1938               0 :   JSContext *cx = scx->GetNativeContext();
    1939                 : #ifndef MOZ_DISABLE_DOMCRYPTO
    1940                 :   // clear smartcard events, our document has gone away.
    1941               0 :   if (mCrypto) {
    1942               0 :     mCrypto->SetEnableSmartCardEvents(false);
    1943                 :   }
    1944                 : #endif
    1945               0 :   if (!mDocument) {
    1946                 :     // First document load.
    1947                 : 
    1948                 :     // Get our private root. If it is equal to us, then we need to
    1949                 :     // attach our global key bindings that handles browser scrolling
    1950                 :     // and other browser commands.
    1951               0 :     nsIDOMWindow* privateRoot = nsGlobalWindow::GetPrivateRoot();
    1952                 : 
    1953               0 :     if (privateRoot == static_cast<nsIDOMWindow*>(this)) {
    1954               0 :       nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1");
    1955               0 :       if (xblService) {
    1956               0 :         xblService->AttachGlobalKeyHandler(mChromeEventHandler);
    1957                 :       }
    1958                 :     }
    1959                 :   }
    1960                 : 
    1961                 :   /* No mDocShell means we're already been partially closed down.  When that
    1962                 :      happens, setting status isn't a big requirement, so don't. (Doesn't happen
    1963                 :      under normal circumstances, but bug 49615 describes a case.) */
    1964                 : 
    1965                 :   nsContentUtils::AddScriptRunner(
    1966               0 :     NS_NewRunnableMethod(this, &nsGlobalWindow::ClearStatus));
    1967                 : 
    1968               0 :   bool reUseInnerWindow = aForceReuseInnerWindow || wouldReuseInnerWindow;
    1969                 : 
    1970               0 :   nsresult rv = NS_OK;
    1971                 : 
    1972                 :   // Set mDocument even if this is an outer window to avoid
    1973                 :   // having to *always* reach into the inner window to find the
    1974                 :   // document.
    1975               0 :   mDocument = do_QueryInterface(aDocument);
    1976               0 :   mDoc = aDocument;
    1977                 : 
    1978                 : #ifdef DEBUG
    1979               0 :   mLastOpenedURI = aDocument->GetDocumentURI();
    1980                 : #endif
    1981                 : 
    1982               0 :   mContext->WillInitializeContext();
    1983                 : 
    1984               0 :   nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal();
    1985                 : 
    1986               0 :   nsRefPtr<nsGlobalWindow> newInnerWindow;
    1987               0 :   bool createdInnerWindow = false;
    1988                 : 
    1989               0 :   bool thisChrome = IsChromeWindow();
    1990                 : 
    1991               0 :   bool isChrome = false;
    1992                 : 
    1993               0 :   nsCxPusher cxPusher;
    1994               0 :   if (!cxPusher.Push(cx)) {
    1995               0 :     return NS_ERROR_FAILURE;
    1996                 :   }
    1997                 : 
    1998               0 :   JSAutoRequest ar(cx);
    1999                 : 
    2000               0 :   nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
    2001               0 :   NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
    2002                 : 
    2003               0 :   if (reUseInnerWindow) {
    2004                 :     // We're reusing the current inner window.
    2005               0 :     NS_ASSERTION(!currentInner->IsFrozen(),
    2006                 :                  "We should never be reusing a shared inner window");
    2007               0 :     newInnerWindow = currentInner;
    2008                 : 
    2009               0 :     if (aDocument != oldDoc) {
    2010               0 :       nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
    2011                 :     }
    2012                 : 
    2013                 :     // The API we're really looking for here is to go clear all of the
    2014                 :     // Xray wrappers associated with our outer window. However, we
    2015                 :     // don't expose that API because the implementation would be
    2016                 :     // identical to that of JS_TransplantObject, so we just call that
    2017                 :     // instead.
    2018               0 :     if (!JS_TransplantObject(cx, mJSObject, mJSObject)) {
    2019               0 :       return NS_ERROR_FAILURE;
    2020                 :     }
    2021                 :   } else {
    2022               0 :     if (aState) {
    2023               0 :       newInnerWindow = wsh->GetInnerWindow();
    2024               0 :       mInnerWindowHolder = wsh->GetInnerWindowHolder();
    2025                 : 
    2026               0 :       NS_ASSERTION(newInnerWindow, "Got a state without inner window");
    2027               0 :     } else if (thisChrome) {
    2028               0 :       newInnerWindow = new nsGlobalChromeWindow(this);
    2029               0 :       isChrome = true;
    2030               0 :     } else if (mIsModalContentWindow) {
    2031               0 :       newInnerWindow = new nsGlobalModalWindow(this);
    2032                 :     } else {
    2033               0 :       newInnerWindow = new nsGlobalWindow(this);
    2034                 :     }
    2035                 : 
    2036               0 :     if (!aState) {
    2037                 :       // This is redundant if we're restoring from a previous inner window.
    2038                 :       nsIScriptGlobalObject *sgo =
    2039               0 :         (nsIScriptGlobalObject *)newInnerWindow.get();
    2040                 : 
    2041                 :       // Freeze the outer window and null out the inner window so
    2042                 :       // that initializing classes on the new inner doesn't end up
    2043                 :       // reaching into the old inner window for classes etc.
    2044                 :       //
    2045                 :       // [This happens with Object.prototype when XPConnect creates
    2046                 :       // a temporary global while initializing classes; the reason
    2047                 :       // being that xpconnect creates the temp global w/o a parent
    2048                 :       // and proto, which makes the JS engine look up classes in
    2049                 :       // cx->globalObject, i.e. this outer window].
    2050                 : 
    2051               0 :       mInnerWindow = nsnull;
    2052                 : 
    2053               0 :       Freeze();
    2054               0 :       mCreatingInnerWindow = true;
    2055                 :       // Every script context we are initialized with must create a
    2056                 :       // new global.
    2057               0 :       nsCOMPtr<nsIXPConnectJSObjectHolder> &holder = mInnerWindowHolder;
    2058               0 :       rv = mContext->CreateNativeGlobalForInner(sgo, isChrome,
    2059                 :                                                 aDocument->NodePrincipal(),
    2060               0 :                                                 &newInnerWindow->mJSObject,
    2061               0 :                                                 getter_AddRefs(holder));
    2062               0 :       NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerWindow->mJSObject && holder,
    2063                 :                    "Failed to get script global and holder");
    2064                 : 
    2065               0 :       mCreatingInnerWindow = false;
    2066               0 :       createdInnerWindow = true;
    2067               0 :       Thaw();
    2068                 : 
    2069               0 :       NS_ENSURE_SUCCESS(rv, rv);
    2070                 :     }
    2071                 : 
    2072               0 :     if (currentInner && currentInner->mJSObject) {
    2073               0 :       if (oldDoc == aDocument) {
    2074                 :         // Move the navigator from the old inner window to the new one since
    2075                 :         // this is a document.write. This is safe from a same-origin point of
    2076                 :         // view because document.write can only be used by the same origin.
    2077               0 :         newInnerWindow->mNavigator = currentInner->mNavigator;
    2078               0 :         currentInner->mNavigator = nsnull;
    2079               0 :         if (newInnerWindow->mNavigator) {
    2080               0 :           newInnerWindow->mNavigator->SetWindow(newInnerWindow);
    2081                 :         }
    2082                 :       }
    2083                 : 
    2084                 :       // Don't free objects on our current inner window if it's going to be
    2085                 :       // held in the bfcache.
    2086               0 :       if (!currentInner->IsFrozen()) {
    2087               0 :         currentInner->FreeInnerObjects();
    2088                 :       }
    2089                 :     }
    2090                 : 
    2091               0 :     mInnerWindow = newInnerWindow;
    2092                 : 
    2093               0 :     if (!mJSObject) {
    2094               0 :       mContext->CreateOuterObject(this, newInnerWindow);
    2095               0 :       mContext->DidInitializeContext();
    2096                 : 
    2097               0 :       mJSObject = mContext->GetNativeGlobal();
    2098               0 :       SetWrapper(mJSObject);
    2099                 :     } else {
    2100                 :       JSObject *outerObject =
    2101               0 :         NS_NewOuterWindowProxy(cx, newInnerWindow->mJSObject);
    2102               0 :       if (!outerObject) {
    2103               0 :         NS_ERROR("out of memory");
    2104               0 :         return NS_ERROR_FAILURE;
    2105                 :       }
    2106                 : 
    2107               0 :       js::SetProxyExtra(mJSObject, 0, js::PrivateValue(NULL));
    2108                 : 
    2109               0 :       outerObject = JS_TransplantObject(cx, mJSObject, outerObject);
    2110               0 :       if (!outerObject) {
    2111               0 :         NS_ERROR("unable to transplant wrappers, probably OOM");
    2112               0 :         return NS_ERROR_FAILURE;
    2113                 :       }
    2114                 : 
    2115               0 :       nsIScriptGlobalObject *global = static_cast<nsIScriptGlobalObject*>(this);
    2116               0 :       js::SetProxyExtra(outerObject, 0, js::PrivateValue(global));
    2117                 : 
    2118               0 :       mJSObject = outerObject;
    2119               0 :       SetWrapper(mJSObject);
    2120                 : 
    2121                 :       {
    2122               0 :         JSAutoEnterCompartment ac;
    2123               0 :         if (!ac.enter(cx, mJSObject)) {
    2124               0 :           NS_ERROR("unable to enter a compartment");
    2125               0 :           return NS_ERROR_FAILURE;
    2126                 :         }
    2127                 : 
    2128               0 :         JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject);
    2129                 : 
    2130               0 :         mContext->SetOuterObject(mJSObject);
    2131                 : 
    2132               0 :         JSCompartment *compartment = js::GetObjectCompartment(mJSObject);
    2133                 :         xpc::CompartmentPrivate *priv =
    2134               0 :           static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
    2135               0 :         if (priv && priv->waiverWrapperMap) {
    2136               0 :           NS_ASSERTION(!JS_IsExceptionPending(cx),
    2137                 :                        "We might overwrite a pending exception!");
    2138                 :           ReparentWaiverClosure closure = {
    2139                 :             cx,
    2140               0 :             newInnerWindow->mJSObject
    2141               0 :           };
    2142               0 :           priv->waiverWrapperMap->Enumerate(ReparentWaiverWrappers, &closure);
    2143                 :         }
    2144                 :       }
    2145                 :     }
    2146                 : 
    2147                 :     // If we created a new inner window above, we need to do the last little bit
    2148                 :     // of initialization now that the dust has settled.
    2149               0 :     if (createdInnerWindow) {
    2150               0 :       nsIXPConnect *xpc = nsContentUtils::XPConnect();
    2151               0 :       nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
    2152               0 :       nsresult rv = xpc->GetWrappedNativeOfJSObject(cx, newInnerWindow->mJSObject,
    2153               0 :                                                     getter_AddRefs(wrapper));
    2154               0 :       NS_ENSURE_SUCCESS(rv, rv);
    2155               0 :       NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
    2156               0 :       rv = wrapper->FinishInitForWrappedGlobal();
    2157               0 :       NS_ENSURE_SUCCESS(rv, rv);
    2158                 :     }
    2159                 : 
    2160               0 :     JSAutoEnterCompartment ac;
    2161               0 :     if (!ac.enter(cx, mJSObject)) {
    2162               0 :       NS_ERROR("unable to enter a compartment");
    2163               0 :       return NS_ERROR_FAILURE;
    2164                 :     }
    2165                 : 
    2166                 :     // XXX Not sure if this is needed.
    2167               0 :     if (aState) {
    2168                 :       JSObject *proto;
    2169               0 :       if (nsIXPConnectJSObjectHolder *holder = wsh->GetOuterRealProto()) {
    2170               0 :         holder->GetJSObject(&proto);
    2171                 :       } else {
    2172               0 :         proto = nsnull;
    2173                 :       }
    2174                 : 
    2175               0 :       if (!JS_SetPrototype(cx, mJSObject, proto)) {
    2176               0 :         NS_ERROR("can't set prototype");
    2177               0 :         return NS_ERROR_FAILURE;
    2178                 :       }
    2179                 :     } else {
    2180               0 :       if (!JS_DefineProperty(cx, newInnerWindow->mJSObject, "window",
    2181               0 :                              OBJECT_TO_JSVAL(mJSObject),
    2182                 :                              JS_PropertyStub, JS_StrictPropertyStub,
    2183               0 :                              JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
    2184               0 :         NS_ERROR("can't create the 'window' property");
    2185               0 :         return NS_ERROR_FAILURE;
    2186                 :       }
    2187                 :     }
    2188                 :   }
    2189                 : 
    2190               0 :   JSAutoEnterCompartment ac;
    2191               0 :   if (!ac.enter(cx, mJSObject)) {
    2192               0 :     NS_ERROR("unable to enter a compartment");
    2193               0 :     return NS_ERROR_FAILURE;
    2194                 :   }
    2195                 : 
    2196               0 :   if (!aState && !reUseInnerWindow) {
    2197                 :     // Loading a new page and creating a new inner window, *not*
    2198                 :     // restoring from session history.
    2199                 : 
    2200                 :     // Now that both the the inner and outer windows are initialized
    2201                 :     // let the script context do its magic to hook them together.
    2202               0 :     mContext->ConnectToInner(newInnerWindow, mJSObject);
    2203                 : 
    2204               0 :     nsCOMPtr<nsIContent> frame = do_QueryInterface(GetFrameElementInternal());
    2205               0 :     if (frame && frame->OwnerDoc()) {
    2206               0 :       nsPIDOMWindow* parentWindow = frame->OwnerDoc()->GetWindow();
    2207               0 :       if (parentWindow && parentWindow->TimeoutSuspendCount()) {
    2208               0 :         SuspendTimeouts(parentWindow->TimeoutSuspendCount());
    2209                 :       }
    2210                 :     }
    2211                 :   }
    2212                 : 
    2213                 :   // Add an extra ref in case we release mContext during GC.
    2214               0 :   nsCOMPtr<nsIScriptContext> kungFuDeathGrip(mContext);
    2215                 : 
    2216                 :   // Now that the prototype is all set up, install the global scope
    2217                 :   // polluter. This must happen after the above prototype fixup. If
    2218                 :   // the GSP was to be installed on the inner window's real
    2219                 :   // prototype (as it would be if this was done before the prototype
    2220                 :   // fixup above) we would end up holding the GSP alive (through
    2221                 :   // XPConnect's internal marking of wrapper prototypes) as long as
    2222                 :   // the inner window was around, and if the GSP had properties on
    2223                 :   // it that held an element alive we'd hold the document alive,
    2224                 :   // which could hold event handlers alive, which hold the context
    2225                 :   // alive etc.
    2226                 : 
    2227               0 :   if ((!reUseInnerWindow || aDocument != oldDoc) && !aState) {
    2228               0 :     nsCOMPtr<nsIHTMLDocument> html_doc(do_QueryInterface(mDocument));
    2229               0 :     nsWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject,
    2230               0 :                                            html_doc);
    2231                 :   }
    2232                 : 
    2233               0 :   if (aDocument) {
    2234               0 :     aDocument->SetScriptGlobalObject(newInnerWindow);
    2235                 :   }
    2236                 : 
    2237               0 :   if (!aState) {
    2238               0 :     if (reUseInnerWindow) {
    2239               0 :       if (newInnerWindow->mDoc != aDocument) {
    2240               0 :         newInnerWindow->mDocument = do_QueryInterface(aDocument);
    2241               0 :         newInnerWindow->mDoc = aDocument;
    2242                 : 
    2243                 :         // We're reusing the inner window for a new document. In this
    2244                 :         // case we don't clear the inner window's scope, but we must
    2245                 :         // make sure the cached document property gets updated.
    2246                 : 
    2247                 :         // XXXmarkh - tell other languages about this?
    2248               0 :         ::JS_DeleteProperty(cx, currentInner->mJSObject, "document");
    2249                 : 
    2250               0 :         if (mDummyJavaPluginOwner) {
    2251                 :           // Since we're reusing the inner window, tear down the
    2252                 :           // dummy Java plugin we created for the old document in
    2253                 :           // this window.
    2254               0 :           mDummyJavaPluginOwner->Destroy();
    2255               0 :           mDummyJavaPluginOwner = nsnull;
    2256                 : 
    2257               0 :           mDidInitJavaProperties = false;
    2258                 :         }
    2259                 :       }
    2260                 :     } else {
    2261               0 :       rv = newInnerWindow->InnerSetNewDocument(aDocument);
    2262               0 :       NS_ENSURE_SUCCESS(rv, rv);
    2263                 : 
    2264                 :       // Initialize DOM classes etc on the inner window.
    2265               0 :       rv = mContext->InitClasses(newInnerWindow->mJSObject);
    2266               0 :       NS_ENSURE_SUCCESS(rv, rv);
    2267                 :     }
    2268                 : 
    2269               0 :     if (mArguments) {
    2270               0 :       newInnerWindow->DefineArgumentsProperty(mArguments);
    2271               0 :       newInnerWindow->mArguments = mArguments;
    2272               0 :       newInnerWindow->mArgumentsOrigin = mArgumentsOrigin;
    2273                 : 
    2274               0 :       mArguments = nsnull;
    2275               0 :       mArgumentsOrigin = nsnull;
    2276                 :     }
    2277                 : 
    2278                 :     // Give the new inner window our chrome event handler (since it
    2279                 :     // doesn't have one).
    2280               0 :     newInnerWindow->mChromeEventHandler = mChromeEventHandler;
    2281                 :   }
    2282                 : 
    2283               0 :   mContext->GC(js::gcreason::SET_NEW_DOCUMENT);
    2284               0 :   mContext->DidInitializeContext();
    2285                 : 
    2286               0 :   if (newInnerWindow && !newInnerWindow->mHasNotifiedGlobalCreated && mDoc) {
    2287                 :     // We should probably notify. However if this is the, arguably bad,
    2288                 :     // situation when we're creating a temporary non-chrome-about-blank
    2289                 :     // document in a chrome docshell, don't notify just yet. Instead wait
    2290                 :     // until we have a real chrome doc.
    2291               0 :     nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(mDocShell));
    2292               0 :     PRInt32 itemType = nsIDocShellTreeItem::typeContent;
    2293               0 :     if (treeItem) {
    2294               0 :       treeItem->GetItemType(&itemType);
    2295                 :     }
    2296                 : 
    2297               0 :     if (itemType != nsIDocShellTreeItem::typeChrome ||
    2298               0 :         nsContentUtils::IsSystemPrincipal(mDoc->NodePrincipal())) {
    2299               0 :       newInnerWindow->mHasNotifiedGlobalCreated = true;
    2300                 :       nsContentUtils::AddScriptRunner(
    2301               0 :         NS_NewRunnableMethod(this, &nsGlobalWindow::DispatchDOMWindowCreated));
    2302                 :     }
    2303                 :   }
    2304                 : 
    2305               0 :   return NS_OK;
    2306                 : }
    2307                 : 
    2308                 : void
    2309               0 : nsGlobalWindow::DispatchDOMWindowCreated()
    2310                 : {
    2311               0 :   if (!mDoc || !mDocument) {
    2312               0 :     return;
    2313                 :   }
    2314                 : 
    2315                 :   // Fire DOMWindowCreated at chrome event listeners
    2316               0 :   nsContentUtils::DispatchChromeEvent(mDoc, mDocument, NS_LITERAL_STRING("DOMWindowCreated"),
    2317                 :                                       true /* bubbles */,
    2318               0 :                                       false /* not cancellable */);
    2319                 : 
    2320                 :   nsCOMPtr<nsIObserverService> observerService =
    2321               0 :     mozilla::services::GetObserverService();
    2322               0 :   if (observerService) {
    2323               0 :     nsAutoString origin;
    2324               0 :     nsIPrincipal* principal = mDoc->NodePrincipal();
    2325               0 :     nsContentUtils::GetUTFOrigin(principal, origin);
    2326               0 :     observerService->
    2327                 :       NotifyObservers(static_cast<nsIDOMWindow*>(this),
    2328               0 :                       nsContentUtils::IsSystemPrincipal(principal) ?
    2329                 :                         "chrome-document-global-created" :
    2330                 :                         "content-document-global-created",
    2331               0 :                       origin.get());
    2332                 :   }
    2333                 : }
    2334                 : 
    2335                 : void
    2336               0 : nsGlobalWindow::ClearStatus()
    2337                 : {
    2338               0 :   SetStatus(EmptyString());
    2339               0 :   SetDefaultStatus(EmptyString());
    2340               0 : }
    2341                 : 
    2342                 : nsresult
    2343               0 : nsGlobalWindow::InnerSetNewDocument(nsIDocument* aDocument)
    2344                 : {
    2345               0 :   NS_PRECONDITION(IsInnerWindow(), "Must only be called on inner windows");
    2346                 : 
    2347                 : #ifdef PR_LOGGING
    2348               0 :   if (aDocument && gDOMLeakPRLog &&
    2349                 :       PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
    2350               0 :     nsIURI *uri = aDocument->GetDocumentURI();
    2351               0 :     nsCAutoString spec;
    2352               0 :     if (uri)
    2353               0 :       uri->GetSpec(spec);
    2354               0 :     PR_LogPrint("DOMWINDOW %p SetNewDocument %s", this, spec.get());
    2355                 :   }
    2356                 : #endif
    2357                 : 
    2358               0 :   mDocument = do_QueryInterface(aDocument);
    2359               0 :   mDoc = aDocument;
    2360               0 :   mFocusedNode = nsnull;
    2361               0 :   mLocalStorage = nsnull;
    2362               0 :   mSessionStorage = nsnull;
    2363                 : 
    2364                 : #ifdef DEBUG
    2365               0 :   mLastOpenedURI = aDocument->GetDocumentURI();
    2366                 : #endif
    2367                 : 
    2368                 :   Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
    2369               0 :                         mMutationBits ? 1 : 0);
    2370                 : 
    2371                 :   // Clear our mutation bitfield.
    2372               0 :   mMutationBits = 0;
    2373                 : 
    2374               0 :   return NS_OK;
    2375                 : }
    2376                 : 
    2377                 : void
    2378               0 : nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
    2379                 : {
    2380               0 :   NS_ASSERTION(IsOuterWindow(), "Uh, SetDocShell() called on inner window!");
    2381                 : 
    2382               0 :   if (aDocShell == mDocShell)
    2383               0 :     return;
    2384                 : 
    2385                 :   // SetDocShell(nsnull) means the window is being torn down. Drop our
    2386                 :   // reference to the script context, allowing it to be deleted
    2387                 :   // later. Meanwhile, keep our weak reference to the script object
    2388                 :   // (mJSObject) so that it can be retrieved later (until it is
    2389                 :   // finalized by the JS GC).
    2390                 : 
    2391               0 :   if (!aDocShell) {
    2392               0 :     NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts),
    2393                 :                  "Uh, outer window holds timeouts!");
    2394                 : 
    2395                 :     // Call FreeInnerObjects on all inner windows, not just the current
    2396                 :     // one, since some could be held by WindowStateHolder objects that
    2397                 :     // are GC-owned.
    2398               0 :     for (nsRefPtr<nsGlobalWindow> inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
    2399                 :          inner != this;
    2400               0 :          inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
    2401               0 :       NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == this,
    2402                 :                    "bad outer window pointer");
    2403               0 :       inner->FreeInnerObjects();
    2404                 :     }
    2405                 : 
    2406                 :     // Make sure that this is called before we null out the document.
    2407               0 :     NotifyDOMWindowDestroyed(this);
    2408                 : 
    2409               0 :     NotifyWindowIDDestroyed("outer-window-destroyed");
    2410                 : 
    2411               0 :     nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal();
    2412                 : 
    2413               0 :     if (currentInner) {
    2414               0 :       NS_ASSERTION(mDoc, "Must have doc!");
    2415                 :       
    2416                 :       // Remember the document's principal.
    2417               0 :       mDocumentPrincipal = mDoc->NodePrincipal();
    2418                 : 
    2419                 :       // Release our document reference
    2420               0 :       mDocument = nsnull;
    2421               0 :       mDoc = nsnull;
    2422               0 :       mFocusedNode = nsnull;
    2423                 :     }
    2424                 : 
    2425               0 :     ClearControllers();
    2426                 : 
    2427               0 :     mChromeEventHandler = nsnull; // force release now
    2428                 : 
    2429               0 :     if (mArguments) { 
    2430                 :       // We got no new document after someone called
    2431                 :       // SetArguments(), drop our reference to the arguments.
    2432               0 :       mArguments = nsnull;
    2433               0 :       mArgumentsLast = nsnull;
    2434               0 :       mArgumentsOrigin = nsnull;
    2435                 :     }
    2436                 : 
    2437               0 :     if (mContext) {
    2438               0 :       mContext->GC(js::gcreason::SET_DOC_SHELL);
    2439               0 :       mContext = nsnull;
    2440                 :     }
    2441                 : 
    2442                 : #ifdef DEBUG
    2443               0 :     nsCycleCollector_DEBUG_shouldBeFreed(mContext);
    2444               0 :     nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
    2445                 : #endif
    2446                 :   }
    2447                 : 
    2448               0 :   mDocShell = aDocShell;        // Weak Reference
    2449                 : 
    2450               0 :   NS_ASSERTION(!mNavigator, "Non-null mNavigator in outer window!");
    2451                 : 
    2452               0 :   if (mFrames)
    2453               0 :     mFrames->SetDocShell(aDocShell);
    2454               0 :   if (mScreen)
    2455               0 :     mScreen->SetDocShell(aDocShell);
    2456                 : 
    2457               0 :   if (!mDocShell) {
    2458               0 :     MaybeForgiveSpamCount();
    2459               0 :     CleanUp(false);
    2460                 :   } else {
    2461                 :     // Get our enclosing chrome shell and retrieve its global window impl, so
    2462                 :     // that we can do some forwarding to the chrome document.
    2463               0 :     nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
    2464               0 :     mDocShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
    2465               0 :     mChromeEventHandler = do_QueryInterface(chromeEventHandler);
    2466               0 :     if (!mChromeEventHandler) {
    2467                 :       // We have no chrome event handler. If we have a parent,
    2468                 :       // get our chrome event handler from the parent. If
    2469                 :       // we don't have a parent, then we need to make a new
    2470                 :       // window root object that will function as a chrome event
    2471                 :       // handler and receive all events that occur anywhere inside
    2472                 :       // our window.
    2473               0 :       nsCOMPtr<nsIDOMWindow> parentWindow;
    2474               0 :       GetParent(getter_AddRefs(parentWindow));
    2475               0 :       if (parentWindow.get() != static_cast<nsIDOMWindow*>(this)) {
    2476               0 :         nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(parentWindow));
    2477               0 :         mChromeEventHandler = piWindow->GetChromeEventHandler();
    2478                 :       }
    2479               0 :       else NS_NewWindowRoot(this, getter_AddRefs(mChromeEventHandler));
    2480                 :     }
    2481                 : 
    2482                 :     bool docShellActive;
    2483               0 :     mDocShell->GetIsActive(&docShellActive);
    2484               0 :     mIsBackground = !docShellActive;
    2485                 :   }
    2486                 : }
    2487                 : 
    2488                 : void
    2489               0 : nsGlobalWindow::SetOpenerWindow(nsIDOMWindow* aOpener,
    2490                 :                                 bool aOriginalOpener)
    2491                 : {
    2492               0 :   FORWARD_TO_OUTER_VOID(SetOpenerWindow, (aOpener, aOriginalOpener));
    2493                 : 
    2494               0 :   NS_ASSERTION(!aOriginalOpener || !mSetOpenerWindowCalled,
    2495                 :                "aOriginalOpener is true, but not first call to "
    2496                 :                "SetOpenerWindow!");
    2497               0 :   NS_ASSERTION(aOpener || !aOriginalOpener,
    2498                 :                "Shouldn't set mHadOriginalOpener if aOpener is null");
    2499                 : 
    2500               0 :   mOpener = do_GetWeakReference(aOpener);
    2501               0 :   NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
    2502                 : 
    2503               0 :   if (aOriginalOpener) {
    2504               0 :     mHadOriginalOpener = true;
    2505                 :   }
    2506                 : 
    2507                 : #ifdef DEBUG
    2508               0 :   mSetOpenerWindowCalled = true;
    2509                 : #endif
    2510                 : }
    2511                 : 
    2512                 : void
    2513               0 : nsGlobalWindow::UpdateParentTarget()
    2514                 : {
    2515               0 :   nsCOMPtr<nsIFrameLoaderOwner> flo = do_QueryInterface(mChromeEventHandler);
    2516               0 :   if (flo) {
    2517               0 :     nsRefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
    2518               0 :     if (fl) {
    2519               0 :       mParentTarget = fl->GetTabChildGlobalAsEventTarget();
    2520                 :     }
    2521                 :   }
    2522               0 :   if (!mParentTarget) {
    2523               0 :     mParentTarget = mChromeEventHandler;
    2524                 :   }
    2525               0 : }
    2526                 : 
    2527                 : bool
    2528               0 : nsGlobalWindow::GetIsTabModalPromptAllowed()
    2529                 : {
    2530               0 :   bool allowTabModal = true;
    2531               0 :   if (mDocShell) {
    2532               0 :     nsCOMPtr<nsIContentViewer> cv;
    2533               0 :     mDocShell->GetContentViewer(getter_AddRefs(cv));
    2534               0 :     cv->GetIsTabModalPromptAllowed(&allowTabModal);
    2535                 :   }
    2536                 : 
    2537               0 :   return allowTabModal;
    2538                 : }
    2539                 : 
    2540                 : nsIDOMEventTarget*
    2541               0 : nsGlobalWindow::GetTargetForDOMEvent()
    2542                 : {
    2543               0 :   return static_cast<nsIDOMEventTarget*>(GetOuterWindowInternal());
    2544                 : }
    2545                 : 
    2546                 : nsIDOMEventTarget*
    2547               0 : nsGlobalWindow::GetTargetForEventTargetChain()
    2548                 : {
    2549               0 :   return IsInnerWindow() ?
    2550               0 :     this : static_cast<nsIDOMEventTarget*>(GetCurrentInnerWindowInternal());
    2551                 : }
    2552                 : 
    2553                 : nsresult
    2554               0 : nsGlobalWindow::WillHandleEvent(nsEventChainPostVisitor& aVisitor)
    2555                 : {
    2556               0 :   return NS_OK;
    2557                 : }
    2558                 : 
    2559                 : JSContext*
    2560               0 : nsGlobalWindow::GetJSContextForEventHandlers()
    2561                 : {
    2562               0 :   return nsnull;
    2563                 : }
    2564                 : 
    2565                 : nsresult
    2566               0 : nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
    2567                 : {
    2568               0 :   NS_PRECONDITION(IsInnerWindow(), "PreHandleEvent is used on outer window!?");
    2569                 :   static PRUint32 count = 0;
    2570               0 :   PRUint32 msg = aVisitor.mEvent->message;
    2571                 : 
    2572               0 :   aVisitor.mCanHandle = true;
    2573               0 :   aVisitor.mForceContentDispatch = true; //FIXME! Bug 329119
    2574               0 :   if ((msg == NS_MOUSE_MOVE) && gEntropyCollector) {
    2575                 :     //Chances are this counter will overflow during the life of the
    2576                 :     //process, but that's OK for our case. Means we get a little
    2577                 :     //more entropy.
    2578               0 :     if (count++ % 100 == 0) {
    2579                 :       //Since the high bits seem to be zero's most of the time,
    2580                 :       //let's only take the lowest half of the point structure.
    2581                 :       PRInt16 myCoord[2];
    2582                 : 
    2583               0 :       myCoord[0] = aVisitor.mEvent->refPoint.x;
    2584               0 :       myCoord[1] = aVisitor.mEvent->refPoint.y;
    2585               0 :       gEntropyCollector->RandomUpdate((void*)myCoord, sizeof(myCoord));
    2586                 :       gEntropyCollector->RandomUpdate((void*)&(aVisitor.mEvent->time),
    2587               0 :                                       sizeof(PRUint32));
    2588               0 :     }
    2589               0 :   } else if (msg == NS_RESIZE_EVENT) {
    2590               0 :     mIsHandlingResizeEvent = true;
    2591               0 :   } else if (msg == NS_MOUSE_BUTTON_DOWN &&
    2592                 :              NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
    2593               0 :     gMouseDown = true;
    2594               0 :   } else if ((msg == NS_MOUSE_BUTTON_UP ||
    2595                 :               msg == NS_DRAGDROP_END) &&
    2596                 :              NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
    2597               0 :     gMouseDown = false;
    2598               0 :     if (gDragServiceDisabled) {
    2599                 :       nsCOMPtr<nsIDragService> ds =
    2600               0 :         do_GetService("@mozilla.org/widget/dragservice;1");
    2601               0 :       if (ds) {
    2602               0 :         gDragServiceDisabled = false;
    2603               0 :         ds->Unsuppress();
    2604                 :       }
    2605                 :     }
    2606                 :   }
    2607                 : 
    2608               0 :   aVisitor.mParentTarget = GetParentTarget();
    2609               0 :   return NS_OK;
    2610                 : }
    2611                 : 
    2612                 : bool
    2613               0 : nsGlobalWindow::DialogOpenAttempted()
    2614                 : {
    2615               0 :   nsGlobalWindow *topWindow = GetTop();
    2616               0 :   if (!topWindow) {
    2617               0 :     NS_ERROR("DialogOpenAttempted() called without a top window?");
    2618                 : 
    2619               0 :     return false;
    2620                 :   }
    2621                 : 
    2622               0 :   topWindow = topWindow->GetCurrentInnerWindowInternal();
    2623               0 :   if (!topWindow ||
    2624               0 :       topWindow->mLastDialogQuitTime.IsNull() ||
    2625               0 :       nsContentUtils::CallerHasUniversalXPConnect()) {
    2626               0 :     return false;
    2627                 :   }
    2628                 : 
    2629                 :   TimeDuration dialogDuration(TimeStamp::Now() -
    2630               0 :                               topWindow->mLastDialogQuitTime);
    2631                 : 
    2632               0 :   if (dialogDuration.ToSeconds() <
    2633                 :         Preferences::GetInt("dom.successive_dialog_time_limit",
    2634               0 :                             SUCCESSIVE_DIALOG_TIME_LIMIT)) {
    2635               0 :     topWindow->mDialogAbuseCount++;
    2636                 : 
    2637               0 :     return (topWindow->GetPopupControlState() > openAllowed ||
    2638               0 :             topWindow->mDialogAbuseCount > MAX_DIALOG_COUNT);
    2639                 :   }
    2640                 : 
    2641               0 :   topWindow->mDialogAbuseCount = 0;
    2642                 : 
    2643               0 :   return false;
    2644                 : }
    2645                 : 
    2646                 : bool
    2647               0 : nsGlobalWindow::AreDialogsBlocked()
    2648                 : {
    2649               0 :   nsGlobalWindow *topWindow = GetTop();
    2650               0 :   if (!topWindow) {
    2651               0 :     NS_ASSERTION(!mDocShell, "AreDialogsBlocked() called without a top window?");
    2652                 : 
    2653               0 :     return true;
    2654                 :   }
    2655                 : 
    2656               0 :   topWindow = topWindow->GetCurrentInnerWindowInternal();
    2657                 : 
    2658                 :   return !topWindow ||
    2659                 :          (topWindow->mDialogDisabled &&
    2660               0 :           (topWindow->GetPopupControlState() > openAllowed ||
    2661               0 :            topWindow->mDialogAbuseCount >= MAX_DIALOG_COUNT));
    2662                 : }
    2663                 : 
    2664                 : bool
    2665               0 : nsGlobalWindow::ConfirmDialogAllowed()
    2666                 : {
    2667               0 :   FORWARD_TO_OUTER(ConfirmDialogAllowed, (), false);
    2668                 : 
    2669               0 :   NS_ENSURE_TRUE(mDocShell, false);
    2670                 :   nsCOMPtr<nsIPromptService> promptSvc =
    2671               0 :     do_GetService("@mozilla.org/embedcomp/prompt-service;1");
    2672                 : 
    2673               0 :   if (!DialogOpenAttempted() || !promptSvc) {
    2674               0 :     return true;
    2675                 :   }
    2676                 : 
    2677                 :   // Reset popup state while opening a modal dialog, and firing events
    2678                 :   // about the dialog, to prevent the current state from being active
    2679                 :   // the whole time a modal dialog is open.
    2680               0 :   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
    2681                 : 
    2682               0 :   bool disableDialog = false;
    2683               0 :   nsXPIDLString label, title;
    2684                 :   nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    2685               0 :                                      "ScriptDialogLabel", label);
    2686                 :   nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    2687               0 :                                      "ScriptDialogPreventTitle", title);
    2688               0 :   promptSvc->Confirm(this, title.get(), label.get(), &disableDialog);
    2689               0 :   if (disableDialog) {
    2690               0 :     PreventFurtherDialogs();
    2691               0 :     return false;
    2692                 :   }
    2693                 : 
    2694               0 :   return true;
    2695                 : }
    2696                 : 
    2697                 : void
    2698               0 : nsGlobalWindow::PreventFurtherDialogs()
    2699                 : {
    2700               0 :   nsGlobalWindow *topWindow = GetTop();
    2701               0 :   if (!topWindow) {
    2702               0 :     NS_ERROR("PreventFurtherDialogs() called without a top window?");
    2703                 : 
    2704               0 :     return;
    2705                 :   }
    2706                 : 
    2707               0 :   topWindow = topWindow->GetCurrentInnerWindowInternal();
    2708                 : 
    2709               0 :   if (topWindow)
    2710               0 :     topWindow->mDialogDisabled = true;
    2711                 : }
    2712                 : 
    2713                 : nsresult
    2714               0 : nsGlobalWindow::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
    2715                 : {
    2716               0 :   NS_PRECONDITION(IsInnerWindow(), "PostHandleEvent is used on outer window!?");
    2717                 : 
    2718                 :   // Return early if there is nothing to do.
    2719               0 :   switch (aVisitor.mEvent->message) {
    2720                 :     case NS_RESIZE_EVENT:
    2721                 :     case NS_PAGE_UNLOAD:
    2722                 :     case NS_LOAD:
    2723                 :       break;
    2724                 :     default:
    2725               0 :       return NS_OK;
    2726                 :   }
    2727                 : 
    2728                 :   /* mChromeEventHandler and mContext go dangling in the middle of this
    2729                 :    function under some circumstances (events that destroy the window)
    2730                 :    without this addref. */
    2731               0 :   nsCOMPtr<nsIDOMEventTarget> kungFuDeathGrip1(mChromeEventHandler);
    2732               0 :   nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
    2733                 : 
    2734               0 :   if (aVisitor.mEvent->message == NS_RESIZE_EVENT) {
    2735               0 :     mIsHandlingResizeEvent = false;
    2736               0 :   } else if (aVisitor.mEvent->message == NS_PAGE_UNLOAD &&
    2737                 :              NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
    2738                 :     // Execute bindingdetached handlers before we tear ourselves
    2739                 :     // down.
    2740               0 :     if (mDocument) {
    2741               0 :       NS_ASSERTION(mDoc, "Must have doc");
    2742               0 :       mDoc->BindingManager()->ExecuteDetachedHandlers();
    2743                 :     }
    2744               0 :     mIsDocumentLoaded = false;
    2745               0 :   } else if (aVisitor.mEvent->message == NS_LOAD &&
    2746                 :              NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
    2747                 :     // This is page load event since load events don't propagate to |window|.
    2748                 :     // @see nsDocument::PreHandleEvent.
    2749               0 :     mIsDocumentLoaded = true;
    2750                 : 
    2751               0 :     nsCOMPtr<nsIContent> content(do_QueryInterface(GetFrameElementInternal()));
    2752                 :     nsCOMPtr<nsIDocShellTreeItem> treeItem =
    2753               0 :       do_QueryInterface(GetDocShell());
    2754                 : 
    2755               0 :     PRInt32 itemType = nsIDocShellTreeItem::typeChrome;
    2756                 : 
    2757               0 :     if (treeItem) {
    2758               0 :       treeItem->GetItemType(&itemType);
    2759                 :     }
    2760                 : 
    2761               0 :     if (content && GetParentInternal() &&
    2762                 :         itemType != nsIDocShellTreeItem::typeChrome) {
    2763                 :       // If we're not in chrome, or at a chrome boundary, fire the
    2764                 :       // onload event for the frame element.
    2765                 : 
    2766               0 :       nsEventStatus status = nsEventStatus_eIgnore;
    2767               0 :       nsEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_LOAD);
    2768               0 :       event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
    2769                 : 
    2770                 :       // Most of the time we could get a pres context to pass in here,
    2771                 :       // but not always (i.e. if this window is not shown there won't
    2772                 :       // be a pres context available). Since we're not firing a GUI
    2773                 :       // event we don't need a pres context anyway so we just pass
    2774                 :       // null as the pres context all the time here.
    2775               0 :       nsEventDispatcher::Dispatch(content, nsnull, &event, nsnull, &status);
    2776                 :     }
    2777                 :   }
    2778                 : 
    2779               0 :   return NS_OK;
    2780                 : }
    2781                 : 
    2782                 : nsresult
    2783               0 : nsGlobalWindow::DispatchDOMEvent(nsEvent* aEvent,
    2784                 :                                  nsIDOMEvent* aDOMEvent,
    2785                 :                                  nsPresContext* aPresContext,
    2786                 :                                  nsEventStatus* aEventStatus)
    2787                 : {
    2788                 :   return
    2789                 :     nsEventDispatcher::DispatchDOMEvent(static_cast<nsPIDOMWindow*>(this),
    2790                 :                                        aEvent, aDOMEvent, aPresContext,
    2791               0 :                                        aEventStatus);
    2792                 : }
    2793                 : 
    2794                 : void
    2795               0 : nsGlobalWindow::OnFinalize(JSObject* aObject)
    2796                 : {
    2797               0 :   if (aObject == mJSObject) {
    2798               0 :     mJSObject = NULL;
    2799                 :   }
    2800               0 : }
    2801                 : 
    2802                 : void
    2803               0 : nsGlobalWindow::SetScriptsEnabled(bool aEnabled, bool aFireTimeouts)
    2804                 : {
    2805               0 :   FORWARD_TO_INNER_VOID(SetScriptsEnabled, (aEnabled, aFireTimeouts));
    2806                 : 
    2807               0 :   if (aEnabled && aFireTimeouts) {
    2808                 :     // Scripts are enabled (again?) on this context, run timeouts that
    2809                 :     // fired on this context while scripts were disabled.
    2810               0 :     void (nsGlobalWindow::*run)() = &nsGlobalWindow::RunTimeout;
    2811               0 :     NS_DispatchToCurrentThread(NS_NewRunnableMethod(this, run));
    2812                 :   }
    2813                 : }
    2814                 : 
    2815                 : nsresult
    2816               0 : nsGlobalWindow::SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin)
    2817                 : {
    2818               0 :   FORWARD_TO_OUTER(SetArguments, (aArguments, aOrigin),
    2819                 :                    NS_ERROR_NOT_INITIALIZED);
    2820                 : 
    2821                 :   // Hold on to the arguments so that we can re-set them once the next
    2822                 :   // document is loaded.
    2823               0 :   mArguments = aArguments;
    2824               0 :   mArgumentsOrigin = aOrigin;
    2825                 : 
    2826               0 :   nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal();
    2827                 : 
    2828               0 :   if (!mIsModalContentWindow) {
    2829               0 :     mArgumentsLast = aArguments;
    2830               0 :   } else if (currentInner) {
    2831                 :     // SetArguments() is being called on a modal content window that
    2832                 :     // already has an inner window. This can happen when loading
    2833                 :     // javascript: URIs as modal content dialogs. In this case, we'll
    2834                 :     // set up the dialog window, both inner and outer, before we call
    2835                 :     // SetArguments() on the window, so to deal with that, make sure
    2836                 :     // here that the arguments are propagated to the inner window.
    2837                 : 
    2838               0 :     currentInner->mArguments = aArguments;
    2839               0 :     currentInner->mArgumentsOrigin = aOrigin;
    2840                 :   }
    2841                 : 
    2842                 :   return currentInner ?
    2843               0 :     currentInner->DefineArgumentsProperty(aArguments) : NS_OK;
    2844                 : }
    2845                 : 
    2846                 : nsresult
    2847               0 : nsGlobalWindow::DefineArgumentsProperty(nsIArray *aArguments)
    2848                 : {
    2849                 :   JSContext *cx;
    2850               0 :   nsIScriptContext *ctx = GetOuterWindowInternal()->mContext;
    2851               0 :   NS_ENSURE_TRUE(aArguments && ctx &&
    2852                 :                  (cx = ctx->GetNativeContext()),
    2853                 :                  NS_ERROR_NOT_INITIALIZED);
    2854                 : 
    2855               0 :   if (mIsModalContentWindow) {
    2856                 :     // Modal content windows don't have an "arguments" property, they
    2857                 :     // have a "dialogArguments" property which is handled
    2858                 :     // separately. See nsWindowSH::NewResolve().
    2859                 : 
    2860               0 :     return NS_OK;
    2861                 :   }
    2862                 : 
    2863               0 :   return GetContextInternal()->SetProperty(mJSObject, "arguments", aArguments);
    2864                 : }
    2865                 : 
    2866                 : //*****************************************************************************
    2867                 : // nsGlobalWindow::nsIScriptObjectPrincipal
    2868                 : //*****************************************************************************
    2869                 : 
    2870                 : nsIPrincipal*
    2871               0 : nsGlobalWindow::GetPrincipal()
    2872                 : {
    2873               0 :   if (mDoc) {
    2874                 :     // If we have a document, get the principal from the document
    2875               0 :     return mDoc->NodePrincipal();
    2876                 :   }
    2877                 : 
    2878               0 :   if (mDocumentPrincipal) {
    2879               0 :     return mDocumentPrincipal;
    2880                 :   }
    2881                 : 
    2882                 :   // If we don't have a principal and we don't have a document we
    2883                 :   // ask the parent window for the principal. This can happen when
    2884                 :   // loading a frameset that has a <frame src="javascript:xxx">, in
    2885                 :   // that case the global window is used in JS before we've loaded
    2886                 :   // a document into the window.
    2887                 : 
    2888                 :   nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
    2889               0 :     do_QueryInterface(GetParentInternal());
    2890                 : 
    2891               0 :   if (objPrincipal) {
    2892               0 :     return objPrincipal->GetPrincipal();
    2893                 :   }
    2894                 : 
    2895               0 :   return nsnull;
    2896                 : }
    2897                 : 
    2898                 : //*****************************************************************************
    2899                 : // nsGlobalWindow::nsIDOMWindow
    2900                 : //*****************************************************************************
    2901                 : 
    2902                 : NS_IMETHODIMP
    2903               0 : nsGlobalWindow::GetDocument(nsIDOMDocument** aDocument)
    2904                 : {
    2905                 :   // This method *should* forward calls to the outer window, but since
    2906                 :   // there's nothing here that *depends* on anything in the outer
    2907                 :   // (GetDocShell() eliminates that dependency), we won't do that to
    2908                 :   // avoid the extra virtual function call.
    2909                 : 
    2910                 :   // lazily instantiate an about:blank document if necessary, and if
    2911                 :   // we have what it takes to do so. Note that domdoc here is the same
    2912                 :   // thing as our mDocument, but we don't have to explicitly set the
    2913                 :   // member variable because the docshell has already called
    2914                 :   // SetNewDocument().
    2915                 :   nsIDocShell *docShell;
    2916               0 :   if (!mDocument && (docShell = GetDocShell()))
    2917               0 :     nsCOMPtr<nsIDOMDocument> domdoc(do_GetInterface(docShell));
    2918                 : 
    2919               0 :   NS_IF_ADDREF(*aDocument = mDocument);
    2920                 : 
    2921               0 :   return NS_OK;
    2922                 : }
    2923                 : 
    2924                 : NS_IMETHODIMP
    2925               0 : nsGlobalWindow::GetWindow(nsIDOMWindow** aWindow)
    2926                 : {
    2927               0 :   FORWARD_TO_OUTER(GetWindow, (aWindow), NS_ERROR_NOT_INITIALIZED);
    2928                 : 
    2929               0 :   *aWindow = static_cast<nsIDOMWindow*>(this);
    2930               0 :   NS_ADDREF(*aWindow);
    2931               0 :   return NS_OK;
    2932                 : }
    2933                 : 
    2934                 : NS_IMETHODIMP
    2935               0 : nsGlobalWindow::GetSelf(nsIDOMWindow** aWindow)
    2936                 : {
    2937               0 :   FORWARD_TO_OUTER(GetSelf, (aWindow), NS_ERROR_NOT_INITIALIZED);
    2938                 : 
    2939               0 :   *aWindow = static_cast<nsIDOMWindow*>(this);
    2940               0 :   NS_ADDREF(*aWindow);
    2941               0 :   return NS_OK;
    2942                 : }
    2943                 : 
    2944                 : NS_IMETHODIMP
    2945               0 : nsGlobalWindow::GetNavigator(nsIDOMNavigator** aNavigator)
    2946                 : {
    2947               0 :   FORWARD_TO_INNER(GetNavigator, (aNavigator), NS_ERROR_NOT_INITIALIZED);
    2948                 : 
    2949               0 :   *aNavigator = nsnull;
    2950                 : 
    2951               0 :   if (!mNavigator) {
    2952               0 :     mNavigator = new Navigator(this);
    2953                 :   }
    2954                 : 
    2955               0 :   NS_ADDREF(*aNavigator = mNavigator);
    2956                 : 
    2957               0 :   return NS_OK;
    2958                 : }
    2959                 : 
    2960                 : NS_IMETHODIMP
    2961               0 : nsGlobalWindow::GetScreen(nsIDOMScreen** aScreen)
    2962                 : {
    2963               0 :   FORWARD_TO_OUTER(GetScreen, (aScreen), NS_ERROR_NOT_INITIALIZED);
    2964                 : 
    2965               0 :   *aScreen = nsnull;
    2966                 : 
    2967               0 :   if (!mScreen && mDocShell) {
    2968               0 :     mScreen = new nsScreen(mDocShell);
    2969               0 :     if (!mScreen) {
    2970               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2971                 :     }
    2972                 :   }
    2973                 : 
    2974               0 :   NS_IF_ADDREF(*aScreen = mScreen);
    2975                 : 
    2976               0 :   return NS_OK;
    2977                 : }
    2978                 : 
    2979                 : NS_IMETHODIMP
    2980               0 : nsGlobalWindow::GetHistory(nsIDOMHistory** aHistory)
    2981                 : {
    2982               0 :   FORWARD_TO_INNER(GetHistory, (aHistory), NS_ERROR_NOT_INITIALIZED);
    2983                 : 
    2984               0 :   *aHistory = nsnull;
    2985                 : 
    2986               0 :   if (!mHistory) {
    2987               0 :     mHistory = new nsHistory(this);
    2988               0 :     if (!mHistory) {
    2989               0 :       return NS_ERROR_OUT_OF_MEMORY;
    2990                 :     }
    2991                 :   }
    2992                 : 
    2993               0 :   NS_IF_ADDREF(*aHistory = mHistory);
    2994               0 :   return NS_OK;
    2995                 : }
    2996                 : 
    2997                 : NS_IMETHODIMP
    2998               0 : nsGlobalWindow::GetPerformance(nsIDOMPerformance** aPerformance)
    2999                 : {
    3000               0 :   FORWARD_TO_INNER(GetPerformance, (aPerformance), NS_ERROR_NOT_INITIALIZED);
    3001                 : 
    3002               0 :   *aPerformance = nsnull;
    3003                 : 
    3004               0 :   if (nsGlobalWindow::HasPerformanceSupport()) {
    3005               0 :     if (!mPerformance) {
    3006               0 :       if (!mDoc) {
    3007               0 :         return NS_OK;
    3008                 :       }
    3009               0 :       nsRefPtr<nsDOMNavigationTiming> timing = mDoc->GetNavigationTiming();
    3010               0 :       nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(mDoc->GetChannel()));
    3011               0 :       bool timingEnabled = false;
    3012               0 :       if (!timedChannel ||
    3013               0 :           !NS_SUCCEEDED(timedChannel->GetTimingEnabled(&timingEnabled)) ||
    3014               0 :           !timingEnabled) {
    3015               0 :         timedChannel = nsnull;
    3016                 :       }
    3017               0 :       if (timing) {
    3018               0 :         mPerformance = new nsPerformance(timing, timedChannel);
    3019                 :       }
    3020                 :     }
    3021               0 :     NS_IF_ADDREF(*aPerformance = mPerformance);
    3022                 :   }
    3023               0 :   return NS_OK;
    3024                 : }
    3025                 : 
    3026                 : /**
    3027                 :  * GetScriptableParent is called when script reads window.parent.
    3028                 :  *
    3029                 :  * In contrast to GetRealParent, GetScriptableParent respects <iframe
    3030                 :  * mozbrowser> boundaries, so if |this| is contained by an <iframe
    3031                 :  * mozbrowser>, we will return |this| as its own parent.
    3032                 :  */
    3033                 : NS_IMETHODIMP
    3034               0 : nsGlobalWindow::GetScriptableParent(nsIDOMWindow** aParent)
    3035                 : {
    3036               0 :   FORWARD_TO_OUTER(GetScriptableParent, (aParent), NS_ERROR_NOT_INITIALIZED);
    3037                 : 
    3038               0 :   *aParent = NULL;
    3039               0 :   if (!mDocShell) {
    3040               0 :     return NS_OK;
    3041                 :   }
    3042                 : 
    3043               0 :   bool isMozBrowser = false;
    3044               0 :   mDocShell->GetIsBrowserFrame(&isMozBrowser);
    3045               0 :   if (isMozBrowser) {
    3046               0 :     nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
    3047               0 :     parent.swap(*aParent);
    3048               0 :     return NS_OK;
    3049                 :   }
    3050                 : 
    3051               0 :   return GetRealParent(aParent);
    3052                 : }
    3053                 : 
    3054                 : /**
    3055                 :  * nsIDOMWindow::GetParent (when called from C++) is just a wrapper around
    3056                 :  * GetRealParent.
    3057                 :  */
    3058                 : NS_IMETHODIMP
    3059               0 : nsGlobalWindow::GetRealParent(nsIDOMWindow** aParent)
    3060                 : {
    3061               0 :   FORWARD_TO_OUTER(GetRealParent, (aParent), NS_ERROR_NOT_INITIALIZED);
    3062                 : 
    3063               0 :   *aParent = nsnull;
    3064               0 :   if (!mDocShell) {
    3065               0 :     return NS_OK;
    3066                 :   }
    3067                 : 
    3068               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    3069               0 :   NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
    3070                 : 
    3071               0 :   nsCOMPtr<nsIDocShellTreeItem> parent;
    3072               0 :   docShellAsItem->GetSameTypeParent(getter_AddRefs(parent));
    3073                 : 
    3074               0 :   if (parent) {
    3075               0 :     nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(parent));
    3076               0 :     NS_ENSURE_SUCCESS(CallQueryInterface(globalObject.get(), aParent),
    3077                 :                       NS_ERROR_FAILURE);
    3078                 :   }
    3079                 :   else {
    3080               0 :     *aParent = static_cast<nsIDOMWindow*>(this);
    3081               0 :     NS_ADDREF(*aParent);
    3082                 :   }
    3083               0 :   return NS_OK;
    3084                 : }
    3085                 : 
    3086                 : /**
    3087                 :  * GetScriptableTop is called when script reads window.top.
    3088                 :  *
    3089                 :  * In contrast to GetRealTop, GetScriptableTop respects <iframe mozbrowser>
    3090                 :  * boundaries.  If we encounter a window owned by an <iframe mozbrowser> while
    3091                 :  * walking up the window hierarchy, we'll stop and return that window.
    3092                 :  */
    3093                 : NS_IMETHODIMP
    3094               0 : nsGlobalWindow::GetScriptableTop(nsIDOMWindow **aTop)
    3095                 : {
    3096               0 :   return GetTopImpl(aTop, /* aScriptable = */ true);
    3097                 : }
    3098                 : 
    3099                 : /**
    3100                 :  * nsIDOMWindow::GetTop (when called from C++) is just a wrapper around
    3101                 :  * GetRealTop.
    3102                 :  */
    3103                 : NS_IMETHODIMP
    3104               0 : nsGlobalWindow::GetRealTop(nsIDOMWindow** aTop)
    3105                 : {
    3106               0 :   return GetTopImpl(aTop, /* aScriptable = */ false);
    3107                 : }
    3108                 : 
    3109                 : nsresult
    3110               0 : nsGlobalWindow::GetTopImpl(nsIDOMWindow** aTop, bool aScriptable)
    3111                 : {
    3112               0 :   FORWARD_TO_OUTER(GetTopImpl, (aTop, aScriptable), NS_ERROR_NOT_INITIALIZED);
    3113               0 :   *aTop = nsnull;
    3114                 : 
    3115                 :   // Walk up the parent chain.
    3116                 : 
    3117               0 :   nsCOMPtr<nsIDOMWindow> prevParent = this;
    3118               0 :   nsCOMPtr<nsIDOMWindow> parent = this;
    3119               0 :   do {
    3120               0 :     if (!parent) {
    3121               0 :       break;
    3122                 :     }
    3123                 : 
    3124               0 :     prevParent = parent;
    3125                 : 
    3126               0 :     nsCOMPtr<nsIDOMWindow> newParent;
    3127                 :     nsresult rv;
    3128               0 :     if (aScriptable) {
    3129               0 :       rv = parent->GetScriptableParent(getter_AddRefs(newParent));
    3130                 :     }
    3131                 :     else {
    3132               0 :       rv = parent->GetParent(getter_AddRefs(newParent));
    3133                 :     }
    3134               0 :     NS_ENSURE_SUCCESS(rv, rv);
    3135                 : 
    3136               0 :     parent = newParent;
    3137                 : 
    3138                 :   } while (parent != prevParent);
    3139                 : 
    3140               0 :   if (parent) {
    3141               0 :     parent.swap(*aTop);
    3142                 :   }
    3143                 : 
    3144               0 :   return NS_OK;
    3145                 : }
    3146                 : 
    3147                 : NS_IMETHODIMP
    3148               0 : nsGlobalWindow::GetContent(nsIDOMWindow** aContent)
    3149                 : {
    3150               0 :   FORWARD_TO_OUTER(GetContent, (aContent), NS_ERROR_NOT_INITIALIZED);
    3151                 : 
    3152               0 :   *aContent = nsnull;
    3153                 : 
    3154               0 :   nsCOMPtr<nsIDocShellTreeItem> primaryContent;
    3155                 : 
    3156               0 :   if (!nsContentUtils::IsCallerChrome()) {
    3157                 :     // If we're called by non-chrome code, make sure we don't return
    3158                 :     // the primary content window if the calling tab is hidden. In
    3159                 :     // such a case we return the same-type root in the hidden tab,
    3160                 :     // which is "good enough", for now.
    3161               0 :     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mDocShell));
    3162                 : 
    3163               0 :     if (baseWin) {
    3164               0 :       bool visible = false;
    3165               0 :       baseWin->GetVisibility(&visible);
    3166                 : 
    3167               0 :       if (!visible) {
    3168               0 :         nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(mDocShell));
    3169                 : 
    3170               0 :         treeItem->GetSameTypeRootTreeItem(getter_AddRefs(primaryContent));
    3171                 :       }
    3172                 :     }
    3173                 :   }
    3174                 : 
    3175               0 :   if (!primaryContent) {
    3176               0 :     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    3177               0 :     GetTreeOwner(getter_AddRefs(treeOwner));
    3178               0 :     NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
    3179                 : 
    3180               0 :     treeOwner->GetPrimaryContentShell(getter_AddRefs(primaryContent));
    3181                 :   }
    3182                 : 
    3183               0 :   nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(primaryContent));
    3184               0 :   NS_IF_ADDREF(*aContent = domWindow);
    3185                 : 
    3186               0 :   return NS_OK;
    3187                 : }
    3188                 : 
    3189                 : NS_IMETHODIMP
    3190               0 : nsGlobalWindow::GetPrompter(nsIPrompt** aPrompt)
    3191                 : {
    3192               0 :   FORWARD_TO_OUTER(GetPrompter, (aPrompt), NS_ERROR_NOT_INITIALIZED);
    3193                 : 
    3194               0 :   if (!mDocShell)
    3195               0 :     return NS_ERROR_FAILURE;
    3196                 : 
    3197               0 :   nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
    3198               0 :   NS_ENSURE_TRUE(prompter, NS_ERROR_NO_INTERFACE);
    3199                 : 
    3200               0 :   NS_ADDREF(*aPrompt = prompter);
    3201               0 :   return NS_OK;
    3202                 : }
    3203                 : 
    3204                 : NS_IMETHODIMP
    3205               0 : nsGlobalWindow::GetMenubar(nsIDOMBarProp** aMenubar)
    3206                 : {
    3207               0 :   FORWARD_TO_OUTER(GetMenubar, (aMenubar), NS_ERROR_NOT_INITIALIZED);
    3208                 : 
    3209               0 :   *aMenubar = nsnull;
    3210                 : 
    3211               0 :   if (!mMenubar) {
    3212               0 :     mMenubar = new nsMenubarProp(this);
    3213               0 :     if (!mMenubar) {
    3214               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3215                 :     }
    3216                 :   }
    3217                 : 
    3218               0 :   NS_ADDREF(*aMenubar = mMenubar);
    3219                 : 
    3220               0 :   return NS_OK;
    3221                 : }
    3222                 : 
    3223                 : NS_IMETHODIMP
    3224               0 : nsGlobalWindow::GetToolbar(nsIDOMBarProp** aToolbar)
    3225                 : {
    3226               0 :   FORWARD_TO_OUTER(GetToolbar, (aToolbar), NS_ERROR_NOT_INITIALIZED);
    3227                 : 
    3228               0 :   *aToolbar = nsnull;
    3229                 : 
    3230               0 :   if (!mToolbar) {
    3231               0 :     mToolbar = new nsToolbarProp(this);
    3232               0 :     if (!mToolbar) {
    3233               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3234                 :     }
    3235                 :   }
    3236                 : 
    3237               0 :   NS_ADDREF(*aToolbar = mToolbar);
    3238                 : 
    3239               0 :   return NS_OK;
    3240                 : }
    3241                 : 
    3242                 : NS_IMETHODIMP
    3243               0 : nsGlobalWindow::GetLocationbar(nsIDOMBarProp** aLocationbar)
    3244                 : {
    3245               0 :   FORWARD_TO_OUTER(GetLocationbar, (aLocationbar), NS_ERROR_NOT_INITIALIZED);
    3246                 : 
    3247               0 :   *aLocationbar = nsnull;
    3248                 : 
    3249               0 :   if (!mLocationbar) {
    3250               0 :     mLocationbar = new nsLocationbarProp(this);
    3251               0 :     if (!mLocationbar) {
    3252               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3253                 :     }
    3254                 :   }
    3255                 : 
    3256               0 :   NS_ADDREF(*aLocationbar = mLocationbar);
    3257                 : 
    3258               0 :   return NS_OK;
    3259                 : }
    3260                 : 
    3261                 : NS_IMETHODIMP
    3262               0 : nsGlobalWindow::GetPersonalbar(nsIDOMBarProp** aPersonalbar)
    3263                 : {
    3264               0 :   FORWARD_TO_OUTER(GetPersonalbar, (aPersonalbar), NS_ERROR_NOT_INITIALIZED);
    3265                 : 
    3266               0 :   *aPersonalbar = nsnull;
    3267                 : 
    3268               0 :   if (!mPersonalbar) {
    3269               0 :     mPersonalbar = new nsPersonalbarProp(this);
    3270               0 :     if (!mPersonalbar) {
    3271               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3272                 :     }
    3273                 :   }
    3274                 : 
    3275               0 :   NS_ADDREF(*aPersonalbar = mPersonalbar);
    3276                 : 
    3277               0 :   return NS_OK;
    3278                 : }
    3279                 : 
    3280                 : NS_IMETHODIMP
    3281               0 : nsGlobalWindow::GetStatusbar(nsIDOMBarProp** aStatusbar)
    3282                 : {
    3283               0 :   FORWARD_TO_OUTER(GetStatusbar, (aStatusbar), NS_ERROR_NOT_INITIALIZED);
    3284                 : 
    3285               0 :   *aStatusbar = nsnull;
    3286                 : 
    3287               0 :   if (!mStatusbar) {
    3288               0 :     mStatusbar = new nsStatusbarProp(this);
    3289               0 :     if (!mStatusbar) {
    3290               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3291                 :     }
    3292                 :   }
    3293                 : 
    3294               0 :   NS_ADDREF(*aStatusbar = mStatusbar);
    3295                 : 
    3296               0 :   return NS_OK;
    3297                 : }
    3298                 : 
    3299                 : NS_IMETHODIMP
    3300               0 : nsGlobalWindow::GetScrollbars(nsIDOMBarProp** aScrollbars)
    3301                 : {
    3302               0 :   FORWARD_TO_OUTER(GetScrollbars, (aScrollbars), NS_ERROR_NOT_INITIALIZED);
    3303                 : 
    3304               0 :   *aScrollbars = nsnull;
    3305                 : 
    3306               0 :   if (!mScrollbars) {
    3307               0 :     mScrollbars = new nsScrollbarsProp(this);
    3308               0 :     if (!mScrollbars) {
    3309               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3310                 :     }
    3311                 :   }
    3312                 : 
    3313               0 :   NS_ADDREF(*aScrollbars = mScrollbars);
    3314                 : 
    3315               0 :   return NS_OK;
    3316                 : }
    3317                 : 
    3318                 : NS_IMETHODIMP
    3319               0 : nsGlobalWindow::GetClosed(bool* aClosed)
    3320                 : {
    3321               0 :   FORWARD_TO_OUTER(GetClosed, (aClosed), NS_ERROR_NOT_INITIALIZED);
    3322                 : 
    3323                 :   // If someone called close(), or if we don't have a docshell, we're
    3324                 :   // closed.
    3325               0 :   *aClosed = mIsClosed || !mDocShell;
    3326                 : 
    3327               0 :   return NS_OK;
    3328                 : }
    3329                 : 
    3330                 : NS_IMETHODIMP
    3331               0 : nsGlobalWindow::GetFrames(nsIDOMWindowCollection** aFrames)
    3332                 : {
    3333               0 :   FORWARD_TO_OUTER(GetFrames, (aFrames), NS_ERROR_NOT_INITIALIZED);
    3334                 : 
    3335               0 :   *aFrames = nsnull;
    3336                 : 
    3337               0 :   if (!mFrames && mDocShell) {
    3338               0 :     mFrames = new nsDOMWindowList(mDocShell);
    3339               0 :     if (!mFrames) {
    3340               0 :       return NS_ERROR_OUT_OF_MEMORY;
    3341                 :     }
    3342                 :   }
    3343                 : 
    3344               0 :   *aFrames = static_cast<nsIDOMWindowCollection *>(mFrames);
    3345               0 :   NS_IF_ADDREF(*aFrames);
    3346               0 :   return NS_OK;
    3347                 : }
    3348                 : 
    3349                 : NS_IMETHODIMP
    3350               0 : nsGlobalWindow::GetApplicationCache(nsIDOMOfflineResourceList **aApplicationCache)
    3351                 : {
    3352               0 :   FORWARD_TO_INNER(GetApplicationCache, (aApplicationCache), NS_ERROR_UNEXPECTED);
    3353                 : 
    3354               0 :   NS_ENSURE_ARG_POINTER(aApplicationCache);
    3355                 : 
    3356               0 :   if (!mApplicationCache) {
    3357               0 :     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(GetDocShell()));
    3358               0 :     if (!webNav) {
    3359               0 :       return NS_ERROR_FAILURE;
    3360                 :     }
    3361                 : 
    3362               0 :     nsCOMPtr<nsIURI> uri;
    3363               0 :     nsresult rv = webNav->GetCurrentURI(getter_AddRefs(uri));
    3364               0 :     NS_ENSURE_SUCCESS(rv, rv);
    3365                 : 
    3366               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
    3367               0 :     nsCOMPtr<nsIURI> manifestURI;
    3368               0 :     nsContentUtils::GetOfflineAppManifest(doc, getter_AddRefs(manifestURI));
    3369                 : 
    3370                 :     nsRefPtr<nsDOMOfflineResourceList> applicationCache =
    3371               0 :       new nsDOMOfflineResourceList(manifestURI, uri, this);
    3372               0 :     NS_ENSURE_TRUE(applicationCache, NS_ERROR_OUT_OF_MEMORY);
    3373                 : 
    3374               0 :     applicationCache->Init();
    3375                 : 
    3376               0 :     mApplicationCache = applicationCache;
    3377                 :   }
    3378                 : 
    3379               0 :   NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
    3380                 : 
    3381               0 :   return NS_OK;
    3382                 : }
    3383                 : 
    3384                 : NS_IMETHODIMP
    3385               0 : nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto)
    3386                 : {
    3387                 : #ifdef MOZ_DISABLE_DOMCRYPTO
    3388                 :   return NS_ERROR_NOT_IMPLEMENTED;
    3389                 : #else
    3390               0 :   FORWARD_TO_OUTER(GetCrypto, (aCrypto), NS_ERROR_NOT_INITIALIZED);
    3391                 : 
    3392               0 :   if (!mCrypto) {
    3393               0 :     mCrypto = do_CreateInstance(kCryptoContractID);
    3394                 :   }
    3395                 : 
    3396               0 :   NS_IF_ADDREF(*aCrypto = mCrypto);
    3397                 : 
    3398               0 :   return NS_OK;
    3399                 : #endif
    3400                 : }
    3401                 : 
    3402                 : NS_IMETHODIMP
    3403               0 : nsGlobalWindow::GetPkcs11(nsIDOMPkcs11** aPkcs11)
    3404                 : {
    3405               0 :   *aPkcs11 = nsnull;
    3406               0 :   return NS_OK;
    3407                 : }
    3408                 : 
    3409                 : NS_IMETHODIMP
    3410               0 : nsGlobalWindow::GetControllers(nsIControllers** aResult)
    3411                 : {
    3412               0 :   FORWARD_TO_OUTER(GetControllers, (aResult), NS_ERROR_NOT_INITIALIZED);
    3413                 : 
    3414               0 :   if (!mControllers) {
    3415                 :     nsresult rv;
    3416               0 :     mControllers = do_CreateInstance(kXULControllersCID, &rv);
    3417               0 :     NS_ENSURE_SUCCESS(rv, rv);
    3418                 : 
    3419                 :     // Add in the default controller
    3420                 :     nsCOMPtr<nsIController> controller = do_CreateInstance(
    3421               0 :                                NS_WINDOWCONTROLLER_CONTRACTID, &rv);
    3422               0 :     NS_ENSURE_SUCCESS(rv, rv);
    3423                 :     
    3424               0 :     mControllers->InsertControllerAt(0, controller);
    3425               0 :     nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller);
    3426               0 :     if (!controllerContext) return NS_ERROR_FAILURE;
    3427                 : 
    3428               0 :     controllerContext->SetCommandContext(static_cast<nsIDOMWindow*>(this));
    3429                 :   }
    3430                 : 
    3431               0 :   *aResult = mControllers;
    3432               0 :   NS_ADDREF(*aResult);
    3433               0 :   return NS_OK;
    3434                 : }
    3435                 : 
    3436                 : NS_IMETHODIMP
    3437               0 : nsGlobalWindow::GetOpener(nsIDOMWindow** aOpener)
    3438                 : {
    3439               0 :   FORWARD_TO_OUTER(GetOpener, (aOpener), NS_ERROR_NOT_INITIALIZED);
    3440                 : 
    3441               0 :   *aOpener = nsnull;
    3442                 : 
    3443               0 :   nsCOMPtr<nsPIDOMWindow> opener = do_QueryReferent(mOpener);
    3444               0 :   if (!opener) {
    3445               0 :     return NS_OK;
    3446                 :   }
    3447                 : 
    3448                 :   // First, check if we were called from a privileged chrome script
    3449               0 :   if (nsContentUtils::IsCallerTrustedForRead()) {
    3450               0 :     NS_ADDREF(*aOpener = opener);
    3451               0 :     return NS_OK;
    3452                 :   }
    3453                 : 
    3454               0 :   nsCOMPtr<nsPIDOMWindow> openerPwin(do_QueryInterface(opener));
    3455               0 :   if (!openerPwin) {
    3456               0 :     return NS_OK;
    3457                 :   }
    3458                 : 
    3459                 :   // First, ensure that we're not handing back a chrome window.
    3460               0 :   nsGlobalWindow *win = static_cast<nsGlobalWindow *>(openerPwin.get());
    3461               0 :   if (win->IsChromeWindow()) {
    3462               0 :     return NS_OK;
    3463                 :   }
    3464                 : 
    3465                 :   // We don't want to reveal the opener if the opener is a mail window,
    3466                 :   // because opener can be used to spoof the contents of a message (bug 105050).
    3467                 :   // So, we look in the opener's root docshell to see if it's a mail window.
    3468                 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
    3469               0 :     do_QueryInterface(openerPwin->GetDocShell());
    3470                 : 
    3471               0 :   if (docShellAsItem) {
    3472               0 :     nsCOMPtr<nsIDocShellTreeItem> openerRootItem;
    3473               0 :     docShellAsItem->GetRootTreeItem(getter_AddRefs(openerRootItem));
    3474               0 :     nsCOMPtr<nsIDocShell> openerRootDocShell(do_QueryInterface(openerRootItem));
    3475               0 :     if (openerRootDocShell) {
    3476                 :       PRUint32 appType;
    3477               0 :       nsresult rv = openerRootDocShell->GetAppType(&appType);
    3478               0 :       if (NS_SUCCEEDED(rv) && appType != nsIDocShell::APP_TYPE_MAIL) {
    3479               0 :         *aOpener = opener;
    3480                 :       }
    3481                 :     }
    3482                 :   }
    3483                 : 
    3484               0 :   NS_IF_ADDREF(*aOpener);
    3485               0 :   return NS_OK;
    3486                 : }
    3487                 : 
    3488                 : NS_IMETHODIMP
    3489               0 : nsGlobalWindow::SetOpener(nsIDOMWindow* aOpener)
    3490                 : {
    3491                 :   // check if we were called from a privileged chrome script.
    3492                 :   // If not, opener is settable only to null.
    3493               0 :   if (aOpener && !nsContentUtils::IsCallerTrustedForWrite()) {
    3494               0 :     return NS_OK;
    3495                 :   }
    3496                 : 
    3497               0 :   SetOpenerWindow(aOpener, false);
    3498                 : 
    3499               0 :   return NS_OK;
    3500                 : }
    3501                 : 
    3502                 : NS_IMETHODIMP
    3503               0 : nsGlobalWindow::GetStatus(nsAString& aStatus)
    3504                 : {
    3505               0 :   FORWARD_TO_OUTER(GetStatus, (aStatus), NS_ERROR_NOT_INITIALIZED);
    3506                 : 
    3507               0 :   aStatus = mStatus;
    3508               0 :   return NS_OK;
    3509                 : }
    3510                 : 
    3511                 : NS_IMETHODIMP
    3512               0 : nsGlobalWindow::SetStatus(const nsAString& aStatus)
    3513                 : {
    3514               0 :   FORWARD_TO_OUTER(SetStatus, (aStatus), NS_ERROR_NOT_INITIALIZED);
    3515                 : 
    3516                 :   /*
    3517                 :    * If caller is not chrome and dom.disable_window_status_change is true,
    3518                 :    * prevent setting window.status by exiting early
    3519                 :    */
    3520                 : 
    3521               0 :   if (!CanSetProperty("dom.disable_window_status_change")) {
    3522               0 :     return NS_OK;
    3523                 :   }
    3524                 : 
    3525               0 :   mStatus = aStatus;
    3526                 : 
    3527               0 :   nsCOMPtr<nsIWebBrowserChrome> browserChrome;
    3528               0 :   GetWebBrowserChrome(getter_AddRefs(browserChrome));
    3529               0 :   if(browserChrome) {
    3530               0 :     browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT,
    3531               0 :                              PromiseFlatString(aStatus).get());
    3532                 :   }
    3533                 : 
    3534               0 :   return NS_OK;
    3535                 : }
    3536                 : 
    3537                 : NS_IMETHODIMP
    3538               0 : nsGlobalWindow::GetDefaultStatus(nsAString& aDefaultStatus)
    3539                 : {
    3540               0 :   FORWARD_TO_OUTER(GetDefaultStatus, (aDefaultStatus),
    3541                 :                    NS_ERROR_NOT_INITIALIZED);
    3542                 : 
    3543               0 :   aDefaultStatus = mDefaultStatus;
    3544               0 :   return NS_OK;
    3545                 : }
    3546                 : 
    3547                 : NS_IMETHODIMP
    3548               0 : nsGlobalWindow::SetDefaultStatus(const nsAString& aDefaultStatus)
    3549                 : {
    3550               0 :   FORWARD_TO_OUTER(SetDefaultStatus, (aDefaultStatus),
    3551                 :                    NS_ERROR_NOT_INITIALIZED);
    3552                 : 
    3553                 :   /*
    3554                 :    * If caller is not chrome and dom.disable_window_status_change is true,
    3555                 :    * prevent setting window.defaultStatus by exiting early
    3556                 :    */
    3557                 : 
    3558               0 :   if (!CanSetProperty("dom.disable_window_status_change")) {
    3559               0 :     return NS_OK;
    3560                 :   }
    3561                 : 
    3562               0 :   mDefaultStatus = aDefaultStatus;
    3563                 : 
    3564               0 :   nsCOMPtr<nsIWebBrowserChrome> browserChrome;
    3565               0 :   GetWebBrowserChrome(getter_AddRefs(browserChrome));
    3566               0 :   if (browserChrome) {
    3567               0 :     browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_SCRIPT_DEFAULT,
    3568               0 :                              PromiseFlatString(aDefaultStatus).get());
    3569                 :   }
    3570                 : 
    3571               0 :   return NS_OK;
    3572                 : }
    3573                 : 
    3574                 : NS_IMETHODIMP
    3575               0 : nsGlobalWindow::GetName(nsAString& aName)
    3576                 : {
    3577               0 :   FORWARD_TO_OUTER(GetName, (aName), NS_ERROR_NOT_INITIALIZED);
    3578                 : 
    3579               0 :   nsXPIDLString name;
    3580               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    3581               0 :   if (docShellAsItem)
    3582               0 :     docShellAsItem->GetName(getter_Copies(name));
    3583                 : 
    3584               0 :   aName.Assign(name);
    3585               0 :   return NS_OK;
    3586                 : }
    3587                 : 
    3588                 : NS_IMETHODIMP
    3589               0 : nsGlobalWindow::SetName(const nsAString& aName)
    3590                 : {
    3591               0 :   FORWARD_TO_OUTER(SetName, (aName), NS_ERROR_NOT_INITIALIZED);
    3592                 : 
    3593               0 :   nsresult result = NS_OK;
    3594               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    3595               0 :   if (docShellAsItem)
    3596               0 :     result = docShellAsItem->SetName(PromiseFlatString(aName).get());
    3597               0 :   return result;
    3598                 : }
    3599                 : 
    3600                 : // Helper functions used by many methods below.
    3601                 : PRInt32
    3602               0 : nsGlobalWindow::DevToCSSIntPixels(PRInt32 px)
    3603                 : {
    3604               0 :   if (!mDocShell)
    3605               0 :     return px; // assume 1:1
    3606                 : 
    3607               0 :   nsRefPtr<nsPresContext> presContext;
    3608               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3609               0 :   if (!presContext)
    3610               0 :     return px;
    3611                 : 
    3612               0 :   return presContext->DevPixelsToIntCSSPixels(px);
    3613                 : }
    3614                 : 
    3615                 : PRInt32
    3616               0 : nsGlobalWindow::CSSToDevIntPixels(PRInt32 px)
    3617                 : {
    3618               0 :   if (!mDocShell)
    3619               0 :     return px; // assume 1:1
    3620                 : 
    3621               0 :   nsRefPtr<nsPresContext> presContext;
    3622               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3623               0 :   if (!presContext)
    3624               0 :     return px;
    3625                 : 
    3626               0 :   return presContext->CSSPixelsToDevPixels(px);
    3627                 : }
    3628                 : 
    3629                 : nsIntSize
    3630               0 : nsGlobalWindow::DevToCSSIntPixels(nsIntSize px)
    3631                 : {
    3632               0 :   if (!mDocShell)
    3633               0 :     return px; // assume 1:1
    3634                 : 
    3635               0 :   nsRefPtr<nsPresContext> presContext;
    3636               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3637               0 :   if (!presContext)
    3638               0 :     return px;
    3639                 : 
    3640                 :   return nsIntSize(
    3641                 :       presContext->DevPixelsToIntCSSPixels(px.width),
    3642               0 :       presContext->DevPixelsToIntCSSPixels(px.height));
    3643                 : }
    3644                 : 
    3645                 : nsIntSize
    3646               0 : nsGlobalWindow::CSSToDevIntPixels(nsIntSize px)
    3647                 : {
    3648               0 :   if (!mDocShell)
    3649               0 :     return px; // assume 1:1
    3650                 : 
    3651               0 :   nsRefPtr<nsPresContext> presContext;
    3652               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3653               0 :   if (!presContext)
    3654               0 :     return px;
    3655                 : 
    3656                 :   return nsIntSize(
    3657                 :     presContext->CSSPixelsToDevPixels(px.width),
    3658               0 :     presContext->CSSPixelsToDevPixels(px.height));
    3659                 : }
    3660                 : 
    3661                 : 
    3662                 : NS_IMETHODIMP
    3663               0 : nsGlobalWindow::GetInnerWidth(PRInt32* aInnerWidth)
    3664                 : {
    3665               0 :   FORWARD_TO_OUTER(GetInnerWidth, (aInnerWidth), NS_ERROR_NOT_INITIALIZED);
    3666                 : 
    3667               0 :   NS_ENSURE_STATE(mDocShell);
    3668                 : 
    3669               0 :   EnsureSizeUpToDate();
    3670                 : 
    3671               0 :   nsRefPtr<nsPresContext> presContext;
    3672               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3673                 : 
    3674               0 :   if (presContext) {
    3675               0 :     nsRect shellArea = presContext->GetVisibleArea();
    3676               0 :     *aInnerWidth = nsPresContext::AppUnitsToIntCSSPixels(shellArea.width);
    3677                 :   } else {
    3678               0 :     *aInnerWidth = 0;
    3679                 :   }
    3680                 : 
    3681               0 :   return NS_OK;
    3682                 : }
    3683                 : 
    3684                 : NS_IMETHODIMP
    3685               0 : nsGlobalWindow::SetInnerWidth(PRInt32 aInnerWidth)
    3686                 : {
    3687               0 :   FORWARD_TO_OUTER(SetInnerWidth, (aInnerWidth), NS_ERROR_NOT_INITIALIZED);
    3688                 : 
    3689               0 :   NS_ENSURE_STATE(mDocShell);
    3690                 : 
    3691                 :   /*
    3692                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    3693                 :    * prevent setting window.innerWidth by exiting early
    3694                 :    */
    3695               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    3696               0 :     return NS_OK;
    3697                 :   }
    3698                 : 
    3699               0 :   NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(&aInnerWidth, nsnull),
    3700                 :                     NS_ERROR_FAILURE);
    3701                 : 
    3702                 : 
    3703               0 :   nsRefPtr<nsIPresShell> presShell;
    3704               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    3705                 : 
    3706               0 :   if (presShell && presShell->GetIsViewportOverridden())
    3707                 :   {
    3708               0 :     nscoord height = 0;
    3709               0 :     nscoord width  = 0;
    3710                 : 
    3711               0 :     nsRefPtr<nsPresContext> presContext;
    3712               0 :     presContext = presShell->GetPresContext();
    3713                 : 
    3714               0 :     nsRect shellArea = presContext->GetVisibleArea();
    3715               0 :     height = shellArea.height;
    3716               0 :     width  = nsPresContext::CSSPixelsToAppUnits(aInnerWidth);
    3717               0 :     return SetCSSViewportWidthAndHeight(width, height);
    3718                 :   }
    3719                 :   else
    3720                 :   {
    3721               0 :     PRInt32 height = 0;
    3722               0 :     PRInt32 width  = 0;
    3723                 : 
    3724               0 :     nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
    3725               0 :     docShellAsWin->GetSize(&width, &height);
    3726               0 :     width  = CSSToDevIntPixels(aInnerWidth);
    3727               0 :     return SetDocShellWidthAndHeight(width, height);
    3728                 :   }
    3729                 : }
    3730                 : 
    3731                 : NS_IMETHODIMP
    3732               0 : nsGlobalWindow::GetInnerHeight(PRInt32* aInnerHeight)
    3733                 : {
    3734               0 :   FORWARD_TO_OUTER(GetInnerHeight, (aInnerHeight), NS_ERROR_NOT_INITIALIZED);
    3735                 : 
    3736               0 :   NS_ENSURE_STATE(mDocShell);
    3737                 : 
    3738               0 :   EnsureSizeUpToDate();
    3739                 : 
    3740               0 :   nsRefPtr<nsPresContext> presContext;
    3741               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    3742                 : 
    3743               0 :   if (presContext) {
    3744               0 :     nsRect shellArea = presContext->GetVisibleArea();
    3745               0 :     *aInnerHeight = nsPresContext::AppUnitsToIntCSSPixels(shellArea.height);
    3746                 :   } else {
    3747               0 :     *aInnerHeight = 0;
    3748                 :   }
    3749               0 :   return NS_OK;
    3750                 : }
    3751                 : 
    3752                 : NS_IMETHODIMP
    3753               0 : nsGlobalWindow::SetInnerHeight(PRInt32 aInnerHeight)
    3754                 : {
    3755               0 :   FORWARD_TO_OUTER(SetInnerHeight, (aInnerHeight), NS_ERROR_NOT_INITIALIZED);
    3756                 : 
    3757               0 :   NS_ENSURE_STATE(mDocShell);
    3758                 : 
    3759                 :   /*
    3760                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    3761                 :    * prevent setting window.innerHeight by exiting early
    3762                 :    */
    3763               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    3764               0 :     return NS_OK;
    3765                 :   }
    3766                 : 
    3767               0 :   NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(nsnull, &aInnerHeight),
    3768                 :                     NS_ERROR_FAILURE);
    3769                 : 
    3770               0 :   nsRefPtr<nsIPresShell> presShell;
    3771               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    3772                 : 
    3773               0 :   if (presShell && presShell->GetIsViewportOverridden())
    3774                 :   {
    3775               0 :     nscoord height = 0;
    3776               0 :     nscoord width  = 0;
    3777                 : 
    3778               0 :     nsRefPtr<nsPresContext> presContext;
    3779               0 :     presContext = presShell->GetPresContext();
    3780                 : 
    3781               0 :     nsRect shellArea = presContext->GetVisibleArea();
    3782               0 :     width = shellArea.width;
    3783               0 :     height  = nsPresContext::CSSPixelsToAppUnits(aInnerHeight);
    3784               0 :     return SetCSSViewportWidthAndHeight(width, height);
    3785                 :   }
    3786                 :   else
    3787                 :   {
    3788               0 :     PRInt32 height = 0;
    3789               0 :     PRInt32 width  = 0;
    3790                 : 
    3791               0 :     nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell));
    3792               0 :     docShellAsWin->GetSize(&width, &height);
    3793               0 :     height  = CSSToDevIntPixels(aInnerHeight);
    3794               0 :     return SetDocShellWidthAndHeight(width, height);
    3795                 :   }
    3796                 : }
    3797                 : 
    3798                 : nsresult
    3799               0 : nsGlobalWindow::GetOuterSize(nsIntSize* aSizeCSSPixels)
    3800                 : {
    3801               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    3802               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    3803               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    3804                 : 
    3805                 :   nsGlobalWindow* rootWindow =
    3806               0 :     static_cast<nsGlobalWindow *>(GetPrivateRoot());
    3807               0 :   if (rootWindow) {
    3808               0 :     rootWindow->FlushPendingNotifications(Flush_Layout);
    3809                 :   }
    3810                 : 
    3811               0 :   nsIntSize sizeDevPixels;
    3812               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetSize(&sizeDevPixels.width,
    3813                 :                                             &sizeDevPixels.height),
    3814                 :                     NS_ERROR_FAILURE);
    3815                 : 
    3816               0 :   *aSizeCSSPixels = DevToCSSIntPixels(sizeDevPixels);
    3817               0 :   return NS_OK;
    3818                 : }
    3819                 : 
    3820                 : NS_IMETHODIMP
    3821               0 : nsGlobalWindow::GetOuterWidth(PRInt32* aOuterWidth)
    3822                 : {
    3823               0 :   FORWARD_TO_OUTER(GetOuterWidth, (aOuterWidth), NS_ERROR_NOT_INITIALIZED);
    3824                 : 
    3825               0 :   nsIntSize sizeCSSPixels;
    3826               0 :   nsresult rv = GetOuterSize(&sizeCSSPixels);
    3827               0 :   NS_ENSURE_SUCCESS(rv, rv);
    3828                 : 
    3829               0 :   *aOuterWidth = sizeCSSPixels.width;
    3830               0 :   return NS_OK;
    3831                 : }
    3832                 : 
    3833                 : NS_IMETHODIMP
    3834               0 : nsGlobalWindow::GetOuterHeight(PRInt32* aOuterHeight)
    3835                 : {
    3836               0 :   FORWARD_TO_OUTER(GetOuterHeight, (aOuterHeight), NS_ERROR_NOT_INITIALIZED);
    3837                 : 
    3838               0 :   nsIntSize sizeCSSPixels;
    3839               0 :   nsresult rv = GetOuterSize(&sizeCSSPixels);
    3840               0 :   NS_ENSURE_SUCCESS(rv, rv);
    3841                 : 
    3842               0 :   *aOuterHeight = sizeCSSPixels.height;
    3843               0 :   return NS_OK;
    3844                 : }
    3845                 : 
    3846                 : nsresult
    3847               0 : nsGlobalWindow::SetOuterSize(PRInt32 aLengthCSSPixels, bool aIsWidth)
    3848                 : {
    3849                 :   /*
    3850                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    3851                 :    * prevent setting window.outerWidth by exiting early
    3852                 :    */
    3853                 : 
    3854               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    3855               0 :     return NS_OK;
    3856                 :   }
    3857                 : 
    3858               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    3859               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    3860               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    3861                 : 
    3862               0 :   NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(
    3863                 :                         aIsWidth ? &aLengthCSSPixels : nsnull,
    3864                 :                         aIsWidth ? nsnull : &aLengthCSSPixels),
    3865                 :                     NS_ERROR_FAILURE);
    3866                 : 
    3867                 :   PRInt32 width, height;
    3868               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetSize(&width, &height), NS_ERROR_FAILURE);
    3869                 : 
    3870               0 :   PRInt32 lengthDevPixels = CSSToDevIntPixels(aLengthCSSPixels);
    3871               0 :   if (aIsWidth) {
    3872               0 :     width = lengthDevPixels;
    3873                 :   } else {
    3874               0 :     height = lengthDevPixels;
    3875                 :   }
    3876               0 :   return treeOwnerAsWin->SetSize(width, height, true);    
    3877                 : }
    3878                 : 
    3879                 : NS_IMETHODIMP
    3880               0 : nsGlobalWindow::SetOuterWidth(PRInt32 aOuterWidth)
    3881                 : {
    3882               0 :   FORWARD_TO_OUTER(SetOuterWidth, (aOuterWidth), NS_ERROR_NOT_INITIALIZED);
    3883                 : 
    3884               0 :   return SetOuterSize(aOuterWidth, true);
    3885                 : }
    3886                 : 
    3887                 : NS_IMETHODIMP
    3888               0 : nsGlobalWindow::SetOuterHeight(PRInt32 aOuterHeight)
    3889                 : {
    3890               0 :   FORWARD_TO_OUTER(SetOuterHeight, (aOuterHeight), NS_ERROR_NOT_INITIALIZED);
    3891                 : 
    3892               0 :   return SetOuterSize(aOuterHeight, false);
    3893                 : }
    3894                 : 
    3895                 : NS_IMETHODIMP
    3896               0 : nsGlobalWindow::GetScreenX(PRInt32* aScreenX)
    3897                 : {
    3898               0 :   FORWARD_TO_OUTER(GetScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
    3899                 : 
    3900               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    3901               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    3902               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    3903                 : 
    3904                 :   PRInt32 x, y;
    3905                 : 
    3906               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetPosition(&x, &y),
    3907                 :                     NS_ERROR_FAILURE);
    3908                 : 
    3909               0 :   *aScreenX = DevToCSSIntPixels(x);
    3910               0 :   return NS_OK;
    3911                 : }
    3912                 : 
    3913                 : nsRect
    3914               0 : nsGlobalWindow::GetInnerScreenRect()
    3915                 : {
    3916               0 :   if (!mDocShell)
    3917               0 :     return nsRect();
    3918                 : 
    3919                 :   nsGlobalWindow* rootWindow =
    3920               0 :     static_cast<nsGlobalWindow*>(GetPrivateRoot());
    3921               0 :   if (rootWindow) {
    3922               0 :     rootWindow->FlushPendingNotifications(Flush_Layout);
    3923                 :   }
    3924                 : 
    3925               0 :   nsCOMPtr<nsIPresShell> presShell;
    3926               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    3927               0 :   if (!presShell)
    3928               0 :     return nsRect();
    3929               0 :   nsIFrame* rootFrame = presShell->GetRootFrame();
    3930               0 :   if (!rootFrame)
    3931               0 :     return nsRect();
    3932                 : 
    3933               0 :   return rootFrame->GetScreenRectInAppUnits();
    3934                 : }
    3935                 : 
    3936                 : NS_IMETHODIMP
    3937               0 : nsGlobalWindow::GetMozInnerScreenX(float* aScreenX)
    3938                 : {
    3939               0 :   FORWARD_TO_OUTER(GetMozInnerScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
    3940                 : 
    3941               0 :   nsRect r = GetInnerScreenRect();
    3942               0 :   *aScreenX = nsPresContext::AppUnitsToFloatCSSPixels(r.x);
    3943               0 :   return NS_OK;
    3944                 : }
    3945                 : 
    3946                 : NS_IMETHODIMP
    3947               0 : nsGlobalWindow::GetMozInnerScreenY(float* aScreenY)
    3948                 : {
    3949               0 :   FORWARD_TO_OUTER(GetMozInnerScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
    3950                 : 
    3951               0 :   nsRect r = GetInnerScreenRect();
    3952               0 :   *aScreenY = nsPresContext::AppUnitsToFloatCSSPixels(r.y);
    3953               0 :   return NS_OK;
    3954                 : }
    3955                 : 
    3956                 : NS_IMETHODIMP
    3957               0 : nsGlobalWindow::GetMozPaintCount(PRUint64* aResult)
    3958                 : {
    3959               0 :   FORWARD_TO_OUTER(GetMozPaintCount, (aResult), NS_ERROR_NOT_INITIALIZED);
    3960                 : 
    3961               0 :   *aResult = 0;
    3962                 : 
    3963               0 :   if (!mDocShell)
    3964               0 :     return NS_OK;
    3965                 : 
    3966               0 :   nsCOMPtr<nsIPresShell> presShell;
    3967               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    3968               0 :   if (!presShell)
    3969               0 :     return NS_OK;
    3970                 : 
    3971               0 :   *aResult = presShell->GetPaintCount();
    3972               0 :   return NS_OK;
    3973                 : }
    3974                 : 
    3975                 : NS_IMETHODIMP
    3976               0 : nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback,
    3977                 :                                          PRInt32 *aHandle)
    3978                 : {
    3979               0 :   FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback, aHandle),
    3980                 :                    NS_ERROR_NOT_INITIALIZED);
    3981                 : 
    3982               0 :   if (!mDoc) {
    3983               0 :     return NS_OK;
    3984                 :   }
    3985                 : 
    3986               0 :   if (!aCallback) {
    3987               0 :     mDoc->WarnOnceAbout(nsIDocument::eMozBeforePaint);
    3988               0 :     return NS_ERROR_XPC_BAD_CONVERT_JS;
    3989                 :   }
    3990                 : 
    3991               0 :   return mDoc->ScheduleFrameRequestCallback(aCallback, aHandle);
    3992                 : }
    3993                 : 
    3994                 : NS_IMETHODIMP
    3995               0 : nsGlobalWindow::MozCancelRequestAnimationFrame(PRInt32 aHandle)
    3996                 : {
    3997               0 :   return MozCancelAnimationFrame(aHandle);
    3998                 : }
    3999                 : 
    4000                 : NS_IMETHODIMP
    4001               0 : nsGlobalWindow::MozCancelAnimationFrame(PRInt32 aHandle)
    4002                 : {
    4003               0 :   FORWARD_TO_INNER(MozCancelAnimationFrame, (aHandle),
    4004                 :                    NS_ERROR_NOT_INITIALIZED);
    4005                 : 
    4006               0 :   if (!mDoc) {
    4007               0 :     return NS_OK;
    4008                 :   }
    4009                 : 
    4010               0 :   mDoc->CancelFrameRequestCallback(aHandle);
    4011               0 :   return NS_OK;
    4012                 : }
    4013                 : 
    4014                 : NS_IMETHODIMP
    4015               0 : nsGlobalWindow::GetMozAnimationStartTime(PRInt64 *aTime)
    4016                 : {
    4017               0 :   FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_NOT_INITIALIZED);
    4018                 : 
    4019               0 :   if (mDoc) {
    4020               0 :     nsIPresShell* presShell = mDoc->GetShell();
    4021               0 :     if (presShell) {
    4022                 :       *aTime = presShell->GetPresContext()->RefreshDriver()->
    4023               0 :         MostRecentRefreshEpochTime() / PR_USEC_PER_MSEC;
    4024               0 :       return NS_OK;
    4025                 :     }
    4026                 :   }
    4027                 : 
    4028                 :   // If all else fails, just be compatible with Date.now()
    4029               0 :   *aTime = JS_Now() / PR_USEC_PER_MSEC;
    4030               0 :   return NS_OK;
    4031                 : }
    4032                 : 
    4033                 : NS_IMETHODIMP
    4034               0 : nsGlobalWindow::MatchMedia(const nsAString& aMediaQueryList,
    4035                 :                            nsIDOMMediaQueryList** aResult)
    4036                 : {
    4037                 :   // FIXME: This whole forward-to-outer and then get a pres
    4038                 :   // shell/context off the docshell dance is sort of silly; it'd make
    4039                 :   // more sense to forward to the inner, but it's what everyone else
    4040                 :   // (GetSelection, GetScrollXY, etc.) does around here.
    4041               0 :   FORWARD_TO_OUTER(MatchMedia, (aMediaQueryList, aResult),
    4042                 :                    NS_ERROR_NOT_INITIALIZED);
    4043                 : 
    4044               0 :   *aResult = nsnull;
    4045                 : 
    4046               0 :   if (!mDocShell)
    4047               0 :     return NS_OK;
    4048                 : 
    4049               0 :   nsRefPtr<nsPresContext> presContext;
    4050               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    4051                 : 
    4052               0 :   if (!presContext)
    4053               0 :     return NS_OK;
    4054                 : 
    4055               0 :   presContext->MatchMedia(aMediaQueryList, aResult);
    4056               0 :   return NS_OK;
    4057                 : }
    4058                 : 
    4059                 : NS_IMETHODIMP
    4060               0 : nsGlobalWindow::SetScreenX(PRInt32 aScreenX)
    4061                 : {
    4062               0 :   FORWARD_TO_OUTER(SetScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
    4063                 : 
    4064                 :   /*
    4065                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    4066                 :    * prevent setting window.screenX by exiting early
    4067                 :    */
    4068                 : 
    4069               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    4070               0 :     return NS_OK;
    4071                 :   }
    4072                 : 
    4073               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    4074               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    4075               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    4076                 : 
    4077               0 :   NS_ENSURE_SUCCESS(CheckSecurityLeftAndTop(&aScreenX, nsnull),
    4078                 :                     NS_ERROR_FAILURE);
    4079                 : 
    4080                 :   PRInt32 x, y;
    4081               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetPosition(&x, &y),
    4082                 :                     NS_ERROR_FAILURE);
    4083                 : 
    4084               0 :   x = CSSToDevIntPixels(aScreenX);
    4085                 : 
    4086               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetPosition(x, y),
    4087                 :                     NS_ERROR_FAILURE);
    4088                 : 
    4089               0 :   return NS_OK;
    4090                 : }
    4091                 : 
    4092                 : NS_IMETHODIMP
    4093               0 : nsGlobalWindow::GetScreenY(PRInt32* aScreenY)
    4094                 : {
    4095               0 :   FORWARD_TO_OUTER(GetScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
    4096                 : 
    4097               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    4098               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    4099               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    4100                 : 
    4101                 :   PRInt32 x, y;
    4102                 : 
    4103               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetPosition(&x, &y),
    4104                 :                     NS_ERROR_FAILURE);
    4105                 : 
    4106               0 :   *aScreenY = DevToCSSIntPixels(y);
    4107               0 :   return NS_OK;
    4108                 : }
    4109                 : 
    4110                 : NS_IMETHODIMP
    4111               0 : nsGlobalWindow::SetScreenY(PRInt32 aScreenY)
    4112                 : {
    4113               0 :   FORWARD_TO_OUTER(SetScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
    4114                 : 
    4115                 :   /*
    4116                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    4117                 :    * prevent setting window.screenY by exiting early
    4118                 :    */
    4119                 : 
    4120               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    4121               0 :     return NS_OK;
    4122                 :   }
    4123                 : 
    4124               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    4125               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    4126               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    4127                 : 
    4128               0 :   NS_ENSURE_SUCCESS(CheckSecurityLeftAndTop(nsnull, &aScreenY),
    4129                 :                     NS_ERROR_FAILURE);
    4130                 : 
    4131                 :   PRInt32 x, y;
    4132               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetPosition(&x, &y),
    4133                 :                     NS_ERROR_FAILURE);
    4134                 : 
    4135               0 :   y = CSSToDevIntPixels(aScreenY);
    4136                 : 
    4137               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetPosition(x, y),
    4138                 :                     NS_ERROR_FAILURE);
    4139                 : 
    4140               0 :   return NS_OK;
    4141                 : }
    4142                 : 
    4143                 : // NOTE: Arguments to this function should have values scaled to
    4144                 : // CSS pixels, not device pixels.
    4145                 : nsresult
    4146               0 : nsGlobalWindow::CheckSecurityWidthAndHeight(PRInt32* aWidth, PRInt32* aHeight)
    4147                 : {
    4148                 : #ifdef MOZ_XUL
    4149               0 :   if (!nsContentUtils::IsCallerTrustedForWrite()) {
    4150                 :     // if attempting to resize the window, hide any open popups
    4151               0 :     nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
    4152               0 :     nsContentUtils::HidePopupsInDocument(doc);
    4153                 :   }
    4154                 : #endif
    4155                 : 
    4156                 :   // This one is easy. Just ensure the variable is greater than 100;
    4157               0 :   if ((aWidth && *aWidth < 100) || (aHeight && *aHeight < 100)) {
    4158                 :     // Check security state for use in determing window dimensions
    4159                 : 
    4160               0 :     if (!nsContentUtils::IsCallerTrustedForWrite()) {
    4161                 :       //sec check failed
    4162               0 :       if (aWidth && *aWidth < 100) {
    4163               0 :         *aWidth = 100;
    4164                 :       }
    4165               0 :       if (aHeight && *aHeight < 100) {
    4166               0 :         *aHeight = 100;
    4167                 :       }
    4168                 :     }
    4169                 :   }
    4170                 : 
    4171               0 :   return NS_OK;
    4172                 : }
    4173                 : 
    4174                 : // NOTE: Arguments to this function should have values in device pixels
    4175                 : nsresult
    4176               0 : nsGlobalWindow::SetDocShellWidthAndHeight(PRInt32 aInnerWidth, PRInt32 aInnerHeight)
    4177                 : {
    4178               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    4179               0 :   NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
    4180                 : 
    4181               0 :   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    4182               0 :   docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
    4183               0 :   NS_ENSURE_TRUE(treeOwner, NS_ERROR_FAILURE);
    4184                 : 
    4185               0 :   NS_ENSURE_SUCCESS(treeOwner->SizeShellTo(docShellAsItem, aInnerWidth, aInnerHeight),
    4186                 :                     NS_ERROR_FAILURE);
    4187                 : 
    4188               0 :   return NS_OK;
    4189                 : }
    4190                 : 
    4191                 : // NOTE: Arguments to this function should have values in app units
    4192                 : nsresult
    4193               0 : nsGlobalWindow::SetCSSViewportWidthAndHeight(nscoord aInnerWidth, nscoord aInnerHeight)
    4194                 : {
    4195               0 :   nsRefPtr<nsPresContext> presContext;
    4196               0 :   mDocShell->GetPresContext(getter_AddRefs(presContext));
    4197                 : 
    4198               0 :   nsRect shellArea = presContext->GetVisibleArea();
    4199               0 :   shellArea.height = aInnerHeight;
    4200               0 :   shellArea.width = aInnerWidth;
    4201                 : 
    4202               0 :   presContext->SetVisibleArea(shellArea);
    4203               0 :   return NS_OK;
    4204                 : }
    4205                 : 
    4206                 : // NOTE: Arguments to this function should have values scaled to
    4207                 : // CSS pixels, not device pixels.
    4208                 : nsresult
    4209               0 : nsGlobalWindow::CheckSecurityLeftAndTop(PRInt32* aLeft, PRInt32* aTop)
    4210                 : {
    4211                 :   // This one is harder. We have to get the screen size and window dimensions.
    4212                 : 
    4213                 :   // Check security state for use in determing window dimensions
    4214                 : 
    4215               0 :   if (!nsContentUtils::IsCallerTrustedForWrite()) {
    4216                 : #ifdef MOZ_XUL
    4217                 :     // if attempting to move the window, hide any open popups
    4218               0 :     nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
    4219               0 :     nsContentUtils::HidePopupsInDocument(doc);
    4220                 : #endif
    4221                 : 
    4222                 :     nsGlobalWindow* rootWindow =
    4223               0 :       static_cast<nsGlobalWindow*>(GetPrivateRoot());
    4224               0 :     if (rootWindow) {
    4225               0 :       rootWindow->FlushPendingNotifications(Flush_Layout);
    4226                 :     }
    4227                 : 
    4228               0 :     nsCOMPtr<nsIBaseWindow> treeOwner;
    4229               0 :     GetTreeOwner(getter_AddRefs(treeOwner));
    4230                 : 
    4231               0 :     nsCOMPtr<nsIDOMScreen> screen;
    4232               0 :     GetScreen(getter_AddRefs(screen));
    4233                 : 
    4234               0 :     if (treeOwner && screen) {
    4235                 :       PRInt32 screenLeft, screenTop, screenWidth, screenHeight;
    4236                 :       PRInt32 winLeft, winTop, winWidth, winHeight;
    4237                 : 
    4238                 :       // Get the window size
    4239               0 :       treeOwner->GetPositionAndSize(&winLeft, &winTop, &winWidth, &winHeight);
    4240                 : 
    4241                 :       // convert those values to CSS pixels
    4242                 :       // XXX four separate retrievals of the prescontext
    4243               0 :       winLeft   = DevToCSSIntPixels(winLeft);
    4244               0 :       winTop    = DevToCSSIntPixels(winTop);
    4245               0 :       winWidth  = DevToCSSIntPixels(winWidth);
    4246               0 :       winHeight = DevToCSSIntPixels(winHeight);
    4247                 : 
    4248                 :       // Get the screen dimensions
    4249                 :       // XXX This should use nsIScreenManager once it's fully fleshed out.
    4250               0 :       screen->GetAvailLeft(&screenLeft);
    4251               0 :       screen->GetAvailWidth(&screenWidth);
    4252               0 :       screen->GetAvailHeight(&screenHeight);
    4253                 : #if defined(XP_MACOSX)
    4254                 :       /* The mac's coordinate system is different from the assumed Windows'
    4255                 :          system. It offsets by the height of the menubar so that a window
    4256                 :          placed at (0,0) will be entirely visible. Unfortunately that
    4257                 :          correction is made elsewhere (in Widget) and the meaning of
    4258                 :          the Avail... coordinates is overloaded. Here we allow a window
    4259                 :          to be placed at (0,0) because it does make sense to do so.
    4260                 :       */
    4261                 :       screen->GetTop(&screenTop);
    4262                 : #else
    4263               0 :       screen->GetAvailTop(&screenTop);
    4264                 : #endif
    4265                 : 
    4266               0 :       if (aLeft) {
    4267               0 :         if (screenLeft+screenWidth < *aLeft+winWidth)
    4268               0 :           *aLeft = screenLeft+screenWidth - winWidth;
    4269               0 :         if (screenLeft > *aLeft)
    4270               0 :           *aLeft = screenLeft;
    4271                 :       }
    4272               0 :       if (aTop) {
    4273               0 :         if (screenTop+screenHeight < *aTop+winHeight)
    4274               0 :           *aTop = screenTop+screenHeight - winHeight;
    4275               0 :         if (screenTop > *aTop)
    4276               0 :           *aTop = screenTop;
    4277                 :       }
    4278                 :     } else {
    4279               0 :       if (aLeft)
    4280               0 :         *aLeft = 0;
    4281               0 :       if (aTop)
    4282               0 :         *aTop = 0;
    4283                 :     }
    4284                 :   }
    4285                 : 
    4286               0 :   return NS_OK;
    4287                 : }
    4288                 : 
    4289                 : NS_IMETHODIMP
    4290               0 : nsGlobalWindow::GetPageXOffset(PRInt32* aPageXOffset)
    4291                 : {
    4292               0 :   return GetScrollX(aPageXOffset);
    4293                 : }
    4294                 : 
    4295                 : NS_IMETHODIMP
    4296               0 : nsGlobalWindow::GetPageYOffset(PRInt32* aPageYOffset)
    4297                 : {
    4298               0 :   return GetScrollY(aPageYOffset);
    4299                 : }
    4300                 : 
    4301                 : nsresult
    4302               0 : nsGlobalWindow::GetScrollMaxXY(PRInt32* aScrollMaxX, PRInt32* aScrollMaxY)
    4303                 : {
    4304               0 :   FORWARD_TO_OUTER(GetScrollMaxXY, (aScrollMaxX, aScrollMaxY),
    4305                 :                    NS_ERROR_NOT_INITIALIZED);
    4306                 : 
    4307               0 :   FlushPendingNotifications(Flush_Layout);
    4308               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    4309               0 :   if (!sf)
    4310               0 :     return NS_OK;
    4311                 : 
    4312               0 :   nsRect scrollRange = sf->GetScrollRange();
    4313                 : 
    4314               0 :   if (aScrollMaxX)
    4315                 :     *aScrollMaxX = NS_MAX(0,
    4316               0 :       (PRInt32)floor(nsPresContext::AppUnitsToFloatCSSPixels(scrollRange.XMost())));
    4317               0 :   if (aScrollMaxY)
    4318                 :     *aScrollMaxY = NS_MAX(0,
    4319               0 :       (PRInt32)floor(nsPresContext::AppUnitsToFloatCSSPixels(scrollRange.YMost())));
    4320                 : 
    4321               0 :   return NS_OK;
    4322                 : }
    4323                 : 
    4324                 : NS_IMETHODIMP
    4325               0 : nsGlobalWindow::GetScrollMaxX(PRInt32* aScrollMaxX)
    4326                 : {
    4327               0 :   NS_ENSURE_ARG_POINTER(aScrollMaxX);
    4328               0 :   *aScrollMaxX = 0;
    4329               0 :   return GetScrollMaxXY(aScrollMaxX, nsnull);
    4330                 : }
    4331                 : 
    4332                 : NS_IMETHODIMP
    4333               0 : nsGlobalWindow::GetScrollMaxY(PRInt32* aScrollMaxY)
    4334                 : {
    4335               0 :   NS_ENSURE_ARG_POINTER(aScrollMaxY);
    4336               0 :   *aScrollMaxY = 0;
    4337               0 :   return GetScrollMaxXY(nsnull, aScrollMaxY);
    4338                 : }
    4339                 : 
    4340                 : nsresult
    4341               0 : nsGlobalWindow::GetScrollXY(PRInt32* aScrollX, PRInt32* aScrollY,
    4342                 :                             bool aDoFlush)
    4343                 : {
    4344               0 :   FORWARD_TO_OUTER(GetScrollXY, (aScrollX, aScrollY, aDoFlush),
    4345                 :                    NS_ERROR_NOT_INITIALIZED);
    4346                 : 
    4347               0 :   if (aDoFlush) {
    4348               0 :     FlushPendingNotifications(Flush_Layout);
    4349                 :   } else {
    4350               0 :     EnsureSizeUpToDate();
    4351                 :   }
    4352                 : 
    4353               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    4354               0 :   if (!sf)
    4355               0 :     return NS_OK;
    4356                 : 
    4357               0 :   nsPoint scrollPos = sf->GetScrollPosition();
    4358               0 :   if (scrollPos != nsPoint(0,0) && !aDoFlush) {
    4359                 :     // Oh, well.  This is the expensive case -- the window is scrolled and we
    4360                 :     // didn't actually flush yet.  Repeat, but with a flush, since the content
    4361                 :     // may get shorter and hence our scroll position may decrease.
    4362               0 :     return GetScrollXY(aScrollX, aScrollY, true);
    4363                 :   }
    4364                 : 
    4365               0 :   if (aScrollX)
    4366               0 :     *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
    4367               0 :   if (aScrollY)
    4368               0 :     *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
    4369                 : 
    4370               0 :   return NS_OK;
    4371                 : }
    4372                 : 
    4373                 : NS_IMETHODIMP
    4374               0 : nsGlobalWindow::GetScrollX(PRInt32* aScrollX)
    4375                 : {
    4376               0 :   NS_ENSURE_ARG_POINTER(aScrollX);
    4377               0 :   *aScrollX = 0;
    4378               0 :   return GetScrollXY(aScrollX, nsnull, false);
    4379                 : }
    4380                 : 
    4381                 : NS_IMETHODIMP
    4382               0 : nsGlobalWindow::GetScrollY(PRInt32* aScrollY)
    4383                 : {
    4384               0 :   NS_ENSURE_ARG_POINTER(aScrollY);
    4385               0 :   *aScrollY = 0;
    4386               0 :   return GetScrollXY(nsnull, aScrollY, false);
    4387                 : }
    4388                 : 
    4389                 : NS_IMETHODIMP
    4390               0 : nsGlobalWindow::GetLength(PRUint32* aLength)
    4391                 : {
    4392               0 :   nsCOMPtr<nsIDOMWindowCollection> frames;
    4393               0 :   if (NS_SUCCEEDED(GetFrames(getter_AddRefs(frames))) && frames) {
    4394               0 :     return frames->GetLength(aLength);
    4395                 :   }
    4396               0 :   return NS_ERROR_FAILURE;
    4397                 : }
    4398                 : 
    4399                 : bool
    4400               0 : nsGlobalWindow::DispatchCustomEvent(const char *aEventName)
    4401                 : {
    4402               0 :   bool defaultActionEnabled = true;
    4403               0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
    4404                 :   nsContentUtils::DispatchTrustedEvent(doc,
    4405               0 :                                        GetOuterWindow(),
    4406               0 :                                        NS_ConvertASCIItoUTF16(aEventName),
    4407               0 :                                        true, true, &defaultActionEnabled);
    4408                 : 
    4409               0 :   return defaultActionEnabled;
    4410                 : }
    4411                 : 
    4412                 : static already_AddRefed<nsIDocShellTreeItem>
    4413               0 : GetCallerDocShellTreeItem()
    4414                 : {
    4415               0 :   JSContext *cx = nsContentUtils::GetCurrentJSContext();
    4416               0 :   nsIDocShellTreeItem *callerItem = nsnull;
    4417                 : 
    4418               0 :   if (cx) {
    4419                 :     nsCOMPtr<nsIWebNavigation> callerWebNav =
    4420               0 :       do_GetInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
    4421                 : 
    4422               0 :     if (callerWebNav) {
    4423               0 :       CallQueryInterface(callerWebNav, &callerItem);
    4424                 :     }
    4425                 :   }
    4426                 : 
    4427               0 :   return callerItem;
    4428                 : }
    4429                 : 
    4430                 : bool
    4431               0 : nsGlobalWindow::WindowExists(const nsAString& aName,
    4432                 :                              bool aLookForCallerOnJSStack)
    4433                 : {
    4434               0 :   NS_PRECONDITION(IsOuterWindow(), "Must be outer window");
    4435               0 :   NS_PRECONDITION(mDocShell, "Must have docshell");
    4436                 : 
    4437               0 :   nsCOMPtr<nsIDocShellTreeItem> caller;
    4438               0 :   if (aLookForCallerOnJSStack) {
    4439               0 :     caller = GetCallerDocShellTreeItem();
    4440                 :   }
    4441                 : 
    4442               0 :   nsCOMPtr<nsIDocShellTreeItem> docShell = do_QueryInterface(mDocShell);
    4443               0 :   NS_ASSERTION(docShell,
    4444                 :                "Docshell doesn't implement nsIDocShellTreeItem?");
    4445                 : 
    4446               0 :   if (!caller) {
    4447               0 :     caller = docShell;
    4448                 :   }
    4449                 : 
    4450               0 :   nsCOMPtr<nsIDocShellTreeItem> namedItem;
    4451               0 :   docShell->FindItemWithName(PromiseFlatString(aName).get(), nsnull, caller,
    4452               0 :                              getter_AddRefs(namedItem));
    4453               0 :   return namedItem != nsnull;
    4454                 : }
    4455                 : 
    4456                 : already_AddRefed<nsIWidget>
    4457               0 : nsGlobalWindow::GetMainWidget()
    4458                 : {
    4459               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    4460               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    4461                 : 
    4462               0 :   nsIWidget *widget = nsnull;
    4463                 : 
    4464               0 :   if (treeOwnerAsWin) {
    4465               0 :     treeOwnerAsWin->GetMainWidget(&widget);
    4466                 :   }
    4467                 : 
    4468               0 :   return widget;
    4469                 : }
    4470                 : 
    4471                 : nsIWidget*
    4472               0 : nsGlobalWindow::GetNearestWidget()
    4473                 : {
    4474               0 :   nsIDocShell* docShell = GetDocShell();
    4475               0 :   NS_ENSURE_TRUE(docShell, nsnull);
    4476               0 :   nsCOMPtr<nsIPresShell> presShell;
    4477               0 :   docShell->GetPresShell(getter_AddRefs(presShell));
    4478               0 :   NS_ENSURE_TRUE(presShell, nsnull);
    4479               0 :   nsIFrame* rootFrame = presShell->GetRootFrame();
    4480               0 :   NS_ENSURE_TRUE(rootFrame, nsnull);
    4481               0 :   return rootFrame->GetView()->GetNearestWidget(nsnull);
    4482                 : }
    4483                 : 
    4484                 : NS_IMETHODIMP
    4485               0 : nsGlobalWindow::SetFullScreen(bool aFullScreen)
    4486                 : {
    4487               0 :   return SetFullScreenInternal(aFullScreen, true);
    4488                 : }
    4489                 : 
    4490                 : nsresult
    4491               0 : nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust)
    4492                 : {
    4493               0 :   FORWARD_TO_OUTER(SetFullScreen, (aFullScreen), NS_ERROR_NOT_INITIALIZED);
    4494                 : 
    4495               0 :   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
    4496                 : 
    4497                 :   bool rootWinFullScreen;
    4498               0 :   GetFullScreen(&rootWinFullScreen);
    4499                 :   // Only chrome can change our fullScreen mode, unless we're running in
    4500                 :   // untrusted mode.
    4501               0 :   if (aFullScreen == rootWinFullScreen || 
    4502               0 :       (aRequireTrust && !nsContentUtils::IsCallerTrustedForWrite())) {
    4503               0 :     return NS_OK;
    4504                 :   }
    4505                 : 
    4506                 :   // SetFullScreen needs to be called on the root window, so get that
    4507                 :   // via the DocShell tree, and if we are not already the root,
    4508                 :   // call SetFullScreen on that window instead.
    4509               0 :   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
    4510               0 :   nsCOMPtr<nsIDocShellTreeItem> rootItem;
    4511               0 :   treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
    4512               0 :   nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(rootItem);
    4513               0 :   if (!window)
    4514               0 :     return NS_ERROR_FAILURE;
    4515               0 :   if (rootItem != treeItem)
    4516               0 :     return window->SetFullScreenInternal(aFullScreen, aRequireTrust);
    4517                 : 
    4518                 :   // make sure we don't try to set full screen on a non-chrome window,
    4519                 :   // which might happen in embedding world
    4520                 :   PRInt32 itemType;
    4521               0 :   treeItem->GetItemType(&itemType);
    4522               0 :   if (itemType != nsIDocShellTreeItem::typeChrome)
    4523               0 :     return NS_ERROR_FAILURE;
    4524                 : 
    4525                 :   // If we are already in full screen mode, just return.
    4526               0 :   if (mFullScreen == aFullScreen)
    4527               0 :     return NS_OK;
    4528                 : 
    4529                 :   // dispatch a "fullscreen" DOM event so that XUL apps can
    4530                 :   // respond visually if we are kicked into full screen mode
    4531               0 :   if (!DispatchCustomEvent("fullscreen")) {
    4532               0 :     return NS_OK;
    4533                 :   }
    4534                 : 
    4535                 :   // Prevent chrome documents which are still loading from resizing
    4536                 :   // the window after we set fullscreen mode.
    4537               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    4538               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    4539               0 :   nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwnerAsWin));
    4540               0 :   if (aFullScreen && xulWin) {
    4541               0 :     xulWin->SetIntrinsicallySized(false);
    4542                 :   }
    4543                 : 
    4544                 :   // Set this before so if widget sends an event indicating its
    4545                 :   // gone full screen, the state trap above works.
    4546               0 :   mFullScreen = aFullScreen;
    4547                 : 
    4548               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
    4549               0 :   if (widget)
    4550               0 :     widget->MakeFullScreen(aFullScreen);
    4551                 : 
    4552               0 :   if (!mFullScreen) {
    4553                 :     // Force exit from DOM full-screen mode. This is so that if we're in
    4554                 :     // DOM full-screen mode and the user exits full-screen mode with
    4555                 :     // the browser full-screen mode toggle keyboard-shortcut, we'll detect
    4556                 :     // that and leave DOM API full-screen mode too.
    4557               0 :     nsIDocument::ExitFullScreen(false);
    4558                 :   }
    4559                 : 
    4560               0 :   return NS_OK;
    4561                 : }
    4562                 : 
    4563                 : NS_IMETHODIMP
    4564               0 : nsGlobalWindow::GetFullScreen(bool* aFullScreen)
    4565                 : {
    4566               0 :   FORWARD_TO_OUTER(GetFullScreen, (aFullScreen), NS_ERROR_NOT_INITIALIZED);
    4567                 : 
    4568                 :   // Get the fullscreen value of the root window, to always have the value
    4569                 :   // accurate, even when called from content.
    4570               0 :   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
    4571               0 :   if (treeItem) {
    4572               0 :     nsCOMPtr<nsIDocShellTreeItem> rootItem;
    4573               0 :     treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
    4574               0 :     if (rootItem != treeItem) {
    4575               0 :       nsCOMPtr<nsIDOMWindow> window = do_GetInterface(rootItem);
    4576               0 :       if (window)
    4577               0 :         return window->GetFullScreen(aFullScreen);
    4578                 :     }
    4579                 :   }
    4580                 : 
    4581                 :   // We are the root window, or something went wrong. Return our internal value.
    4582               0 :   *aFullScreen = mFullScreen;
    4583               0 :   return NS_OK;
    4584                 : }
    4585                 : 
    4586                 : bool
    4587               0 : nsGlobalWindow::DOMWindowDumpEnabled()
    4588                 : {
    4589                 : #if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
    4590                 :   // In optimized builds we check a pref that controls if we should
    4591                 :   // enable output from dump() or not, in debug builds it's always
    4592                 :   // enabled.
    4593                 :   return gDOMWindowDumpEnabled;
    4594                 : #else
    4595               0 :   return true;
    4596                 : #endif
    4597                 : }
    4598                 : 
    4599                 : NS_IMETHODIMP
    4600               0 : nsGlobalWindow::Dump(const nsAString& aStr)
    4601                 : {
    4602               0 :   if (!DOMWindowDumpEnabled()) {
    4603               0 :     return NS_OK;
    4604                 :   }
    4605                 : 
    4606               0 :   char *cstr = ToNewUTF8String(aStr);
    4607                 : 
    4608                 : #if defined(XP_MACOSX)
    4609                 :   // have to convert \r to \n so that printing to the console works
    4610                 :   char *c = cstr, *cEnd = cstr + strlen(cstr);
    4611                 :   while (c < cEnd) {
    4612                 :     if (*c == '\r')
    4613                 :       *c = '\n';
    4614                 :     c++;
    4615                 :   }
    4616                 : #endif
    4617                 : 
    4618               0 :   if (cstr) {
    4619                 : #ifdef ANDROID
    4620                 :     __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
    4621                 : #endif
    4622               0 :     FILE *fp = gDumpFile ? gDumpFile : stdout;
    4623               0 :     fputs(cstr, fp);
    4624               0 :     fflush(fp);
    4625               0 :     nsMemory::Free(cstr);
    4626                 :   }
    4627                 : 
    4628               0 :   return NS_OK;
    4629                 : }
    4630                 : 
    4631                 : void
    4632               0 : nsGlobalWindow::EnsureReflowFlushAndPaint()
    4633                 : {
    4634               0 :   NS_ASSERTION(IsOuterWindow(), "EnsureReflowFlushAndPaint() must be called on"
    4635                 :                "the outer window");
    4636               0 :   NS_ASSERTION(mDocShell, "EnsureReflowFlushAndPaint() called with no "
    4637                 :                "docshell!");
    4638                 : 
    4639               0 :   if (!mDocShell)
    4640               0 :     return;
    4641                 : 
    4642               0 :   nsCOMPtr<nsIPresShell> presShell;
    4643               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    4644                 : 
    4645               0 :   if (!presShell)
    4646                 :     return;
    4647                 : 
    4648                 :   // Flush pending reflows.
    4649               0 :   if (mDoc) {
    4650               0 :     mDoc->FlushPendingNotifications(Flush_Layout);
    4651                 :   }
    4652                 : 
    4653                 :   // Unsuppress painting.
    4654               0 :   presShell->UnsuppressPainting();
    4655                 : }
    4656                 : 
    4657                 : NS_IMETHODIMP
    4658               0 : nsGlobalWindow::GetTextZoom(float *aZoom)
    4659                 : {
    4660               0 :   FORWARD_TO_OUTER(GetTextZoom, (aZoom), NS_ERROR_NOT_INITIALIZED);
    4661                 : 
    4662               0 :   if (mDocShell) {
    4663               0 :     nsCOMPtr<nsIContentViewer> contentViewer;
    4664               0 :     mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
    4665               0 :     nsCOMPtr<nsIMarkupDocumentViewer> markupViewer(do_QueryInterface(contentViewer));
    4666                 : 
    4667               0 :     if (markupViewer) {
    4668               0 :       return markupViewer->GetTextZoom(aZoom);
    4669                 :     }
    4670                 :   }
    4671               0 :   return NS_ERROR_FAILURE;
    4672                 : }
    4673                 : 
    4674                 : NS_IMETHODIMP
    4675               0 : nsGlobalWindow::SetTextZoom(float aZoom)
    4676                 : {
    4677               0 :   FORWARD_TO_OUTER(SetTextZoom, (aZoom), NS_ERROR_NOT_INITIALIZED);
    4678                 : 
    4679               0 :   if (mDocShell) {
    4680               0 :     nsCOMPtr<nsIContentViewer> contentViewer;
    4681               0 :     mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
    4682               0 :     nsCOMPtr<nsIMarkupDocumentViewer> markupViewer(do_QueryInterface(contentViewer));
    4683                 : 
    4684               0 :     if (markupViewer)
    4685               0 :       return markupViewer->SetTextZoom(aZoom);
    4686                 :   }
    4687               0 :   return NS_ERROR_FAILURE;
    4688                 : }
    4689                 : 
    4690                 : // static
    4691                 : void
    4692               0 : nsGlobalWindow::MakeScriptDialogTitle(nsAString &aOutTitle)
    4693                 : {
    4694               0 :   aOutTitle.Truncate();
    4695                 : 
    4696                 :   // Try to get a host from the running principal -- this will do the
    4697                 :   // right thing for javascript: and data: documents.
    4698                 : 
    4699               0 :   nsresult rv = NS_OK;
    4700               0 :   NS_ASSERTION(nsContentUtils::GetSecurityManager(),
    4701                 :     "Global Window has no security manager!");
    4702               0 :   if (nsContentUtils::GetSecurityManager()) {
    4703               0 :     nsCOMPtr<nsIPrincipal> principal;
    4704               0 :     rv = nsContentUtils::GetSecurityManager()->
    4705               0 :       GetSubjectPrincipal(getter_AddRefs(principal));
    4706                 : 
    4707               0 :     if (NS_SUCCEEDED(rv) && principal) {
    4708               0 :       nsCOMPtr<nsIURI> uri;
    4709               0 :       rv = principal->GetURI(getter_AddRefs(uri));
    4710                 : 
    4711               0 :       if (NS_SUCCEEDED(rv) && uri) {
    4712                 :         // remove user:pass for privacy and spoof prevention
    4713                 : 
    4714               0 :         nsCOMPtr<nsIURIFixup> fixup(do_GetService(NS_URIFIXUP_CONTRACTID));
    4715               0 :         if (fixup) {
    4716               0 :           nsCOMPtr<nsIURI> fixedURI;
    4717               0 :           rv = fixup->CreateExposableURI(uri, getter_AddRefs(fixedURI));
    4718               0 :           if (NS_SUCCEEDED(rv) && fixedURI) {
    4719               0 :             nsCAutoString host;
    4720               0 :             fixedURI->GetHost(host);
    4721                 : 
    4722               0 :             if (!host.IsEmpty()) {
    4723                 :               // if this URI has a host we'll show it. For other
    4724                 :               // schemes (e.g. file:) we fall back to the localized
    4725                 :               // generic string
    4726                 : 
    4727               0 :               nsCAutoString prepath;
    4728               0 :               fixedURI->GetPrePath(prepath);
    4729                 : 
    4730               0 :               NS_ConvertUTF8toUTF16 ucsPrePath(prepath);
    4731               0 :               const PRUnichar *formatStrings[] = { ucsPrePath.get() };
    4732               0 :               nsXPIDLString tempString;
    4733                 :               nsContentUtils::FormatLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    4734                 :                                                     "ScriptDlgHeading",
    4735                 :                                                     formatStrings,
    4736               0 :                                                     tempString);
    4737               0 :               aOutTitle = tempString;
    4738                 :             }
    4739                 :           }
    4740                 :         }
    4741                 :       }
    4742                 :     }
    4743                 :     else { // failed to get subject principal
    4744               0 :       NS_WARNING("No script principal? Who is calling alert/confirm/prompt?!");
    4745                 :     }
    4746                 :   }
    4747                 : 
    4748               0 :   if (aOutTitle.IsEmpty()) {
    4749                 :     // We didn't find a host so use the generic heading
    4750               0 :     nsXPIDLString tempString;
    4751                 :     nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    4752                 :                                        "ScriptDlgGenericHeading",
    4753               0 :                                        tempString);
    4754               0 :     aOutTitle = tempString;
    4755                 :   }
    4756                 : 
    4757                 :   // Just in case
    4758               0 :   if (aOutTitle.IsEmpty()) {
    4759               0 :     NS_WARNING("could not get ScriptDlgGenericHeading string from string bundle");
    4760               0 :     aOutTitle.AssignLiteral("[Script]");
    4761                 :   }
    4762               0 : }
    4763                 : 
    4764                 : bool
    4765               0 : nsGlobalWindow::CanMoveResizeWindows()
    4766                 : {
    4767                 :   // When called from chrome, we can avoid the following checks.
    4768               0 :   if (!nsContentUtils::IsCallerTrustedForWrite()) {
    4769                 :     // Don't allow scripts to move or resize windows that were not opened by a
    4770                 :     // script.
    4771               0 :     if (!mHadOriginalOpener) {
    4772               0 :       return false;
    4773                 :     }
    4774                 : 
    4775               0 :     if (!CanSetProperty("dom.disable_window_move_resize")) {
    4776               0 :       return false;
    4777                 :     }
    4778                 : 
    4779                 :     // Ignore the request if we have more than one tab in the window.
    4780               0 :     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    4781               0 :     GetTreeOwner(getter_AddRefs(treeOwner));
    4782               0 :     if (treeOwner) {
    4783                 :       PRUint32 itemCount;
    4784               0 :       if (NS_SUCCEEDED(treeOwner->GetTargetableShellCount(&itemCount)) &&
    4785                 :           itemCount > 1) {
    4786               0 :         return false;
    4787                 :       }
    4788                 :     }
    4789                 :   }
    4790                 : 
    4791               0 :   if (mDocShell) {
    4792                 :     bool allow;
    4793               0 :     nsresult rv = mDocShell->GetAllowWindowControl(&allow);
    4794               0 :     if (NS_SUCCEEDED(rv) && !allow)
    4795               0 :       return false;
    4796                 :   }
    4797                 : 
    4798               0 :   if (gMouseDown && !gDragServiceDisabled) {
    4799                 :     nsCOMPtr<nsIDragService> ds =
    4800               0 :       do_GetService("@mozilla.org/widget/dragservice;1");
    4801               0 :     if (ds) {
    4802               0 :       gDragServiceDisabled = true;
    4803               0 :       ds->Suppress();
    4804                 :     }
    4805                 :   }
    4806               0 :   return true;
    4807                 : }
    4808                 : 
    4809                 : NS_IMETHODIMP
    4810               0 : nsGlobalWindow::Alert(const nsAString& aString)
    4811                 : {
    4812               0 :   FORWARD_TO_OUTER(Alert, (aString), NS_ERROR_NOT_INITIALIZED);
    4813                 : 
    4814               0 :   if (AreDialogsBlocked())
    4815               0 :     return NS_ERROR_NOT_AVAILABLE;
    4816                 : 
    4817                 :   // We have to capture this now so as not to get confused with the
    4818                 :   // popup state we push next
    4819               0 :   bool shouldEnableDisableDialog = DialogOpenAttempted();
    4820                 : 
    4821                 :   // Reset popup state while opening a modal dialog, and firing events
    4822                 :   // about the dialog, to prevent the current state from being active
    4823                 :   // the whole time a modal dialog is open.
    4824               0 :   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
    4825                 : 
    4826                 :   // Special handling for alert(null) in JS for backwards
    4827                 :   // compatibility.
    4828                 : 
    4829               0 :   NS_NAMED_LITERAL_STRING(null_str, "null");
    4830                 : 
    4831               0 :   const nsAString *str = DOMStringIsNull(aString) ? &null_str : &aString;
    4832                 : 
    4833                 :   // Before bringing up the window, unsuppress painting and flush
    4834                 :   // pending reflows.
    4835               0 :   EnsureReflowFlushAndPaint();
    4836                 : 
    4837               0 :   nsAutoString title;
    4838               0 :   MakeScriptDialogTitle(title);
    4839                 : 
    4840                 :   // Remove non-terminating null characters from the 
    4841                 :   // string. See bug #310037. 
    4842               0 :   nsAutoString final;
    4843               0 :   nsContentUtils::StripNullChars(*str, final);
    4844                 : 
    4845                 :   // Check if we're being called at a point where we can't use tab-modal
    4846                 :   // prompts, because something doesn't want reentrancy.
    4847               0 :   bool allowTabModal = GetIsTabModalPromptAllowed();
    4848                 : 
    4849                 :   nsresult rv;
    4850                 :   nsCOMPtr<nsIPromptFactory> promptFac =
    4851               0 :     do_GetService("@mozilla.org/prompter;1", &rv);
    4852               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4853                 : 
    4854               0 :   nsCOMPtr<nsIPrompt> prompt;
    4855               0 :   rv = promptFac->GetPrompt(this, NS_GET_IID(nsIPrompt),
    4856               0 :                             reinterpret_cast<void**>(&prompt));
    4857               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4858                 : 
    4859               0 :   nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
    4860               0 :   if (promptBag)
    4861               0 :     promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
    4862                 : 
    4863               0 :   if (shouldEnableDisableDialog) {
    4864               0 :     bool disallowDialog = false;
    4865               0 :     nsXPIDLString label;
    4866                 :     nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    4867               0 :                                        "ScriptDialogLabel", label);
    4868                 : 
    4869               0 :     rv = prompt->AlertCheck(title.get(), final.get(), label.get(),
    4870               0 :                             &disallowDialog);
    4871               0 :     if (disallowDialog)
    4872               0 :       PreventFurtherDialogs();
    4873                 :   } else {
    4874               0 :     rv = prompt->Alert(title.get(), final.get());
    4875                 :   }
    4876                 : 
    4877               0 :   return rv;
    4878                 : }
    4879                 : 
    4880                 : NS_IMETHODIMP
    4881               0 : nsGlobalWindow::Confirm(const nsAString& aString, bool* aReturn)
    4882                 : {
    4883               0 :   FORWARD_TO_OUTER(Confirm, (aString, aReturn), NS_ERROR_NOT_INITIALIZED);
    4884                 : 
    4885               0 :   if (AreDialogsBlocked())
    4886               0 :     return NS_ERROR_NOT_AVAILABLE;
    4887                 : 
    4888                 :   // We have to capture this now so as not to get confused with the popup state
    4889                 :   // we push next
    4890               0 :   bool shouldEnableDisableDialog = DialogOpenAttempted();
    4891                 : 
    4892                 :   // Reset popup state while opening a modal dialog, and firing events
    4893                 :   // about the dialog, to prevent the current state from being active
    4894                 :   // the whole time a modal dialog is open.
    4895               0 :   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
    4896                 : 
    4897               0 :   *aReturn = false;
    4898                 : 
    4899                 :   // Before bringing up the window, unsuppress painting and flush
    4900                 :   // pending reflows.
    4901               0 :   EnsureReflowFlushAndPaint();
    4902                 : 
    4903               0 :   nsAutoString title;
    4904               0 :   MakeScriptDialogTitle(title);
    4905                 : 
    4906                 :   // Remove non-terminating null characters from the 
    4907                 :   // string. See bug #310037. 
    4908               0 :   nsAutoString final;
    4909               0 :   nsContentUtils::StripNullChars(aString, final);
    4910                 : 
    4911                 :   // Check if we're being called at a point where we can't use tab-modal
    4912                 :   // prompts, because something doesn't want reentrancy.
    4913               0 :   bool allowTabModal = GetIsTabModalPromptAllowed();
    4914                 : 
    4915                 :   nsresult rv;
    4916                 :   nsCOMPtr<nsIPromptFactory> promptFac =
    4917               0 :     do_GetService("@mozilla.org/prompter;1", &rv);
    4918               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4919                 : 
    4920               0 :   nsCOMPtr<nsIPrompt> prompt;
    4921               0 :   rv = promptFac->GetPrompt(this, NS_GET_IID(nsIPrompt),
    4922               0 :                             reinterpret_cast<void**>(&prompt));
    4923               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4924                 : 
    4925               0 :   nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
    4926               0 :   if (promptBag)
    4927               0 :     promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
    4928                 : 
    4929               0 :   if (shouldEnableDisableDialog) {
    4930               0 :     bool disallowDialog = false;
    4931               0 :     nsXPIDLString label;
    4932                 :     nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    4933               0 :                                        "ScriptDialogLabel", label);
    4934                 : 
    4935               0 :     rv = prompt->ConfirmCheck(title.get(), final.get(), label.get(),
    4936               0 :                               &disallowDialog, aReturn);
    4937               0 :     if (disallowDialog)
    4938               0 :       PreventFurtherDialogs();
    4939                 :   } else {
    4940               0 :     rv = prompt->Confirm(title.get(), final.get(), aReturn);
    4941                 :   }
    4942                 : 
    4943               0 :   return rv;
    4944                 : }
    4945                 : 
    4946                 : NS_IMETHODIMP
    4947               0 : nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
    4948                 :                        nsAString& aReturn)
    4949                 : {
    4950               0 :   FORWARD_TO_OUTER(Prompt, (aMessage, aInitial, aReturn),
    4951                 :                    NS_ERROR_NOT_INITIALIZED);
    4952                 : 
    4953               0 :   SetDOMStringToNull(aReturn);
    4954                 : 
    4955               0 :   if (AreDialogsBlocked())
    4956               0 :     return NS_ERROR_NOT_AVAILABLE;
    4957                 : 
    4958                 :   // We have to capture this now so as not to get confused with the popup state
    4959                 :   // we push next
    4960               0 :   bool shouldEnableDisableDialog = DialogOpenAttempted();
    4961                 : 
    4962                 :   // Reset popup state while opening a modal dialog, and firing events
    4963                 :   // about the dialog, to prevent the current state from being active
    4964                 :   // the whole time a modal dialog is open.
    4965               0 :   nsAutoPopupStatePusher popupStatePusher(openAbused, true);
    4966                 : 
    4967                 :   // Before bringing up the window, unsuppress painting and flush
    4968                 :   // pending reflows.
    4969               0 :   EnsureReflowFlushAndPaint();
    4970                 : 
    4971               0 :   nsAutoString title;
    4972               0 :   MakeScriptDialogTitle(title);
    4973                 :   
    4974                 :   // Remove non-terminating null characters from the 
    4975                 :   // string. See bug #310037. 
    4976               0 :   nsAutoString fixedMessage, fixedInitial;
    4977               0 :   nsContentUtils::StripNullChars(aMessage, fixedMessage);
    4978               0 :   nsContentUtils::StripNullChars(aInitial, fixedInitial);
    4979                 : 
    4980                 :   // Check if we're being called at a point where we can't use tab-modal
    4981                 :   // prompts, because something doesn't want reentrancy.
    4982               0 :   bool allowTabModal = GetIsTabModalPromptAllowed();
    4983                 : 
    4984                 :   nsresult rv;
    4985                 :   nsCOMPtr<nsIPromptFactory> promptFac =
    4986               0 :     do_GetService("@mozilla.org/prompter;1", &rv);
    4987               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4988                 : 
    4989               0 :   nsCOMPtr<nsIPrompt> prompt;
    4990               0 :   rv = promptFac->GetPrompt(this, NS_GET_IID(nsIPrompt),
    4991               0 :                             reinterpret_cast<void**>(&prompt));
    4992               0 :   NS_ENSURE_SUCCESS(rv, rv);
    4993                 : 
    4994               0 :   nsCOMPtr<nsIWritablePropertyBag2> promptBag = do_QueryInterface(prompt);
    4995               0 :   if (promptBag)
    4996               0 :     promptBag->SetPropertyAsBool(NS_LITERAL_STRING("allowTabModal"), allowTabModal);
    4997                 : 
    4998                 :   // Pass in the default value, if any.
    4999               0 :   PRUnichar *inoutValue = ToNewUnicode(fixedInitial);
    5000               0 :   bool disallowDialog = false;
    5001                 : 
    5002               0 :   nsXPIDLString label;
    5003               0 :   if (shouldEnableDisableDialog) {
    5004                 :     nsContentUtils::GetLocalizedString(nsContentUtils::eCOMMON_DIALOG_PROPERTIES,
    5005               0 :                                        "ScriptDialogLabel", label);
    5006                 :   }
    5007                 : 
    5008                 :   bool ok;
    5009               0 :   rv = prompt->Prompt(title.get(), fixedMessage.get(),
    5010               0 :                       &inoutValue, label.get(), &disallowDialog, &ok);
    5011                 : 
    5012               0 :   if (disallowDialog) {
    5013               0 :     PreventFurtherDialogs();
    5014                 :   }
    5015                 : 
    5016               0 :   NS_ENSURE_SUCCESS(rv, rv);
    5017                 : 
    5018               0 :   nsAdoptingString outValue(inoutValue);
    5019                 : 
    5020               0 :   if (ok && outValue) {
    5021               0 :     aReturn.Assign(outValue);
    5022                 :   }
    5023                 : 
    5024               0 :   return rv;
    5025                 : }
    5026                 : 
    5027                 : NS_IMETHODIMP
    5028               0 : nsGlobalWindow::Focus()
    5029                 : {
    5030               0 :   FORWARD_TO_OUTER(Focus, (), NS_ERROR_NOT_INITIALIZED);
    5031                 : 
    5032               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    5033               0 :   if (!fm)
    5034               0 :     return NS_OK;
    5035                 : 
    5036               0 :   nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mDocShell);
    5037                 : 
    5038               0 :   bool isVisible = false;
    5039               0 :   if (baseWin) {
    5040               0 :     baseWin->GetVisibility(&isVisible);
    5041                 :   }
    5042                 : 
    5043               0 :   if (!isVisible) {
    5044                 :     // A hidden tab is being focused, ignore this call.
    5045               0 :     return NS_OK;
    5046                 :   }
    5047                 : 
    5048               0 :   nsIDOMWindow *caller = nsContentUtils::GetWindowFromCaller();
    5049               0 :   nsCOMPtr<nsIDOMWindow> opener;
    5050               0 :   GetOpener(getter_AddRefs(opener));
    5051                 : 
    5052                 :   // Enforce dom.disable_window_flip (for non-chrome), but still allow the
    5053                 :   // window which opened us to raise us at times when popups are allowed
    5054                 :   // (bugs 355482 and 369306).
    5055               0 :   bool canFocus = CanSetProperty("dom.disable_window_flip") ||
    5056               0 :                     (opener == caller &&
    5057               0 :                      RevisePopupAbuseLevel(gPopupControlState) < openAbused);
    5058                 : 
    5059               0 :   nsCOMPtr<nsIDOMWindow> activeWindow;
    5060               0 :   fm->GetActiveWindow(getter_AddRefs(activeWindow));
    5061                 : 
    5062               0 :   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
    5063               0 :   NS_ASSERTION(treeItem, "What happened?");
    5064               0 :   nsCOMPtr<nsIDocShellTreeItem> rootItem;
    5065               0 :   treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
    5066               0 :   nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
    5067               0 :   bool isActive = (rootWin == activeWindow);
    5068                 : 
    5069               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    5070               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    5071               0 :   if (treeOwnerAsWin && (canFocus || isActive)) {
    5072               0 :     bool isEnabled = true;
    5073               0 :     if (NS_SUCCEEDED(treeOwnerAsWin->GetEnabled(&isEnabled)) && !isEnabled) {
    5074               0 :       NS_WARNING( "Should not try to set the focus on a disabled window" );
    5075               0 :       return NS_OK;
    5076                 :     }
    5077                 : 
    5078                 :     // XXXndeakin not sure what this is for or if it should go somewhere else
    5079               0 :     nsCOMPtr<nsIEmbeddingSiteWindow> embeddingWin(do_GetInterface(treeOwnerAsWin));
    5080               0 :     if (embeddingWin)
    5081               0 :       embeddingWin->SetFocus();
    5082                 :   }
    5083                 : 
    5084               0 :   if (!mDocShell)
    5085               0 :     return NS_OK;
    5086                 : 
    5087               0 :   nsCOMPtr<nsIPresShell> presShell;
    5088                 :   // Don't look for a presshell if we're a root chrome window that's got
    5089                 :   // about:blank loaded.  We don't want to focus our widget in that case.
    5090                 :   // XXXbz should we really be checking for IsInitialDocument() instead?
    5091               0 :   bool lookForPresShell = true;
    5092               0 :   PRInt32 itemType = nsIDocShellTreeItem::typeContent;
    5093               0 :   treeItem->GetItemType(&itemType);
    5094               0 :   if (itemType == nsIDocShellTreeItem::typeChrome &&
    5095               0 :       GetPrivateRoot() == static_cast<nsIDOMWindow*>(this) &&
    5096               0 :       mDocument) {
    5097               0 :     nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
    5098               0 :     NS_ASSERTION(doc, "Bogus doc?");
    5099               0 :     nsIURI* ourURI = doc->GetDocumentURI();
    5100               0 :     if (ourURI) {
    5101               0 :       lookForPresShell = !NS_IsAboutBlank(ourURI);
    5102                 :     }
    5103                 :   }
    5104                 : 
    5105               0 :   if (lookForPresShell) {
    5106               0 :     mDocShell->GetEldestPresShell(getter_AddRefs(presShell));
    5107                 :   }
    5108                 : 
    5109               0 :   nsCOMPtr<nsIDocShellTreeItem> parentDsti;
    5110               0 :   treeItem->GetParent(getter_AddRefs(parentDsti));
    5111                 : 
    5112                 :   // set the parent's current focus to the frame containing this window.
    5113               0 :   nsCOMPtr<nsIDOMWindow> parent(do_GetInterface(parentDsti));
    5114               0 :   if (parent) {
    5115               0 :     nsCOMPtr<nsIDOMDocument> parentdomdoc;
    5116               0 :     parent->GetDocument(getter_AddRefs(parentdomdoc));
    5117                 : 
    5118               0 :     nsCOMPtr<nsIDocument> parentdoc = do_QueryInterface(parentdomdoc);
    5119               0 :     if (!parentdoc)
    5120               0 :       return NS_OK;
    5121                 : 
    5122               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
    5123               0 :     nsIContent* frame = parentdoc->FindContentForSubDocument(doc);
    5124               0 :     nsCOMPtr<nsIDOMElement> frameElement = do_QueryInterface(frame);
    5125               0 :     if (frameElement) {
    5126               0 :       PRUint32 flags = nsIFocusManager::FLAG_NOSCROLL;
    5127               0 :       if (canFocus)
    5128               0 :         flags |= nsIFocusManager::FLAG_RAISE;
    5129               0 :       return fm->SetFocus(frameElement, flags);
    5130                 :     }
    5131                 :   }
    5132               0 :   else if (canFocus) {
    5133                 :     // if there is no parent, this must be a toplevel window, so raise the
    5134                 :     // window if canFocus is true
    5135               0 :     return fm->SetActiveWindow(this);
    5136                 :   }
    5137                 : 
    5138               0 :   return NS_OK;
    5139                 : }
    5140                 : 
    5141                 : NS_IMETHODIMP
    5142               0 : nsGlobalWindow::Blur()
    5143                 : {
    5144               0 :   FORWARD_TO_OUTER(Blur, (), NS_ERROR_NOT_INITIALIZED);
    5145                 : 
    5146                 :   // If dom.disable_window_flip == true, then content should not be allowed
    5147                 :   // to call this function (this would allow popunders, bug 369306)
    5148               0 :   if (!CanSetProperty("dom.disable_window_flip")) {
    5149               0 :     return NS_OK;
    5150                 :   }
    5151                 : 
    5152                 :   // If embedding apps don't implement nsIEmbeddingSiteWindow2, we
    5153                 :   // shouldn't throw exceptions to web content.
    5154               0 :   nsresult rv = NS_OK;
    5155                 : 
    5156               0 :   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    5157               0 :   GetTreeOwner(getter_AddRefs(treeOwner));
    5158               0 :   nsCOMPtr<nsIEmbeddingSiteWindow2> siteWindow(do_GetInterface(treeOwner));
    5159               0 :   if (siteWindow) {
    5160                 :     // This method call may cause mDocShell to become nsnull.
    5161               0 :     rv = siteWindow->Blur();
    5162                 : 
    5163                 :     // if the root is focused, clear the focus
    5164               0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    5165               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
    5166               0 :     if (fm && mDocument) {
    5167               0 :       nsCOMPtr<nsIDOMElement> element;
    5168               0 :       fm->GetFocusedElementForWindow(this, false, nsnull, getter_AddRefs(element));
    5169               0 :       nsCOMPtr<nsIContent> content = do_QueryInterface(element);
    5170               0 :       if (content == doc->GetRootElement())
    5171               0 :         fm->ClearFocus(this);
    5172                 :     }
    5173                 :   }
    5174                 : 
    5175               0 :   return rv;
    5176                 : }
    5177                 : 
    5178                 : NS_IMETHODIMP
    5179               0 : nsGlobalWindow::Back()
    5180                 : {
    5181               0 :   FORWARD_TO_OUTER(Back, (), NS_ERROR_NOT_INITIALIZED);
    5182                 : 
    5183               0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
    5184               0 :   NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
    5185                 : 
    5186               0 :   return webNav->GoBack();
    5187                 : }
    5188                 : 
    5189                 : NS_IMETHODIMP
    5190               0 : nsGlobalWindow::Forward()
    5191                 : {
    5192               0 :   FORWARD_TO_OUTER(Forward, (), NS_ERROR_NOT_INITIALIZED);
    5193                 : 
    5194               0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
    5195               0 :   NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
    5196                 : 
    5197               0 :   return webNav->GoForward();
    5198                 : }
    5199                 : 
    5200                 : NS_IMETHODIMP
    5201               0 : nsGlobalWindow::Home()
    5202                 : {
    5203               0 :   FORWARD_TO_OUTER(Home, (), NS_ERROR_NOT_INITIALIZED);
    5204                 : 
    5205               0 :   if (!mDocShell)
    5206               0 :     return NS_OK;
    5207                 : 
    5208                 :   nsAdoptingString homeURL =
    5209               0 :     Preferences::GetLocalizedString(PREF_BROWSER_STARTUP_HOMEPAGE);
    5210                 : 
    5211               0 :   if (homeURL.IsEmpty()) {
    5212                 :     // if all else fails, use this
    5213                 : #ifdef DEBUG_seth
    5214                 :     printf("all else failed.  using %s as the home page\n", DEFAULT_HOME_PAGE);
    5215                 : #endif
    5216               0 :     CopyASCIItoUTF16(DEFAULT_HOME_PAGE, homeURL);
    5217                 :   }
    5218                 : 
    5219                 : #ifdef MOZ_PHOENIX
    5220                 :   {
    5221                 :     // Firefox lets the user specify multiple home pages to open in
    5222                 :     // individual tabs by separating them with '|'. Since we don't
    5223                 :     // have the machinery in place to easily open new tabs from here,
    5224                 :     // simply truncate the homeURL at the first '|' character to
    5225                 :     // prevent any possibilities of leaking the users list of home
    5226                 :     // pages to the first home page.
    5227                 :     //
    5228                 :     // Once bug https://bugzilla.mozilla.org/show_bug.cgi?id=221445 is
    5229                 :     // fixed we can revisit this.
    5230               0 :     PRInt32 firstPipe = homeURL.FindChar('|');
    5231                 : 
    5232               0 :     if (firstPipe > 0) {
    5233               0 :       homeURL.Truncate(firstPipe);
    5234                 :     }
    5235                 :   }
    5236                 : #endif
    5237                 : 
    5238                 :   nsresult rv;
    5239               0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
    5240               0 :   NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
    5241               0 :   rv = webNav->LoadURI(homeURL.get(),
    5242                 :                        nsIWebNavigation::LOAD_FLAGS_NONE,
    5243                 :                        nsnull,
    5244                 :                        nsnull,
    5245               0 :                        nsnull);
    5246               0 :   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
    5247               0 :   return NS_OK;
    5248                 : }
    5249                 : 
    5250                 : NS_IMETHODIMP
    5251               0 : nsGlobalWindow::Stop()
    5252                 : {
    5253               0 :   FORWARD_TO_OUTER(Stop, (), NS_ERROR_NOT_INITIALIZED);
    5254                 : 
    5255               0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
    5256               0 :   if (!webNav)
    5257               0 :     return NS_OK;
    5258                 : 
    5259               0 :   return webNav->Stop(nsIWebNavigation::STOP_ALL);
    5260                 : }
    5261                 : 
    5262                 : NS_IMETHODIMP
    5263               0 : nsGlobalWindow::Print()
    5264                 : {
    5265                 : #ifdef NS_PRINTING
    5266               0 :   FORWARD_TO_OUTER(Print, (), NS_ERROR_NOT_INITIALIZED);
    5267                 : 
    5268               0 :   if (AreDialogsBlocked() || !ConfirmDialogAllowed())
    5269               0 :     return NS_ERROR_NOT_AVAILABLE;
    5270                 : 
    5271               0 :   nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint;
    5272               0 :   if (NS_SUCCEEDED(GetInterface(NS_GET_IID(nsIWebBrowserPrint),
    5273                 :                                 getter_AddRefs(webBrowserPrint)))) {
    5274                 : 
    5275                 :     nsCOMPtr<nsIPrintSettingsService> printSettingsService = 
    5276               0 :       do_GetService("@mozilla.org/gfx/printsettings-service;1");
    5277                 : 
    5278               0 :     nsCOMPtr<nsIPrintSettings> printSettings;
    5279               0 :     if (printSettingsService) {
    5280                 :       bool printSettingsAreGlobal =
    5281               0 :         Preferences::GetBool("print.use_global_printsettings", false);
    5282                 : 
    5283               0 :       if (printSettingsAreGlobal) {
    5284               0 :         printSettingsService->GetGlobalPrintSettings(getter_AddRefs(printSettings));
    5285                 : 
    5286               0 :         nsXPIDLString printerName;
    5287               0 :         printSettings->GetPrinterName(getter_Copies(printerName));
    5288               0 :         if (printerName.IsEmpty()) {
    5289               0 :           printSettingsService->GetDefaultPrinterName(getter_Copies(printerName));
    5290               0 :           printSettings->SetPrinterName(printerName);
    5291                 :         }
    5292               0 :         printSettingsService->InitPrintSettingsFromPrinter(printerName, printSettings);
    5293               0 :         printSettingsService->InitPrintSettingsFromPrefs(printSettings, 
    5294                 :                                                          true, 
    5295               0 :                                                          nsIPrintSettings::kInitSaveAll);
    5296                 :       } else {
    5297               0 :         printSettingsService->GetNewPrintSettings(getter_AddRefs(printSettings));
    5298                 :       }
    5299                 : 
    5300               0 :       nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
    5301               0 :       webBrowserPrint->Print(printSettings, nsnull);
    5302               0 :       LeaveModalState(callerWin);
    5303                 : 
    5304                 :       bool savePrintSettings =
    5305               0 :         Preferences::GetBool("print.save_print_settings", false);
    5306               0 :       if (printSettingsAreGlobal && savePrintSettings) {
    5307               0 :         printSettingsService->
    5308                 :           SavePrintSettingsToPrefs(printSettings,
    5309                 :                                    true,
    5310               0 :                                    nsIPrintSettings::kInitSaveAll);
    5311               0 :         printSettingsService->
    5312                 :           SavePrintSettingsToPrefs(printSettings,
    5313                 :                                    false,
    5314               0 :                                    nsIPrintSettings::kInitSavePrinterName);
    5315                 :       }
    5316                 :     } else {
    5317               0 :       webBrowserPrint->GetGlobalPrintSettings(getter_AddRefs(printSettings));
    5318               0 :       webBrowserPrint->Print(printSettings, nsnull);
    5319                 :     }
    5320                 :   }
    5321                 : #endif //NS_PRINTING
    5322                 : 
    5323               0 :   return NS_OK;
    5324                 : }
    5325                 : 
    5326                 : NS_IMETHODIMP
    5327               0 : nsGlobalWindow::MoveTo(PRInt32 aXPos, PRInt32 aYPos)
    5328                 : {
    5329               0 :   FORWARD_TO_OUTER(MoveTo, (aXPos, aYPos), NS_ERROR_NOT_INITIALIZED);
    5330                 : 
    5331                 :   /*
    5332                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    5333                 :    * prevent window.moveTo() by exiting early
    5334                 :    */
    5335                 : 
    5336               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    5337               0 :     return NS_OK;
    5338                 :   }
    5339                 : 
    5340               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    5341               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    5342               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    5343                 : 
    5344               0 :   NS_ENSURE_SUCCESS(CheckSecurityLeftAndTop(&aXPos, &aYPos),
    5345                 :                     NS_ERROR_FAILURE);
    5346                 : 
    5347                 :   // mild abuse of a "size" object so we don't need more helper functions
    5348               0 :   nsIntSize devPos(CSSToDevIntPixels(nsIntSize(aXPos, aYPos)));
    5349                 : 
    5350               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetPosition(devPos.width, devPos.height),
    5351                 :                     NS_ERROR_FAILURE);
    5352                 : 
    5353               0 :   return NS_OK;
    5354                 : }
    5355                 : 
    5356                 : NS_IMETHODIMP
    5357               0 : nsGlobalWindow::MoveBy(PRInt32 aXDif, PRInt32 aYDif)
    5358                 : {
    5359               0 :   FORWARD_TO_OUTER(MoveBy, (aXDif, aYDif), NS_ERROR_NOT_INITIALIZED);
    5360                 : 
    5361                 :   /*
    5362                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    5363                 :    * prevent window.moveBy() by exiting early
    5364                 :    */
    5365                 : 
    5366               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    5367               0 :     return NS_OK;
    5368                 :   }
    5369                 : 
    5370               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    5371               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    5372               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    5373                 : 
    5374                 :   // To do this correctly we have to convert what we get from GetPosition
    5375                 :   // into CSS pixels, add the arguments, do the security check, and
    5376                 :   // then convert back to device pixels for the call to SetPosition.
    5377                 : 
    5378                 :   PRInt32 x, y;
    5379               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetPosition(&x, &y), NS_ERROR_FAILURE);
    5380                 : 
    5381                 :   // mild abuse of a "size" object so we don't need more helper functions
    5382               0 :   nsIntSize cssPos(DevToCSSIntPixels(nsIntSize(x, y)));
    5383                 : 
    5384               0 :   cssPos.width += aXDif;
    5385               0 :   cssPos.height += aYDif;
    5386                 :   
    5387               0 :   NS_ENSURE_SUCCESS(CheckSecurityLeftAndTop(&cssPos.width,
    5388                 :                                             &cssPos.height),
    5389                 :                     NS_ERROR_FAILURE);
    5390                 : 
    5391               0 :   nsIntSize newDevPos(CSSToDevIntPixels(cssPos));
    5392                 : 
    5393               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetPosition(newDevPos.width,
    5394                 :                                                 newDevPos.height),
    5395                 :                     NS_ERROR_FAILURE);
    5396                 : 
    5397               0 :   return NS_OK;
    5398                 : }
    5399                 : 
    5400                 : NS_IMETHODIMP
    5401               0 : nsGlobalWindow::ResizeTo(PRInt32 aWidth, PRInt32 aHeight)
    5402                 : {
    5403               0 :   FORWARD_TO_OUTER(ResizeTo, (aWidth, aHeight), NS_ERROR_NOT_INITIALIZED);
    5404                 : 
    5405                 :   /*
    5406                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    5407                 :    * prevent window.resizeTo() by exiting early
    5408                 :    */
    5409                 : 
    5410               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    5411               0 :     return NS_OK;
    5412                 :   }
    5413                 : 
    5414               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    5415               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    5416               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    5417                 :   
    5418               0 :   NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(&aWidth, &aHeight),
    5419                 :                     NS_ERROR_FAILURE);
    5420                 : 
    5421               0 :   nsIntSize devSz(CSSToDevIntPixels(nsIntSize(aWidth, aHeight)));
    5422                 : 
    5423               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetSize(devSz.width, devSz.height, true),
    5424                 :                     NS_ERROR_FAILURE);
    5425                 : 
    5426               0 :   return NS_OK;
    5427                 : }
    5428                 : 
    5429                 : NS_IMETHODIMP
    5430               0 : nsGlobalWindow::ResizeBy(PRInt32 aWidthDif, PRInt32 aHeightDif)
    5431                 : {
    5432               0 :   FORWARD_TO_OUTER(ResizeBy, (aWidthDif, aHeightDif), NS_ERROR_NOT_INITIALIZED);
    5433                 : 
    5434                 :   /*
    5435                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    5436                 :    * prevent window.resizeBy() by exiting early
    5437                 :    */
    5438                 : 
    5439               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    5440               0 :     return NS_OK;
    5441                 :   }
    5442                 : 
    5443               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    5444               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    5445               0 :   NS_ENSURE_TRUE(treeOwnerAsWin, NS_ERROR_FAILURE);
    5446                 : 
    5447                 :   PRInt32 width, height;
    5448               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->GetSize(&width, &height), NS_ERROR_FAILURE);
    5449                 : 
    5450                 :   // To do this correctly we have to convert what we got from GetSize
    5451                 :   // into CSS pixels, add the arguments, do the security check, and
    5452                 :   // then convert back to device pixels for the call to SetSize.
    5453                 : 
    5454               0 :   nsIntSize cssSize(DevToCSSIntPixels(nsIntSize(width, height)));
    5455                 : 
    5456               0 :   cssSize.width += aWidthDif;
    5457               0 :   cssSize.height += aHeightDif;
    5458                 : 
    5459               0 :   NS_ENSURE_SUCCESS(CheckSecurityWidthAndHeight(&cssSize.width,
    5460                 :                                                 &cssSize.height),
    5461                 :                     NS_ERROR_FAILURE);
    5462                 : 
    5463               0 :   nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
    5464                 : 
    5465               0 :   NS_ENSURE_SUCCESS(treeOwnerAsWin->SetSize(newDevSize.width,
    5466                 :                                             newDevSize.height,
    5467                 :                                             true),
    5468                 :                     NS_ERROR_FAILURE);
    5469                 : 
    5470               0 :   return NS_OK;
    5471                 : }
    5472                 : 
    5473                 : NS_IMETHODIMP
    5474               0 : nsGlobalWindow::SizeToContent()
    5475                 : {
    5476               0 :   FORWARD_TO_OUTER(SizeToContent, (), NS_ERROR_NOT_INITIALIZED);
    5477                 : 
    5478               0 :   if (!mDocShell) {
    5479               0 :     return NS_OK;
    5480                 :   }
    5481                 : 
    5482                 :   /*
    5483                 :    * If caller is not chrome and the user has not explicitly exempted the site,
    5484                 :    * prevent window.sizeToContent() by exiting early
    5485                 :    */
    5486                 : 
    5487               0 :   if (!CanMoveResizeWindows() || IsFrame()) {
    5488               0 :     return NS_OK;
    5489                 :   }
    5490                 : 
    5491                 :   // The content viewer does a check to make sure that it's a content
    5492                 :   // viewer for a toplevel docshell.
    5493                 :   
    5494               0 :   nsCOMPtr<nsIContentViewer> cv;
    5495               0 :   mDocShell->GetContentViewer(getter_AddRefs(cv));
    5496               0 :   nsCOMPtr<nsIMarkupDocumentViewer> markupViewer(do_QueryInterface(cv));
    5497               0 :   NS_ENSURE_TRUE(markupViewer, NS_ERROR_FAILURE);
    5498               0 :   NS_ENSURE_SUCCESS(markupViewer->SizeToContent(), NS_ERROR_FAILURE);
    5499                 : 
    5500               0 :   return NS_OK;
    5501                 : }
    5502                 : 
    5503                 : NS_IMETHODIMP
    5504               0 : nsGlobalWindow::GetWindowRoot(nsIDOMEventTarget **aWindowRoot)
    5505                 : {
    5506               0 :   nsCOMPtr<nsPIWindowRoot> root = GetTopWindowRoot();
    5507               0 :   return CallQueryInterface(root, aWindowRoot);
    5508                 : }
    5509                 : 
    5510                 : already_AddRefed<nsPIWindowRoot>
    5511               0 : nsGlobalWindow::GetTopWindowRoot()
    5512                 : {
    5513               0 :   nsIDOMWindow *rootWindow = GetPrivateRoot();
    5514               0 :   nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(rootWindow));
    5515               0 :   if (!piWin)
    5516               0 :     return nsnull;
    5517                 : 
    5518               0 :   nsCOMPtr<nsPIWindowRoot> window = do_QueryInterface(piWin->GetChromeEventHandler());
    5519               0 :   return window.forget();
    5520                 : }
    5521                 : 
    5522                 : NS_IMETHODIMP
    5523               0 : nsGlobalWindow::Scroll(PRInt32 aXScroll, PRInt32 aYScroll)
    5524                 : {
    5525               0 :   return ScrollTo(aXScroll, aYScroll);
    5526                 : }
    5527                 : 
    5528                 : NS_IMETHODIMP
    5529               0 : nsGlobalWindow::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)
    5530                 : {
    5531               0 :   FlushPendingNotifications(Flush_Layout);
    5532               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    5533                 : 
    5534               0 :   if (sf) {
    5535                 :     // Here we calculate what the max pixel value is that we can
    5536                 :     // scroll to, we do this by dividing maxint with the pixel to
    5537                 :     // twips conversion factor, and substracting 4, the 4 comes from
    5538                 :     // experimenting with this value, anything less makes the view
    5539                 :     // code not scroll correctly, I have no idea why. -- jst
    5540               0 :     const PRInt32 maxpx = nsPresContext::AppUnitsToIntCSSPixels(0x7fffffff) - 4;
    5541                 : 
    5542               0 :     if (aXScroll > maxpx) {
    5543               0 :       aXScroll = maxpx;
    5544                 :     }
    5545                 : 
    5546               0 :     if (aYScroll > maxpx) {
    5547               0 :       aYScroll = maxpx;
    5548                 :     }
    5549                 :     sf->ScrollTo(nsPoint(nsPresContext::CSSPixelsToAppUnits(aXScroll),
    5550                 :                          nsPresContext::CSSPixelsToAppUnits(aYScroll)),
    5551               0 :                  nsIScrollableFrame::INSTANT);
    5552                 :   }
    5553                 : 
    5554               0 :   return NS_OK;
    5555                 : }
    5556                 : 
    5557                 : NS_IMETHODIMP
    5558               0 : nsGlobalWindow::ScrollBy(PRInt32 aXScrollDif, PRInt32 aYScrollDif)
    5559                 : {
    5560               0 :   FlushPendingNotifications(Flush_Layout);
    5561               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    5562                 : 
    5563               0 :   if (sf) {
    5564               0 :     nsPoint scrollPos = sf->GetScrollPosition();
    5565                 :     // It seems like it would make more sense for ScrollBy to use
    5566                 :     // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
    5567                 :     // Perhaps Web content does too.
    5568               0 :     return ScrollTo(nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x) + aXScrollDif,
    5569               0 :                     nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y) + aYScrollDif);
    5570                 :   }
    5571                 : 
    5572               0 :   return NS_OK;
    5573                 : }
    5574                 : 
    5575                 : NS_IMETHODIMP
    5576               0 : nsGlobalWindow::ScrollByLines(PRInt32 numLines)
    5577                 : {
    5578               0 :   FlushPendingNotifications(Flush_Layout);
    5579               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    5580               0 :   if (sf) {
    5581                 :     // It seems like it would make more sense for ScrollByLines to use
    5582                 :     // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
    5583                 :     // Perhaps Web content does too.
    5584                 :     sf->ScrollBy(nsIntPoint(0, numLines), nsIScrollableFrame::LINES,
    5585               0 :                  nsIScrollableFrame::INSTANT);
    5586                 :   }
    5587                 : 
    5588               0 :   return NS_OK;
    5589                 : }
    5590                 : 
    5591                 : NS_IMETHODIMP
    5592               0 : nsGlobalWindow::ScrollByPages(PRInt32 numPages)
    5593                 : {
    5594               0 :   FlushPendingNotifications(Flush_Layout);
    5595               0 :   nsIScrollableFrame *sf = GetScrollFrame();
    5596               0 :   if (sf) {
    5597                 :     // It seems like it would make more sense for ScrollByPages to use
    5598                 :     // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
    5599                 :     // Perhaps Web content does too.
    5600                 :     sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
    5601               0 :                  nsIScrollableFrame::INSTANT);
    5602                 :   }
    5603                 : 
    5604               0 :   return NS_OK;
    5605                 : }
    5606                 : 
    5607                 : NS_IMETHODIMP
    5608               0 : nsGlobalWindow::ClearTimeout(PRInt32 aHandle)
    5609                 : {
    5610               0 :   if (aHandle <= 0) {
    5611               0 :     return NS_OK;
    5612                 :   }
    5613                 : 
    5614               0 :   return ClearTimeoutOrInterval(aHandle);
    5615                 : }
    5616                 : 
    5617                 : NS_IMETHODIMP
    5618               0 : nsGlobalWindow::ClearInterval(PRInt32 aHandle)
    5619                 : {
    5620               0 :   if (aHandle <= 0) {
    5621               0 :     return NS_OK;
    5622                 :   }
    5623                 : 
    5624               0 :   return ClearTimeoutOrInterval(aHandle);
    5625                 : }
    5626                 : 
    5627                 : NS_IMETHODIMP
    5628               0 : nsGlobalWindow::SetTimeout(PRInt32 *_retval)
    5629                 : {
    5630               0 :   return SetTimeoutOrInterval(false, _retval);
    5631                 : }
    5632                 : 
    5633                 : NS_IMETHODIMP
    5634               0 : nsGlobalWindow::SetInterval(PRInt32 *_retval)
    5635                 : {
    5636               0 :   return SetTimeoutOrInterval(true, _retval);
    5637                 : }
    5638                 : 
    5639                 : NS_IMETHODIMP
    5640               0 : nsGlobalWindow::SetResizable(bool aResizable)
    5641                 : {
    5642                 :   // nop
    5643                 : 
    5644               0 :   return NS_OK;
    5645                 : }
    5646                 : 
    5647                 : static void
    5648               0 : ReportUseOfDeprecatedMethod(nsGlobalWindow* aWindow, const char* aWarning)
    5649                 : {
    5650               0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
    5651                 :   nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
    5652                 :                                   "DOM Events", doc,
    5653                 :                                   nsContentUtils::eDOM_PROPERTIES,
    5654               0 :                                   aWarning);
    5655               0 : }
    5656                 : 
    5657                 : NS_IMETHODIMP
    5658               0 : nsGlobalWindow::CaptureEvents(PRInt32 aEventFlags)
    5659                 : {
    5660               0 :   ReportUseOfDeprecatedMethod(this, "UseOfCaptureEventsWarning");
    5661               0 :   return NS_OK;
    5662                 : }
    5663                 : 
    5664                 : NS_IMETHODIMP
    5665               0 : nsGlobalWindow::ReleaseEvents(PRInt32 aEventFlags)
    5666                 : {
    5667               0 :   ReportUseOfDeprecatedMethod(this, "UseOfReleaseEventsWarning");
    5668               0 :   return NS_OK;
    5669                 : }
    5670                 : 
    5671                 : NS_IMETHODIMP
    5672               0 : nsGlobalWindow::RouteEvent(nsIDOMEvent* aEvt)
    5673                 : {
    5674               0 :   ReportUseOfDeprecatedMethod(this, "UseOfRouteEventWarning");
    5675               0 :   return NS_OK;
    5676                 : }
    5677                 : 
    5678                 : NS_IMETHODIMP
    5679               0 : nsGlobalWindow::EnableExternalCapture()
    5680                 : {
    5681               0 :   return NS_ERROR_FAILURE;
    5682                 : }
    5683                 : 
    5684                 : NS_IMETHODIMP
    5685               0 : nsGlobalWindow::DisableExternalCapture()
    5686                 : {
    5687               0 :   return NS_ERROR_FAILURE;
    5688                 : }
    5689                 : 
    5690                 : static
    5691               0 : bool IsPopupBlocked(nsIDOMDocument* aDoc)
    5692                 : {
    5693                 :   nsCOMPtr<nsIPopupWindowManager> pm =
    5694               0 :     do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
    5695                 : 
    5696               0 :   if (!pm) {
    5697               0 :     return false;
    5698                 :   }
    5699                 : 
    5700               0 :   bool blocked = true;
    5701               0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(aDoc));
    5702                 : 
    5703               0 :   if (doc) {
    5704               0 :     PRUint32 permission = nsIPopupWindowManager::ALLOW_POPUP;
    5705               0 :     pm->TestPermission(doc->GetDocumentURI(), &permission);
    5706               0 :     blocked = (permission == nsIPopupWindowManager::DENY_POPUP);
    5707                 :   }
    5708               0 :   return blocked;
    5709                 : }
    5710                 : 
    5711                 : /* static */
    5712                 : void 
    5713               0 : nsGlobalWindow::FirePopupBlockedEvent(nsIDOMDocument* aDoc,
    5714                 :                                       nsIDOMWindow *aRequestingWindow, nsIURI *aPopupURI,
    5715                 :                                       const nsAString &aPopupWindowName,
    5716                 :                                       const nsAString &aPopupWindowFeatures)
    5717                 : {
    5718               0 :   if (aDoc) {
    5719                 :     // Fire a "DOMPopupBlocked" event so that the UI can hear about
    5720                 :     // blocked popups.
    5721               0 :     nsCOMPtr<nsIDOMEvent> event;
    5722               0 :     aDoc->CreateEvent(NS_LITERAL_STRING("PopupBlockedEvents"),
    5723               0 :                       getter_AddRefs(event));
    5724               0 :     if (event) {
    5725               0 :       nsCOMPtr<nsIDOMPopupBlockedEvent> pbev(do_QueryInterface(event));
    5726               0 :       pbev->InitPopupBlockedEvent(NS_LITERAL_STRING("DOMPopupBlocked"),
    5727                 :                                   true, true, aRequestingWindow,
    5728                 :                                   aPopupURI, aPopupWindowName,
    5729               0 :                                   aPopupWindowFeatures);
    5730               0 :       nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
    5731               0 :       privateEvent->SetTrusted(true);
    5732                 : 
    5733               0 :       nsCOMPtr<nsIDOMEventTarget> targ(do_QueryInterface(aDoc));
    5734                 :       bool defaultActionEnabled;
    5735               0 :       targ->DispatchEvent(event, &defaultActionEnabled);
    5736                 :     }
    5737                 :   }
    5738               0 : }
    5739                 : 
    5740               0 : void FirePopupWindowEvent(nsIDOMDocument* aDoc)
    5741                 : {
    5742                 :   // Fire a "PopupWindow" event
    5743               0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(aDoc));
    5744                 :   nsContentUtils::DispatchTrustedEvent(doc, aDoc,
    5745               0 :                                        NS_LITERAL_STRING("PopupWindow"),
    5746               0 :                                        true, true);
    5747               0 : }
    5748                 : 
    5749                 : // static
    5750                 : bool
    5751               0 : nsGlobalWindow::CanSetProperty(const char *aPrefName)
    5752                 : {
    5753                 :   // Chrome can set any property.
    5754               0 :   if (nsContentUtils::IsCallerTrustedForWrite()) {
    5755               0 :     return true;
    5756                 :   }
    5757                 : 
    5758                 :   // If the pref is set to true, we can not set the property
    5759                 :   // and vice versa.
    5760               0 :   return !Preferences::GetBool(aPrefName, true);
    5761                 : }
    5762                 : 
    5763                 : bool
    5764               0 : nsGlobalWindow::PopupWhitelisted()
    5765                 : {
    5766               0 :   if (!IsPopupBlocked(mDocument))
    5767               0 :     return true;
    5768                 : 
    5769               0 :   nsCOMPtr<nsIDOMWindow> parent;
    5770                 : 
    5771               0 :   if (NS_FAILED(GetParent(getter_AddRefs(parent))) ||
    5772               0 :       parent == static_cast<nsIDOMWindow*>(this))
    5773                 :   {
    5774               0 :     return false;
    5775                 :   }
    5776                 : 
    5777                 :   return static_cast<nsGlobalWindow*>
    5778                 :                     (static_cast<nsIDOMWindow*>
    5779               0 :                                 (parent.get()))->PopupWhitelisted();
    5780                 : }
    5781                 : 
    5782                 : /*
    5783                 :  * Examine the current document state to see if we're in a way that is
    5784                 :  * typically abused by web designers. The window.open code uses this
    5785                 :  * routine to determine whether to allow the new window.
    5786                 :  * Returns a value from the PopupControlState enum.
    5787                 :  */
    5788                 : PopupControlState
    5789               0 : nsGlobalWindow::RevisePopupAbuseLevel(PopupControlState aControl)
    5790                 : {
    5791               0 :   FORWARD_TO_OUTER(RevisePopupAbuseLevel, (aControl), aControl);
    5792                 : 
    5793               0 :   NS_ASSERTION(mDocShell, "Must have docshell");
    5794                 :   
    5795               0 :   nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(mDocShell));
    5796                 : 
    5797               0 :   NS_ASSERTION(item, "Docshell doesn't implement nsIDocShellTreeItem?");
    5798                 : 
    5799               0 :   PRInt32 type = nsIDocShellTreeItem::typeChrome;
    5800               0 :   item->GetItemType(&type);
    5801               0 :   if (type != nsIDocShellTreeItem::typeContent)
    5802               0 :     return openAllowed;
    5803                 : 
    5804               0 :   PopupControlState abuse = aControl;
    5805               0 :   switch (abuse) {
    5806                 :   case openControlled:
    5807                 :   case openAbused:
    5808                 :   case openOverridden:
    5809               0 :     if (PopupWhitelisted())
    5810               0 :       abuse = PopupControlState(abuse - 1);
    5811               0 :   case openAllowed: break;
    5812                 :   default:
    5813               0 :     NS_WARNING("Strange PopupControlState!");
    5814                 :   }
    5815                 : 
    5816                 :   // limit the number of simultaneously open popups
    5817               0 :   if (abuse == openAbused || abuse == openControlled) {
    5818               0 :     PRInt32 popupMax = Preferences::GetInt("dom.popup_maximum", -1);
    5819               0 :     if (popupMax >= 0 && gOpenPopupSpamCount >= popupMax)
    5820               0 :       abuse = openOverridden;
    5821                 :   }
    5822                 : 
    5823               0 :   return abuse;
    5824                 : }
    5825                 : 
    5826                 : /* If a window open is blocked, fire the appropriate DOM events.
    5827                 :    aBlocked signifies we just blocked a popup.
    5828                 :    aWindow signifies we just opened what is probably a popup.
    5829                 : */
    5830                 : void
    5831               0 : nsGlobalWindow::FireAbuseEvents(bool aBlocked, bool aWindow,
    5832                 :                                 const nsAString &aPopupURL,
    5833                 :                                 const nsAString &aPopupWindowName,
    5834                 :                                 const nsAString &aPopupWindowFeatures)
    5835                 : {
    5836                 :   // fetch the URI of the window requesting the opened window
    5837                 : 
    5838               0 :   nsCOMPtr<nsIDOMWindow> topWindow;
    5839               0 :   GetTop(getter_AddRefs(topWindow));
    5840               0 :   if (!topWindow)
    5841                 :     return;
    5842                 : 
    5843               0 :   nsCOMPtr<nsIDOMDocument> topDoc;
    5844               0 :   topWindow->GetDocument(getter_AddRefs(topDoc));
    5845                 : 
    5846               0 :   nsCOMPtr<nsIURI> popupURI;
    5847                 : 
    5848                 :   // build the URI of the would-have-been popup window
    5849                 :   // (see nsWindowWatcher::URIfromURL)
    5850                 : 
    5851                 :   // first, fetch the opener's base URI
    5852                 : 
    5853               0 :   nsIURI *baseURL = 0;
    5854                 : 
    5855               0 :   JSContext *cx = nsContentUtils::GetCurrentJSContext();
    5856               0 :   nsCOMPtr<nsIDOMWindow> contextWindow;
    5857                 : 
    5858               0 :   if (cx) {
    5859               0 :     nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx);
    5860               0 :     if (currentCX) {
    5861               0 :       contextWindow = do_QueryInterface(currentCX->GetGlobalObject());
    5862                 :     }
    5863                 :   }
    5864               0 :   if (!contextWindow)
    5865               0 :     contextWindow = static_cast<nsIDOMWindow*>(this);
    5866                 : 
    5867               0 :   nsCOMPtr<nsIDOMDocument> domdoc;
    5868               0 :   contextWindow->GetDocument(getter_AddRefs(domdoc));
    5869               0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
    5870               0 :   if (doc)
    5871               0 :     baseURL = doc->GetDocBaseURI();
    5872                 : 
    5873                 :   // use the base URI to build what would have been the popup's URI
    5874               0 :   nsCOMPtr<nsIIOService> ios(do_GetService(NS_IOSERVICE_CONTRACTID));
    5875               0 :   if (ios)
    5876               0 :     ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), 0, baseURL,
    5877               0 :                 getter_AddRefs(popupURI));
    5878                 : 
    5879                 :   // fire an event chock full of informative URIs
    5880               0 :   if (aBlocked)
    5881                 :     FirePopupBlockedEvent(topDoc, this, popupURI, aPopupWindowName,
    5882               0 :                           aPopupWindowFeatures);
    5883               0 :   if (aWindow)
    5884               0 :     FirePopupWindowEvent(topDoc);
    5885                 : }
    5886                 : 
    5887                 : NS_IMETHODIMP
    5888               0 : nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName,
    5889                 :                      const nsAString& aOptions, nsIDOMWindow **_retval)
    5890                 : {
    5891                 :   return OpenInternal(aUrl, aName, aOptions,
    5892                 :                       false,          // aDialog
    5893                 :                       false,          // aContentModal
    5894                 :                       true,           // aCalledNoScript
    5895                 :                       false,          // aDoJSFixups
    5896                 :                       nsnull, nsnull,    // No args
    5897               0 :                       GetPrincipal(),    // aCalleePrincipal
    5898                 :                       nsnull,            // aJSCallerContext
    5899               0 :                       _retval);
    5900                 : }
    5901                 : 
    5902                 : NS_IMETHODIMP
    5903               0 : nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName,
    5904                 :                        const nsAString& aOptions, nsIDOMWindow **_retval)
    5905                 : {
    5906                 :   return OpenInternal(aUrl, aName, aOptions,
    5907                 :                       false,          // aDialog
    5908                 :                       false,          // aContentModal
    5909                 :                       false,          // aCalledNoScript
    5910                 :                       true,           // aDoJSFixups
    5911                 :                       nsnull, nsnull,    // No args
    5912               0 :                       GetPrincipal(),    // aCalleePrincipal
    5913                 :                       nsContentUtils::GetCurrentJSContext(), // aJSCallerContext
    5914               0 :                       _retval);
    5915                 : }
    5916                 : 
    5917                 : // like Open, but attaches to the new window any extra parameters past
    5918                 : // [features] as a JS property named "arguments"
    5919                 : NS_IMETHODIMP
    5920               0 : nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
    5921                 :                            const nsAString& aOptions,
    5922                 :                            nsISupports* aExtraArgument, nsIDOMWindow** _retval)
    5923                 : {
    5924                 :   return OpenInternal(aUrl, aName, aOptions,
    5925                 :                       true,                    // aDialog
    5926                 :                       false,                   // aContentModal
    5927                 :                       true,                    // aCalledNoScript
    5928                 :                       false,                   // aDoJSFixups
    5929                 :                       nsnull, aExtraArgument,     // Arguments
    5930               0 :                       GetPrincipal(),             // aCalleePrincipal
    5931                 :                       nsnull,                     // aJSCallerContext
    5932               0 :                       _retval);
    5933                 : }
    5934                 : 
    5935                 : NS_IMETHODIMP
    5936               0 : nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName,
    5937                 :                            const nsAString& aOptions, nsIDOMWindow** _retval)
    5938                 : {
    5939               0 :   if (!nsContentUtils::IsCallerTrustedForWrite()) {
    5940               0 :     return NS_ERROR_DOM_SECURITY_ERR;
    5941                 :   }
    5942                 : 
    5943               0 :   nsAXPCNativeCallContext *ncc = nsnull;
    5944               0 :   nsresult rv = nsContentUtils::XPConnect()->
    5945               0 :     GetCurrentNativeCallContext(&ncc);
    5946               0 :   NS_ENSURE_SUCCESS(rv, rv);
    5947                 : 
    5948               0 :   if (!ncc)
    5949               0 :     return NS_ERROR_NOT_AVAILABLE;
    5950                 : 
    5951               0 :   JSContext *cx = nsnull;
    5952                 : 
    5953               0 :   rv = ncc->GetJSContext(&cx);
    5954               0 :   NS_ENSURE_SUCCESS(rv, rv);
    5955                 : 
    5956                 :   PRUint32 argc;
    5957               0 :   jsval *argv = nsnull;
    5958                 : 
    5959                 :   // XXX - need to get this as nsISupports?
    5960               0 :   ncc->GetArgc(&argc);
    5961               0 :   ncc->GetArgvPtr(&argv);
    5962                 : 
    5963                 :   // Strip the url, name and options from the args seen by scripts.
    5964               0 :   PRUint32 argOffset = argc < 3 ? argc : 3;
    5965               0 :   nsCOMPtr<nsIJSArgArray> argvArray;
    5966               0 :   rv = NS_CreateJSArgv(cx, argc - argOffset, argv + argOffset,
    5967               0 :                        getter_AddRefs(argvArray));
    5968               0 :   NS_ENSURE_SUCCESS(rv, rv);
    5969                 : 
    5970                 :   return OpenInternal(aUrl, aName, aOptions,
    5971                 :                       true,             // aDialog
    5972                 :                       false,            // aContentModal
    5973                 :                       false,            // aCalledNoScript
    5974                 :                       false,            // aDoJSFixups
    5975                 :                       argvArray, nsnull,   // Arguments
    5976               0 :                       GetPrincipal(),      // aCalleePrincipal
    5977                 :                       cx,                  // aJSCallerContext
    5978               0 :                       _retval);
    5979                 : }
    5980                 : 
    5981                 : NS_IMETHODIMP
    5982               0 : nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
    5983                 : {
    5984               0 :   FORWARD_TO_OUTER(GetFrames, (aFrames), NS_ERROR_NOT_INITIALIZED);
    5985                 : 
    5986               0 :   *aFrames = this;
    5987               0 :   NS_ADDREF(*aFrames);
    5988                 : 
    5989               0 :   FlushPendingNotifications(Flush_ContentAndNotify);
    5990                 : 
    5991               0 :   return NS_OK;
    5992                 : }
    5993                 : 
    5994                 : nsGlobalWindow*
    5995               0 : nsGlobalWindow::CallerInnerWindow()
    5996                 : {
    5997               0 :   JSContext *cx = nsContentUtils::GetCurrentJSContext();
    5998               0 :   if (!cx) {
    5999               0 :     NS_ERROR("Please don't call this method from C++!");
    6000                 : 
    6001               0 :     return nsnull;
    6002                 :   }
    6003                 : 
    6004               0 :   JSObject *scope = nsnull;
    6005               0 :   JSStackFrame *fp = nsnull;
    6006               0 :   JS_FrameIterator(cx, &fp);
    6007               0 :   if (fp) {
    6008               0 :     while (!JS_IsScriptFrame(cx, fp)) {
    6009               0 :       if (!JS_FrameIterator(cx, &fp))
    6010               0 :         break;
    6011                 :     }
    6012                 : 
    6013               0 :     if (fp)
    6014               0 :       scope = JS_GetGlobalForFrame(fp);
    6015                 :   }
    6016                 : 
    6017               0 :   if (!scope)
    6018               0 :     scope = JS_GetGlobalForScopeChain(cx);
    6019                 : 
    6020               0 :   JSAutoEnterCompartment ac;
    6021               0 :   if (!ac.enter(cx, scope))
    6022               0 :     return nsnull;
    6023                 : 
    6024               0 :   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
    6025               0 :   nsContentUtils::XPConnect()->
    6026               0 :     GetWrappedNativeOfJSObject(cx, scope, getter_AddRefs(wrapper));
    6027               0 :   if (!wrapper)
    6028               0 :     return nsnull;
    6029                 : 
    6030                 :   // The calling window must be holding a reference, so we can just return a
    6031                 :   // raw pointer here and let the QI's addref be balanced by the nsCOMPtr
    6032                 :   // destructor's release.
    6033               0 :   nsCOMPtr<nsPIDOMWindow> win = do_QueryWrappedNative(wrapper);
    6034               0 :   if (!win)
    6035               0 :     return GetCurrentInnerWindowInternal();
    6036               0 :   return static_cast<nsGlobalWindow*>(win.get());
    6037                 : }
    6038                 : 
    6039                 : /**
    6040                 :  * Class used to represent events generated by calls to Window.postMessage,
    6041                 :  * which asynchronously creates and dispatches events.
    6042                 :  */
    6043                 : class PostMessageEvent : public nsRunnable
    6044                 : {
    6045                 :   public:
    6046                 :     NS_DECL_NSIRUNNABLE
    6047                 : 
    6048               0 :     PostMessageEvent(nsGlobalWindow* aSource,
    6049                 :                      const nsAString& aCallerOrigin,
    6050                 :                      nsGlobalWindow* aTargetWindow,
    6051                 :                      nsIURI* aProvidedOrigin,
    6052                 :                      bool aTrustedCaller)
    6053                 :     : mSource(aSource),
    6054                 :       mCallerOrigin(aCallerOrigin),
    6055                 :       mMessage(nsnull),
    6056                 :       mMessageLen(0),
    6057                 :       mTargetWindow(aTargetWindow),
    6058                 :       mProvidedOrigin(aProvidedOrigin),
    6059               0 :       mTrustedCaller(aTrustedCaller)
    6060                 :     {
    6061               0 :       MOZ_COUNT_CTOR(PostMessageEvent);
    6062               0 :     }
    6063                 :     
    6064               0 :     ~PostMessageEvent()
    6065               0 :     {
    6066               0 :       NS_ASSERTION(!mMessage, "Message should have been deserialized!");
    6067               0 :       MOZ_COUNT_DTOR(PostMessageEvent);
    6068               0 :     }
    6069                 : 
    6070               0 :     void SetJSData(JSAutoStructuredCloneBuffer& aBuffer)
    6071                 :     {
    6072               0 :       NS_ASSERTION(!mMessage && mMessageLen == 0, "Don't call twice!");
    6073               0 :       aBuffer.steal(&mMessage, &mMessageLen);
    6074               0 :     }
    6075                 : 
    6076               0 :     bool StoreISupports(nsISupports* aSupports)
    6077                 :     {
    6078               0 :       mSupportsArray.AppendElement(aSupports);
    6079               0 :       return true;
    6080                 :     }
    6081                 : 
    6082                 :   private:
    6083                 :     nsRefPtr<nsGlobalWindow> mSource;
    6084                 :     nsString mCallerOrigin;
    6085                 :     uint64_t* mMessage;
    6086                 :     size_t mMessageLen;
    6087                 :     nsRefPtr<nsGlobalWindow> mTargetWindow;
    6088                 :     nsCOMPtr<nsIURI> mProvidedOrigin;
    6089                 :     bool mTrustedCaller;
    6090                 :     nsTArray<nsCOMPtr<nsISupports> > mSupportsArray;
    6091                 : };
    6092                 : 
    6093                 : namespace {
    6094                 : 
    6095                 : struct StructuredCloneInfo {
    6096                 :   PostMessageEvent* event;
    6097                 :   bool subsumes;
    6098                 : };
    6099                 : 
    6100                 : static JSObject*
    6101               0 : PostMessageReadStructuredClone(JSContext* cx,
    6102                 :                                JSStructuredCloneReader* reader,
    6103                 :                                uint32 tag,
    6104                 :                                uint32 data,
    6105                 :                                void* closure)
    6106                 : {
    6107               0 :   NS_ASSERTION(closure, "Must have closure!");
    6108                 : 
    6109               0 :   if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
    6110               0 :     NS_ASSERTION(!data, "Data should be empty");
    6111                 : 
    6112                 :     nsISupports* supports;
    6113               0 :     if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
    6114               0 :       JSObject* global = JS_GetGlobalForScopeChain(cx);
    6115               0 :       if (global) {
    6116                 :         jsval val;
    6117               0 :         nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
    6118               0 :         if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, global, supports,
    6119                 :                                                     &val,
    6120                 :                                                     getter_AddRefs(wrapper)))) {
    6121               0 :           return JSVAL_TO_OBJECT(val);
    6122                 :         }
    6123                 :       }
    6124                 :     }
    6125                 :   }
    6126                 : 
    6127                 :   const JSStructuredCloneCallbacks* runtimeCallbacks =
    6128               0 :     js::GetContextStructuredCloneCallbacks(cx);
    6129                 : 
    6130               0 :   if (runtimeCallbacks) {
    6131               0 :     return runtimeCallbacks->read(cx, reader, tag, data, nsnull);
    6132                 :   }
    6133                 : 
    6134               0 :   return JS_FALSE;
    6135                 : }
    6136                 : 
    6137                 : static JSBool
    6138               0 : PostMessageWriteStructuredClone(JSContext* cx,
    6139                 :                                 JSStructuredCloneWriter* writer,
    6140                 :                                 JSObject* obj,
    6141                 :                                 void *closure)
    6142                 : {
    6143               0 :   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
    6144               0 :   NS_ASSERTION(scInfo, "Must have scInfo!");
    6145                 : 
    6146               0 :   nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
    6147               0 :   nsContentUtils::XPConnect()->
    6148               0 :     GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative));
    6149               0 :   if (wrappedNative) {
    6150               0 :     PRUint32 scTag = 0;
    6151               0 :     nsISupports* supports = wrappedNative->Native();
    6152                 : 
    6153               0 :     nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
    6154               0 :     if (blob && scInfo->subsumes)
    6155               0 :       scTag = SCTAG_DOM_BLOB;
    6156                 : 
    6157               0 :     nsCOMPtr<nsIDOMFileList> list = do_QueryInterface(supports);
    6158               0 :     if (list && scInfo->subsumes)
    6159               0 :       scTag = SCTAG_DOM_FILELIST;
    6160                 : 
    6161               0 :     if (scTag)
    6162               0 :       return JS_WriteUint32Pair(writer, scTag, 0) &&
    6163               0 :              JS_WriteBytes(writer, &supports, sizeof(supports)) &&
    6164               0 :              scInfo->event->StoreISupports(supports);
    6165                 :   }
    6166                 : 
    6167                 :   const JSStructuredCloneCallbacks* runtimeCallbacks =
    6168               0 :     js::GetContextStructuredCloneCallbacks(cx);
    6169                 : 
    6170               0 :   if (runtimeCallbacks) {
    6171               0 :     return runtimeCallbacks->write(cx, writer, obj, nsnull);
    6172                 :   }
    6173                 : 
    6174               0 :   return JS_FALSE;
    6175                 : }
    6176                 : 
    6177                 : JSStructuredCloneCallbacks kPostMessageCallbacks = {
    6178                 :   PostMessageReadStructuredClone,
    6179                 :   PostMessageWriteStructuredClone,
    6180                 :   nsnull
    6181                 : };
    6182                 : 
    6183                 : } // anonymous namespace
    6184                 : 
    6185                 : NS_IMETHODIMP
    6186               0 : PostMessageEvent::Run()
    6187                 : {
    6188               0 :   NS_ABORT_IF_FALSE(mTargetWindow->IsOuterWindow(),
    6189                 :                     "should have been passed an outer window!");
    6190               0 :   NS_ABORT_IF_FALSE(!mSource || mSource->IsOuterWindow(),
    6191                 :                     "should have been passed an outer window!");
    6192                 : 
    6193                 :   // Get the JSContext for the target window
    6194               0 :   JSContext* cx = nsnull;
    6195               0 :   nsIScriptContext* scriptContext = mTargetWindow->GetContext();
    6196               0 :   if (scriptContext) {
    6197               0 :     cx = scriptContext->GetNativeContext();
    6198                 :   }
    6199                 : 
    6200               0 :   if (!cx) {
    6201                 :     // This can happen if mTargetWindow has been closed.  To avoid leaking,
    6202                 :     // we need to find a JSContext.
    6203               0 :     nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
    6204               0 :     if (cxStack) {
    6205               0 :       cxStack->GetSafeJSContext(&cx);
    6206                 :     }
    6207                 : 
    6208               0 :     if (!cx) {
    6209               0 :       NS_WARNING("Cannot find a JSContext!  Leaking PostMessage buffer.");
    6210               0 :       return NS_ERROR_FAILURE;
    6211                 :     }
    6212                 :   }
    6213                 : 
    6214                 :   // If we bailed before this point we're going to leak mMessage, but
    6215                 :   // that's probably better than crashing.
    6216                 : 
    6217                 :   // Ensure that the buffer is freed even if we fail to post the message
    6218               0 :   JSAutoStructuredCloneBuffer buffer;
    6219               0 :   buffer.adopt(mMessage, mMessageLen);
    6220               0 :   mMessage = nsnull;
    6221               0 :   mMessageLen = 0;
    6222                 : 
    6223               0 :   nsRefPtr<nsGlobalWindow> targetWindow;
    6224               0 :   if (mTargetWindow->IsClosedOrClosing() ||
    6225               0 :       !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) ||
    6226               0 :       targetWindow->IsClosedOrClosing())
    6227               0 :     return NS_OK;
    6228                 : 
    6229               0 :   NS_ABORT_IF_FALSE(targetWindow->IsInnerWindow(),
    6230                 :                     "we ordered an inner window!");
    6231                 : 
    6232                 :   // Ensure that any origin which might have been provided is the origin of this
    6233                 :   // window's document.  Note that we do this *now* instead of when postMessage
    6234                 :   // is called because the target window might have been navigated to a
    6235                 :   // different location between then and now.  If this check happened when
    6236                 :   // postMessage was called, it would be fairly easy for a malicious webpage to
    6237                 :   // intercept messages intended for another site by carefully timing navigation
    6238                 :   // of the target window so it changed location after postMessage but before
    6239                 :   // now.
    6240               0 :   if (mProvidedOrigin) {
    6241                 :     // Get the target's origin either from its principal or, in the case the
    6242                 :     // principal doesn't carry a URI (e.g. the system principal), the target's
    6243                 :     // document.
    6244               0 :     nsIPrincipal* targetPrin = targetWindow->GetPrincipal();
    6245               0 :     if (!targetPrin)
    6246               0 :       return NS_OK;
    6247               0 :     nsCOMPtr<nsIURI> targetURI;
    6248               0 :     if (NS_FAILED(targetPrin->GetURI(getter_AddRefs(targetURI))))
    6249               0 :       return NS_OK;
    6250               0 :     if (!targetURI) {
    6251               0 :       targetURI = targetWindow->mDoc->GetDocumentURI();
    6252               0 :       if (!targetURI)
    6253               0 :         return NS_OK;
    6254                 :     }
    6255                 : 
    6256                 :     // Note: This is contrary to the spec with respect to file: URLs, which
    6257                 :     //       the spec groups into a single origin, but given we intentionally
    6258                 :     //       don't do that in other places it seems better to hold the line for
    6259                 :     //       now.  Long-term, we want HTML5 to address this so that we can
    6260                 :     //       be compliant while being safer.
    6261               0 :     nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
    6262                 :     nsresult rv =
    6263               0 :       ssm->CheckSameOriginURI(mProvidedOrigin, targetURI, true);
    6264               0 :     if (NS_FAILED(rv))
    6265               0 :       return NS_OK;
    6266                 :   }
    6267                 : 
    6268                 :   // Deserialize the structured clone data
    6269                 :   jsval messageData;
    6270                 :   {
    6271               0 :     JSAutoRequest ar(cx);
    6272                 :     StructuredCloneInfo scInfo;
    6273               0 :     scInfo.event = this;
    6274                 : 
    6275               0 :     if (!buffer.read(cx, &messageData, &kPostMessageCallbacks, &scInfo))
    6276               0 :       return NS_ERROR_DOM_DATA_CLONE_ERR;
    6277                 :   }
    6278                 : 
    6279                 :   // Create the event
    6280               0 :   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(targetWindow->mDocument);
    6281               0 :   if (!domDoc)
    6282               0 :     return NS_OK;
    6283               0 :   nsCOMPtr<nsIDOMEvent> event;
    6284               0 :   domDoc->CreateEvent(NS_LITERAL_STRING("MessageEvent"),
    6285               0 :                       getter_AddRefs(event));
    6286               0 :   if (!event)
    6287               0 :     return NS_OK;
    6288                 : 
    6289               0 :   nsCOMPtr<nsIDOMMessageEvent> message = do_QueryInterface(event);
    6290               0 :   nsresult rv = message->InitMessageEvent(NS_LITERAL_STRING("message"),
    6291                 :                                           false /* non-bubbling */,
    6292                 :                                           true /* cancelable */,
    6293                 :                                           messageData,
    6294                 :                                           mCallerOrigin,
    6295               0 :                                           EmptyString(),
    6296               0 :                                           mSource);
    6297               0 :   if (NS_FAILED(rv))
    6298               0 :     return NS_OK;
    6299                 : 
    6300                 : 
    6301                 :   // We can't simply call dispatchEvent on the window because doing so ends
    6302                 :   // up flipping the trusted bit on the event, and we don't want that to
    6303                 :   // happen because then untrusted content can call postMessage on a chrome
    6304                 :   // window if it can get a reference to it.
    6305                 : 
    6306               0 :   nsIPresShell *shell = targetWindow->mDoc->GetShell();
    6307               0 :   nsRefPtr<nsPresContext> presContext;
    6308               0 :   if (shell)
    6309               0 :     presContext = shell->GetPresContext();
    6310                 : 
    6311               0 :   nsCOMPtr<nsIPrivateDOMEvent> privEvent = do_QueryInterface(message);
    6312               0 :   privEvent->SetTrusted(mTrustedCaller);
    6313               0 :   nsEvent *internalEvent = privEvent->GetInternalNSEvent();
    6314                 : 
    6315               0 :   nsEventStatus status = nsEventStatus_eIgnore;
    6316               0 :   nsEventDispatcher::Dispatch(static_cast<nsPIDOMWindow*>(mTargetWindow),
    6317                 :                               presContext,
    6318                 :                               internalEvent,
    6319                 :                               message,
    6320               0 :                               &status);
    6321               0 :   return NS_OK;
    6322                 : }
    6323                 : 
    6324                 : NS_IMETHODIMP
    6325               0 : nsGlobalWindow::PostMessageMoz(const jsval& aMessage,
    6326                 :                                const nsAString& aOrigin,
    6327                 :                                JSContext* aCx)
    6328                 : {
    6329               0 :   FORWARD_TO_OUTER(PostMessageMoz, (aMessage, aOrigin, aCx),
    6330                 :                    NS_ERROR_NOT_INITIALIZED);
    6331                 : 
    6332                 :   //
    6333                 :   // Window.postMessage is an intentional subversion of the same-origin policy.
    6334                 :   // As such, this code must be particularly careful in the information it
    6335                 :   // exposes to calling code.
    6336                 :   //
    6337                 :   // http://www.whatwg.org/specs/web-apps/current-work/multipage/section-crossDocumentMessages.html
    6338                 :   //
    6339                 : 
    6340                 :   // First, get the caller's window
    6341               0 :   nsRefPtr<nsGlobalWindow> callerInnerWin = CallerInnerWindow();
    6342               0 :   if (!callerInnerWin)
    6343               0 :     return NS_OK;
    6344               0 :   NS_ABORT_IF_FALSE(callerInnerWin->IsInnerWindow(),
    6345                 :                     "should have gotten an inner window here");
    6346                 : 
    6347                 :   // Compute the caller's origin either from its principal or, in the case the
    6348                 :   // principal doesn't carry a URI (e.g. the system principal), the caller's
    6349                 :   // document.  We must get this now instead of when the event is created and
    6350                 :   // dispatched, because ultimately it is the identity of the calling window
    6351                 :   // *now* that determines who sent the message (and not an identity which might
    6352                 :   // have changed due to intervening navigations).
    6353               0 :   nsIPrincipal* callerPrin = callerInnerWin->GetPrincipal();
    6354               0 :   if (!callerPrin)
    6355               0 :     return NS_OK;
    6356                 :   
    6357               0 :   nsCOMPtr<nsIURI> callerOuterURI;
    6358               0 :   if (NS_FAILED(callerPrin->GetURI(getter_AddRefs(callerOuterURI))))
    6359               0 :     return NS_OK;
    6360                 : 
    6361               0 :   nsAutoString origin;
    6362               0 :   if (callerOuterURI) {
    6363                 :     // if the principal has a URI, use that to generate the origin
    6364               0 :     nsContentUtils::GetUTFOrigin(callerPrin, origin);
    6365                 :   }
    6366                 :   else {
    6367                 :     // otherwise use the URI of the document to generate origin
    6368               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(callerInnerWin->mDocument);
    6369               0 :     if (!doc)
    6370               0 :       return NS_OK;
    6371               0 :     callerOuterURI = doc->GetDocumentURI();
    6372                 :     // if the principal has a URI, use that to generate the origin
    6373               0 :     nsContentUtils::GetUTFOrigin(callerOuterURI, origin);
    6374                 :   }
    6375                 : 
    6376                 :   // Convert the provided origin string into a URI for comparison purposes.
    6377                 :   // "*" indicates no specific origin is required.
    6378               0 :   nsCOMPtr<nsIURI> providedOrigin;
    6379               0 :   if (!aOrigin.EqualsASCII("*")) {
    6380               0 :     if (NS_FAILED(NS_NewURI(getter_AddRefs(providedOrigin), aOrigin)))
    6381               0 :       return NS_ERROR_DOM_SYNTAX_ERR;
    6382               0 :     if (NS_FAILED(providedOrigin->SetUserPass(EmptyCString())) ||
    6383               0 :         NS_FAILED(providedOrigin->SetPath(EmptyCString())))
    6384               0 :       return NS_OK;
    6385                 :   }
    6386                 : 
    6387                 :   // Create and asynchronously dispatch a runnable which will handle actual DOM
    6388                 :   // event creation and dispatch.
    6389                 :   nsRefPtr<PostMessageEvent> event =
    6390               0 :     new PostMessageEvent(nsContentUtils::IsCallerChrome()
    6391                 :                          ? nsnull
    6392               0 :                          : callerInnerWin->GetOuterWindowInternal(),
    6393                 :                          origin,
    6394                 :                          this,
    6395                 :                          providedOrigin,
    6396               0 :                          nsContentUtils::IsCallerTrustedForWrite());
    6397                 : 
    6398                 :   // We *must* clone the data here, or the jsval could be modified
    6399                 :   // by script
    6400               0 :   JSAutoStructuredCloneBuffer buffer;
    6401                 :   StructuredCloneInfo scInfo;
    6402               0 :   scInfo.event = event;
    6403                 : 
    6404               0 :   nsIPrincipal* principal = GetPrincipal();
    6405               0 :   if (NS_FAILED(callerPrin->Subsumes(principal, &scInfo.subsumes)))
    6406               0 :     return NS_ERROR_DOM_DATA_CLONE_ERR;
    6407                 : 
    6408               0 :   if (!buffer.write(aCx, aMessage, &kPostMessageCallbacks, &scInfo))
    6409               0 :     return NS_ERROR_DOM_DATA_CLONE_ERR;
    6410                 : 
    6411               0 :   event->SetJSData(buffer);
    6412                 : 
    6413               0 :   return NS_DispatchToCurrentThread(event);
    6414                 : }
    6415                 : 
    6416               0 : class nsCloseEvent : public nsRunnable {
    6417                 : 
    6418                 :   nsRefPtr<nsGlobalWindow> mWindow;
    6419                 : 
    6420               0 :   nsCloseEvent(nsGlobalWindow *aWindow)
    6421               0 :     : mWindow(aWindow)
    6422               0 :   {}
    6423                 : 
    6424                 : public:
    6425                 : 
    6426                 :   static nsresult
    6427               0 :   PostCloseEvent(nsGlobalWindow* aWindow) {
    6428               0 :     nsCOMPtr<nsIRunnable> ev = new nsCloseEvent(aWindow);
    6429               0 :     nsresult rv = NS_DispatchToCurrentThread(ev);
    6430               0 :     if (NS_SUCCEEDED(rv))
    6431               0 :       aWindow->MaybeForgiveSpamCount();
    6432               0 :     return rv;
    6433                 :   }
    6434                 : 
    6435               0 :   NS_IMETHOD Run() {
    6436               0 :     if (mWindow)
    6437               0 :       mWindow->ReallyCloseWindow();
    6438               0 :     return NS_OK;
    6439                 :   }
    6440                 : 
    6441                 : };
    6442                 : 
    6443                 : bool
    6444               0 : nsGlobalWindow::CanClose()
    6445                 : {
    6446               0 :   if (!mDocShell)
    6447               0 :     return true;
    6448                 : 
    6449                 :   // Ask the content viewer whether the toplevel window can close.
    6450                 :   // If the content viewer returns false, it is responsible for calling
    6451                 :   // Close() as soon as it is possible for the window to close.
    6452                 :   // This allows us to not close the window while printing is happening.
    6453                 : 
    6454               0 :   nsCOMPtr<nsIContentViewer> cv;
    6455               0 :   mDocShell->GetContentViewer(getter_AddRefs(cv));
    6456               0 :   if (cv) {
    6457                 :     bool canClose;
    6458               0 :     nsresult rv = cv->PermitUnload(false, &canClose);
    6459               0 :     if (NS_SUCCEEDED(rv) && !canClose)
    6460               0 :       return false;
    6461                 : 
    6462               0 :     rv = cv->RequestWindowClose(&canClose);
    6463               0 :     if (NS_SUCCEEDED(rv) && !canClose)
    6464               0 :       return false;
    6465                 :   }
    6466                 : 
    6467               0 :   return true;
    6468                 : }
    6469                 : 
    6470                 : NS_IMETHODIMP
    6471               0 : nsGlobalWindow::Close()
    6472                 : {
    6473               0 :   FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
    6474                 : 
    6475               0 :   if (IsFrame() || !mDocShell || IsInModalState()) {
    6476                 :     // window.close() is called on a frame in a frameset, on a window
    6477                 :     // that's already closed, or on a window for which there's
    6478                 :     // currently a modal dialog open. Ignore such calls.
    6479                 : 
    6480               0 :     return NS_OK;
    6481                 :   }
    6482                 : 
    6483               0 :   if (mHavePendingClose) {
    6484                 :     // We're going to be closed anyway; do nothing since we don't want
    6485                 :     // to double-close
    6486               0 :     return NS_OK;
    6487                 :   }
    6488                 : 
    6489               0 :   if (mBlockScriptedClosingFlag)
    6490                 :   {
    6491                 :     // A script's popup has been blocked and we don't want
    6492                 :     // the window to be closed directly after this event,
    6493                 :     // so the user can see that there was a blocked popup.
    6494               0 :     return NS_OK;
    6495                 :   }
    6496                 : 
    6497                 :   // Don't allow scripts from content to close windows
    6498                 :   // that were not opened by script
    6499               0 :   if (!mHadOriginalOpener && !nsContentUtils::IsCallerTrustedForWrite()) {
    6500                 :     bool allowClose =
    6501               0 :       Preferences::GetBool("dom.allow_scripts_to_close_windows", true);
    6502               0 :     if (!allowClose) {
    6503                 :       // We're blocking the close operation
    6504                 :       // report localized error msg in JS console
    6505                 :       nsContentUtils::ReportToConsole(
    6506                 :           nsIScriptError::warningFlag,
    6507                 :           "DOM Window", mDoc,  // Better name for the category?
    6508                 :           nsContentUtils::eDOM_PROPERTIES,
    6509               0 :           "WindowCloseBlockedWarning");
    6510                 : 
    6511               0 :       return NS_OK;
    6512                 :     }
    6513                 :   }
    6514                 : 
    6515               0 :   if (!mInClose && !mIsClosed && !CanClose())
    6516               0 :     return NS_OK;
    6517                 : 
    6518                 :   // Fire a DOM event notifying listeners that this window is about to
    6519                 :   // be closed. The tab UI code may choose to cancel the default
    6520                 :   // action for this event, if so, we won't actually close the window
    6521                 :   // (since the tab UI code will close the tab in stead). Sure, this
    6522                 :   // could be abused by content code, but do we care? I don't think
    6523                 :   // so...
    6524                 : 
    6525               0 :   bool wasInClose = mInClose;
    6526               0 :   mInClose = true;
    6527                 : 
    6528               0 :   if (!DispatchCustomEvent("DOMWindowClose")) {
    6529                 :     // Someone chose to prevent the default action for this event, if
    6530                 :     // so, let's not close this window after all...
    6531                 : 
    6532               0 :     mInClose = wasInClose;
    6533               0 :     return NS_OK;
    6534                 :   }
    6535                 : 
    6536               0 :   return FinalClose();
    6537                 : }
    6538                 : 
    6539                 : nsresult
    6540               0 : nsGlobalWindow::ForceClose()
    6541                 : {
    6542               0 :   if (IsFrame() || !mDocShell) {
    6543                 :     // This may be a frame in a frameset, or a window that's already closed.
    6544                 :     // Ignore such calls.
    6545                 : 
    6546               0 :     return NS_OK;
    6547                 :   }
    6548                 : 
    6549               0 :   if (mHavePendingClose) {
    6550                 :     // We're going to be closed anyway; do nothing since we don't want
    6551                 :     // to double-close
    6552               0 :     return NS_OK;
    6553                 :   }
    6554                 : 
    6555               0 :   mInClose = true;
    6556                 : 
    6557               0 :   DispatchCustomEvent("DOMWindowClose");
    6558                 : 
    6559               0 :   return FinalClose();
    6560                 : }
    6561                 : 
    6562                 : nsresult
    6563               0 : nsGlobalWindow::FinalClose()
    6564                 : {
    6565                 :   // Flag that we were closed.
    6566               0 :   mIsClosed = true;
    6567                 : 
    6568                 :   nsCOMPtr<nsIJSContextStack> stack =
    6569               0 :     do_GetService(sJSStackContractID);
    6570                 : 
    6571               0 :   JSContext *cx = nsnull;
    6572                 : 
    6573               0 :   if (stack) {
    6574               0 :     stack->Peek(&cx);
    6575                 :   }
    6576                 : 
    6577               0 :   if (cx) {
    6578               0 :     nsIScriptContext *currentCX = nsJSUtils::GetDynamicScriptContext(cx);
    6579                 : 
    6580               0 :     if (currentCX && currentCX == GetContextInternal()) {
    6581               0 :       currentCX->SetTerminationFunction(CloseWindow, this);
    6582               0 :       mHavePendingClose = true;
    6583               0 :       return NS_OK;
    6584                 :     }
    6585                 :   }
    6586                 : 
    6587                 :   // We may have plugins on the page that have issued this close from their
    6588                 :   // event loop and because we currently destroy the plugin window with
    6589                 :   // frames, we crash. So, if we are called from Javascript, post an event
    6590                 :   // to really close the window.
    6591               0 :   if (nsContentUtils::IsCallerChrome() ||
    6592               0 :       NS_FAILED(nsCloseEvent::PostCloseEvent(this))) {
    6593               0 :     ReallyCloseWindow();
    6594                 :   } else {
    6595               0 :     mHavePendingClose = true;
    6596                 :   }
    6597                 : 
    6598               0 :   return NS_OK;
    6599                 : }
    6600                 : 
    6601                 : 
    6602                 : void
    6603               0 : nsGlobalWindow::ReallyCloseWindow()
    6604                 : {
    6605               0 :   FORWARD_TO_OUTER_VOID(ReallyCloseWindow, ());
    6606                 : 
    6607                 :   // Make sure we never reenter this method.
    6608               0 :   mHavePendingClose = true;
    6609                 : 
    6610               0 :   nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
    6611               0 :   GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
    6612                 : 
    6613                 :   // If there's no treeOwnerAsWin, this window must already be closed.
    6614                 : 
    6615               0 :   if (treeOwnerAsWin) {
    6616                 : 
    6617                 :     // but if we're a browser window we could be in some nasty
    6618                 :     // self-destroying cascade that we should mostly ignore
    6619                 : 
    6620               0 :     nsCOMPtr<nsIDocShellTreeItem> docItem(do_QueryInterface(mDocShell));
    6621               0 :     if (docItem) {
    6622               0 :       nsCOMPtr<nsIBrowserDOMWindow> bwin;
    6623               0 :       nsCOMPtr<nsIDocShellTreeItem> rootItem;
    6624               0 :       docItem->GetRootTreeItem(getter_AddRefs(rootItem));
    6625               0 :       nsCOMPtr<nsIDOMWindow> rootWin(do_GetInterface(rootItem));
    6626               0 :       nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(rootWin));
    6627               0 :       if (chromeWin)
    6628               0 :         chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
    6629                 : 
    6630               0 :       if (rootWin) {
    6631                 :         /* Normally we destroy the entire window, but not if
    6632                 :            this DOM window belongs to a tabbed browser and doesn't
    6633                 :            correspond to a tab. This allows a well-behaved tab
    6634                 :            to destroy the container as it should but is a final measure
    6635                 :            to prevent an errant tab from doing so when it shouldn't.
    6636                 :            This works because we reach this code when we shouldn't only
    6637                 :            in the particular circumstance that we belong to a tab
    6638                 :            that has just been closed (and is therefore already missing
    6639                 :            from the list of browsers) (and has an unload handler
    6640                 :            that closes the window). */
    6641                 :         // XXXbz now that we have mHavePendingClose, is this needed?
    6642               0 :         bool isTab = false;
    6643               0 :         if (rootWin == this ||
    6644               0 :             !bwin || (bwin->IsTabContentWindow(GetOuterWindowInternal(),
    6645               0 :                                                &isTab), isTab))
    6646               0 :           treeOwnerAsWin->Destroy();
    6647                 :       }
    6648                 :     }
    6649                 : 
    6650               0 :     CleanUp(false);
    6651                 :   }
    6652                 : }
    6653                 : 
    6654                 : nsIDOMWindow *
    6655               0 : nsGlobalWindow::EnterModalState()
    6656                 : {
    6657               0 :   nsGlobalWindow* topWin = GetTop();
    6658                 : 
    6659               0 :   if (!topWin) {
    6660               0 :     NS_ERROR("Uh, EnterModalState() called w/o a reachable top window?");
    6661                 : 
    6662               0 :     return nsnull;
    6663                 :   }
    6664                 : 
    6665                 :   // If there is an active ESM in this window, clear it. Otherwise, this can
    6666                 :   // cause a problem if a modal state is entered during a mouseup event.
    6667                 :   nsEventStateManager* activeESM =
    6668               0 :     static_cast<nsEventStateManager*>(nsEventStateManager::GetActiveEventStateManager());
    6669               0 :   if (activeESM && activeESM->GetPresContext()) {
    6670               0 :     nsIPresShell* activeShell = activeESM->GetPresContext()->GetPresShell();
    6671               0 :     if (activeShell && (
    6672               0 :         nsContentUtils::ContentIsCrossDocDescendantOf(activeShell->GetDocument(), mDoc) ||
    6673               0 :         nsContentUtils::ContentIsCrossDocDescendantOf(mDoc, activeShell->GetDocument()))) {
    6674               0 :       nsEventStateManager::ClearGlobalActiveContent(activeESM);
    6675                 : 
    6676               0 :       activeShell->SetCapturingContent(nsnull, 0);
    6677                 : 
    6678               0 :       if (activeShell) {
    6679               0 :         nsRefPtr<nsFrameSelection> frameSelection = activeShell->FrameSelection();
    6680               0 :         frameSelection->SetMouseDownState(false);
    6681                 :       }
    6682                 :     }
    6683                 :   }
    6684                 : 
    6685               0 :   if (topWin->mModalStateDepth == 0) {
    6686               0 :     NS_ASSERTION(!mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
    6687                 : 
    6688               0 :     mSuspendedDoc = do_QueryInterface(topWin->GetExtantDocument());
    6689               0 :     if (mSuspendedDoc && mSuspendedDoc->EventHandlingSuppressed()) {
    6690               0 :       mSuspendedDoc->SuppressEventHandling();
    6691                 :     } else {
    6692               0 :       mSuspendedDoc = nsnull;
    6693                 :     }
    6694                 :   }
    6695               0 :   topWin->mModalStateDepth++;
    6696                 : 
    6697               0 :   JSContext *cx = nsContentUtils::GetCurrentJSContext();
    6698                 : 
    6699               0 :   nsCOMPtr<nsIDOMWindow> callerWin;
    6700                 :   nsIScriptContext *scx;
    6701               0 :   if (cx && (scx = GetScriptContextFromJSContext(cx))) {
    6702               0 :     scx->EnterModalState();
    6703               0 :     callerWin = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
    6704                 :   }
    6705                 : 
    6706               0 :   if (mContext) {
    6707               0 :     mContext->EnterModalState();
    6708                 :   }
    6709                 : 
    6710               0 :   return callerWin;
    6711                 : }
    6712                 : 
    6713                 : // static
    6714                 : void
    6715               0 : nsGlobalWindow::RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
    6716                 :                                             nsGlobalWindow *aWindow)
    6717                 : {
    6718                 :   nsGlobalWindow *inner;
    6719                 : 
    6720                 :   // Return early if we're frozen or have no inner window.
    6721               0 :   if (!(inner = aWindow->GetCurrentInnerWindowInternal()) ||
    6722               0 :       inner->IsFrozen()) {
    6723               0 :     return;
    6724                 :   }
    6725                 : 
    6726               0 :   inner->RunTimeout(nsnull);
    6727                 : 
    6728                 :   // Check again if we're frozen since running pending timeouts
    6729                 :   // could've frozen us.
    6730               0 :   if (inner->IsFrozen()) {
    6731               0 :     return;
    6732                 :   }
    6733                 : 
    6734               0 :   nsCOMPtr<nsIDOMWindowCollection> frames;
    6735               0 :   aWindow->GetFrames(getter_AddRefs(frames));
    6736                 : 
    6737               0 :   if (!frames) {
    6738                 :     return;
    6739                 :   }
    6740                 : 
    6741                 :   PRUint32 i, length;
    6742               0 :   if (NS_FAILED(frames->GetLength(&length)) || !length) {
    6743                 :     return;
    6744                 :   }
    6745                 : 
    6746               0 :   for (i = 0; i < length && aTopWindow->mModalStateDepth == 0; i++) {
    6747               0 :     nsCOMPtr<nsIDOMWindow> child;
    6748               0 :     frames->Item(i, getter_AddRefs(child));
    6749                 : 
    6750               0 :     if (!child) {
    6751                 :       return;
    6752                 :     }
    6753                 : 
    6754                 :     nsGlobalWindow *childWin =
    6755                 :       static_cast<nsGlobalWindow *>
    6756                 :                  (static_cast<nsIDOMWindow *>
    6757               0 :                              (child.get()));
    6758                 : 
    6759               0 :     RunPendingTimeoutsRecursive(aTopWindow, childWin);
    6760                 :   }
    6761                 : }
    6762                 : 
    6763                 : class nsPendingTimeoutRunner : public nsRunnable
    6764               0 : {
    6765                 : public:
    6766               0 :   nsPendingTimeoutRunner(nsGlobalWindow *aWindow)
    6767               0 :     : mWindow(aWindow)
    6768                 :   {
    6769               0 :     NS_ASSERTION(mWindow, "mWindow is null.");
    6770               0 :   }
    6771                 : 
    6772               0 :   NS_IMETHOD Run()
    6773                 :   {
    6774               0 :     nsGlobalWindow::RunPendingTimeoutsRecursive(mWindow, mWindow);
    6775                 : 
    6776               0 :     return NS_OK;
    6777                 :   }
    6778                 : 
    6779                 : private:
    6780                 :   nsRefPtr<nsGlobalWindow> mWindow;
    6781                 : };
    6782                 : 
    6783                 : void
    6784               0 : nsGlobalWindow::LeaveModalState(nsIDOMWindow *aCallerWin)
    6785                 : {
    6786               0 :   nsGlobalWindow *topWin = GetTop();
    6787                 : 
    6788               0 :   if (!topWin) {
    6789               0 :     NS_ERROR("Uh, LeaveModalState() called w/o a reachable top window?");
    6790               0 :     return;
    6791                 :   }
    6792                 : 
    6793               0 :   topWin->mModalStateDepth--;
    6794                 : 
    6795               0 :   if (topWin->mModalStateDepth == 0) {
    6796               0 :     nsCOMPtr<nsIRunnable> runner = new nsPendingTimeoutRunner(topWin);
    6797               0 :     if (NS_FAILED(NS_DispatchToCurrentThread(runner)))
    6798               0 :       NS_WARNING("failed to dispatch pending timeout runnable");
    6799                 : 
    6800               0 :     if (mSuspendedDoc) {
    6801                 :       nsCOMPtr<nsIDocument> currentDoc =
    6802               0 :         do_QueryInterface(topWin->GetExtantDocument());
    6803               0 :       mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(currentDoc == mSuspendedDoc);
    6804               0 :       mSuspendedDoc = nsnull;
    6805                 :     }
    6806                 :   }
    6807                 : 
    6808               0 :   if (aCallerWin) {
    6809               0 :     nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aCallerWin));
    6810               0 :     nsIScriptContext *scx = sgo->GetContext();
    6811               0 :     if (scx)
    6812               0 :       scx->LeaveModalState();
    6813                 :   }
    6814                 : 
    6815               0 :   if (mContext) {
    6816               0 :     mContext->LeaveModalState();
    6817                 :   }
    6818                 : 
    6819                 :   // Remember the time of the last dialog quit.
    6820               0 :   nsGlobalWindow *inner = topWin->GetCurrentInnerWindowInternal();
    6821               0 :   if (inner)
    6822               0 :     inner->mLastDialogQuitTime = TimeStamp::Now();
    6823                 : }
    6824                 : 
    6825                 : bool
    6826               0 : nsGlobalWindow::IsInModalState()
    6827                 : {
    6828               0 :   nsGlobalWindow *topWin = GetTop();
    6829                 : 
    6830               0 :   if (!topWin) {
    6831               0 :     NS_ERROR("Uh, IsInModalState() called w/o a reachable top window?");
    6832                 : 
    6833               0 :     return false;
    6834                 :   }
    6835                 : 
    6836               0 :   return topWin->mModalStateDepth != 0;
    6837                 : }
    6838                 : 
    6839                 : // static
    6840                 : void
    6841               0 : nsGlobalWindow::NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow) {
    6842                 :   nsCOMPtr<nsIObserverService> observerService =
    6843               0 :     services::GetObserverService();
    6844               0 :   if (observerService) {
    6845               0 :     observerService->
    6846               0 :       NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
    6847               0 :                       DOM_WINDOW_DESTROYED_TOPIC, nsnull);
    6848                 :   }
    6849               0 : }
    6850                 : 
    6851                 : class WindowDestroyedEvent : public nsRunnable
    6852               0 : {
    6853                 : public:
    6854               0 :   WindowDestroyedEvent(PRUint64 aID, const char* aTopic) :
    6855               0 :     mID(aID), mTopic(aTopic) {}
    6856                 : 
    6857               0 :   NS_IMETHOD Run()
    6858                 :   {
    6859                 :     nsCOMPtr<nsIObserverService> observerService =
    6860               0 :       do_GetService("@mozilla.org/observer-service;1");
    6861               0 :     if (observerService) {
    6862                 :       nsCOMPtr<nsISupportsPRUint64> wrapper =
    6863               0 :         do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
    6864               0 :       if (wrapper) {
    6865               0 :         wrapper->SetData(mID);
    6866               0 :         observerService->NotifyObservers(wrapper, mTopic.get(), nsnull);
    6867                 :       }
    6868                 :     }
    6869               0 :     return NS_OK;
    6870                 :   }
    6871                 : 
    6872                 : private:
    6873                 :   PRUint64 mID;
    6874                 :   nsCString mTopic;
    6875                 : };
    6876                 : 
    6877                 : void
    6878               0 : nsGlobalWindow::NotifyWindowIDDestroyed(const char* aTopic)
    6879                 : {
    6880               0 :   nsRefPtr<nsIRunnable> runnable = new WindowDestroyedEvent(mWindowID, aTopic);
    6881               0 :   nsresult rv = NS_DispatchToCurrentThread(runnable);
    6882               0 :   if (NS_SUCCEEDED(rv)) {
    6883               0 :     mNotifiedIDDestroyed = true;
    6884                 :   }
    6885               0 : }
    6886                 : 
    6887                 : // static
    6888                 : void
    6889               0 : nsGlobalWindow::NotifyDOMWindowFrozen(nsGlobalWindow* aWindow) {
    6890               0 :   if (aWindow && aWindow->IsInnerWindow()) {
    6891                 :     nsCOMPtr<nsIObserverService> observerService =
    6892               0 :       services::GetObserverService();
    6893               0 :     if (observerService) {
    6894               0 :       observerService->
    6895               0 :         NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
    6896               0 :                         DOM_WINDOW_FROZEN_TOPIC, nsnull);
    6897                 :     }
    6898                 :   }
    6899               0 : }
    6900                 : 
    6901                 : // static
    6902                 : void
    6903               0 : nsGlobalWindow::NotifyDOMWindowThawed(nsGlobalWindow* aWindow) {
    6904               0 :   if (aWindow && aWindow->IsInnerWindow()) {
    6905                 :     nsCOMPtr<nsIObserverService> observerService =
    6906               0 :       services::GetObserverService();
    6907               0 :     if (observerService) {
    6908               0 :       observerService->
    6909               0 :         NotifyObservers(static_cast<nsIScriptGlobalObject*>(aWindow),
    6910               0 :                         DOM_WINDOW_THAWED_TOPIC, nsnull);
    6911                 :     }
    6912                 :   }
    6913               0 : }
    6914                 : 
    6915                 : void
    6916               0 : nsGlobalWindow::InitJavaProperties()
    6917                 : {
    6918               0 :   nsIScriptContext *scx = GetContextInternal();
    6919                 : 
    6920               0 :   if (mDidInitJavaProperties || IsOuterWindow() || !scx || !mJSObject) {
    6921               0 :     return;
    6922                 :   }
    6923                 : 
    6924                 :   // Set mDidInitJavaProperties to true here even if initialization
    6925                 :   // can fail. If it fails, we won't try again...
    6926               0 :   mDidInitJavaProperties = true;
    6927                 : 
    6928               0 :   mDummyJavaPluginOwner = new nsDummyJavaPluginOwner(mDoc);
    6929               0 :   if (!mDummyJavaPluginOwner) {
    6930               0 :     return;
    6931                 :   }
    6932                 : 
    6933               0 :   nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
    6934               0 :   nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
    6935               0 :   if (!pluginHost) {
    6936                 :     return;
    6937                 :   }  
    6938               0 :   pluginHost->InstantiateDummyJavaPlugin(mDummyJavaPluginOwner);
    6939                 : 
    6940                 :   // It's possible for us (or the Java plugin, rather) to process
    6941                 :   // events during the above call, which can lead to this window being
    6942                 :   // torn down or what not, so re-check that the dummy plugin is still
    6943                 :   // around.
    6944               0 :   if (!mDummyJavaPluginOwner) {
    6945                 :     return;
    6946                 :   }
    6947                 : 
    6948               0 :   nsRefPtr<nsNPAPIPluginInstance> dummyPlugin;
    6949               0 :   mDummyJavaPluginOwner->GetInstance(getter_AddRefs(dummyPlugin));
    6950                 : 
    6951               0 :   if (dummyPlugin) {
    6952                 :     // A dummy plugin was instantiated. This means we have a Java
    6953                 :     // plugin that supports NPRuntime. For such a plugin, the plugin
    6954                 :     // instantiation code defines the Java properties for us, so we're
    6955                 :     // done here.
    6956                 : 
    6957                 :     return;
    6958                 :   }
    6959                 : 
    6960                 :   // No NPRuntime enabled Java plugin found, null out the owner we
    6961                 :   // would have used in that case as it's no longer needed.
    6962               0 :   mDummyJavaPluginOwner = nsnull;
    6963                 : }
    6964                 : 
    6965                 : JSObject*
    6966               0 : nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
    6967                 : {
    6968               0 :   JSObject* handler = nsnull;
    6969               0 :   if (mCachedXBLPrototypeHandlers.IsInitialized()) {
    6970               0 :     mCachedXBLPrototypeHandlers.Get(aKey, &handler);
    6971                 :   }
    6972               0 :   return handler;
    6973                 : }
    6974                 : 
    6975                 : void
    6976               0 : nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
    6977                 :                                          nsScriptObjectHolder<JSObject>& aHandler)
    6978                 : {
    6979               0 :   if (!mCachedXBLPrototypeHandlers.IsInitialized() &&
    6980               0 :       !mCachedXBLPrototypeHandlers.Init()) {
    6981               0 :     NS_ERROR("Failed to initiailize hashtable!");
    6982               0 :     return;
    6983                 :   }
    6984                 : 
    6985               0 :   if (!mCachedXBLPrototypeHandlers.Count()) {
    6986                 :     // Can't use macros to get the participant because nsGlobalChromeWindow also
    6987                 :     // runs through this code. Use QueryInterface to get the correct objects.
    6988                 :     nsXPCOMCycleCollectionParticipant* participant;
    6989               0 :     CallQueryInterface(this, &participant);
    6990               0 :     NS_ASSERTION(participant,
    6991                 :                  "Failed to QI to nsXPCOMCycleCollectionParticipant!");
    6992                 : 
    6993                 :     nsISupports* thisSupports;
    6994                 :     QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
    6995               0 :                    reinterpret_cast<void**>(&thisSupports));
    6996               0 :     NS_ASSERTION(thisSupports, "Failed to QI to nsCycleCollectionISupports!");
    6997                 : 
    6998               0 :     nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
    6999               0 :     if (NS_FAILED(rv)) {
    7000               0 :       NS_ERROR("nsContentUtils::HoldJSObjects failed!");
    7001               0 :       return;
    7002                 :     }
    7003                 :   }
    7004                 : 
    7005               0 :   mCachedXBLPrototypeHandlers.Put(aKey, aHandler.get());
    7006                 : }
    7007                 : 
    7008                 : /**
    7009                 :  * GetScriptableFrameElement is called when script reads
    7010                 :  * nsIGlobalWindow::frameElement.
    7011                 :  *
    7012                 :  * In contrast to GetRealFrameElement, GetScriptableFrameElement says that the
    7013                 :  * window contained by an <iframe mozbrowser> has no frame element
    7014                 :  * (effectively treating a mozbrowser the same as a content/chrome boundary).
    7015                 :  */
    7016                 : NS_IMETHODIMP
    7017               0 : nsGlobalWindow::GetScriptableFrameElement(nsIDOMElement** aFrameElement)
    7018                 : {
    7019               0 :   FORWARD_TO_OUTER(GetScriptableFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
    7020               0 :   *aFrameElement = NULL;
    7021                 : 
    7022               0 :   if (!mDocShell) {
    7023               0 :     return NS_OK;
    7024                 :   }
    7025                 : 
    7026               0 :   bool isMozBrowser = false;
    7027               0 :   mDocShell->GetIsBrowserFrame(&isMozBrowser);
    7028               0 :   if (isMozBrowser) {
    7029               0 :     return NS_OK;
    7030                 :   }
    7031                 : 
    7032               0 :   return GetFrameElement(aFrameElement);
    7033                 : }
    7034                 : 
    7035                 : /**
    7036                 :  * nsIGlobalWindow::GetFrameElement (when called from C++) is just a wrapper
    7037                 :  * around GetRealFrameElement.
    7038                 :  */
    7039                 : NS_IMETHODIMP
    7040               0 : nsGlobalWindow::GetRealFrameElement(nsIDOMElement** aFrameElement)
    7041                 : {
    7042               0 :   FORWARD_TO_OUTER(GetRealFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
    7043                 : 
    7044               0 :   *aFrameElement = NULL;
    7045                 : 
    7046               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellTI(do_QueryInterface(mDocShell));
    7047                 : 
    7048               0 :   if (!docShellTI) {
    7049               0 :     return NS_OK;
    7050                 :   }
    7051                 : 
    7052               0 :   nsCOMPtr<nsIDocShellTreeItem> parent;
    7053               0 :   docShellTI->GetSameTypeParent(getter_AddRefs(parent));
    7054                 : 
    7055               0 :   if (!parent || parent == docShellTI) {
    7056                 :     // We're at a chrome boundary, don't expose the chrome iframe
    7057                 :     // element to content code.
    7058                 : 
    7059               0 :     return NS_OK;
    7060                 :   }
    7061                 : 
    7062               0 :   *aFrameElement = mFrameElement;
    7063               0 :   NS_IF_ADDREF(*aFrameElement);
    7064                 : 
    7065               0 :   return NS_OK;
    7066                 : }
    7067                 : 
    7068                 : // Helper for converting window.showModalDialog() options (list of ';'
    7069                 : // separated name (:|=) value pairs) to a format that's parsable by
    7070                 : // our normal window opening code.
    7071                 : 
    7072                 : void
    7073               0 : ConvertDialogOptions(const nsAString& aOptions, nsAString& aResult)
    7074                 : {
    7075               0 :   nsAString::const_iterator end;
    7076               0 :   aOptions.EndReading(end);
    7077                 : 
    7078               0 :   nsAString::const_iterator iter;
    7079               0 :   aOptions.BeginReading(iter);
    7080                 : 
    7081               0 :   while (iter != end) {
    7082                 :     // Skip whitespace.
    7083               0 :     while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
    7084               0 :       ++iter;
    7085                 :     }
    7086                 : 
    7087               0 :     nsAString::const_iterator name_start = iter;
    7088                 : 
    7089                 :     // Skip characters until we find whitespace, ';', ':', or '='
    7090               0 :     while (iter != end && !nsCRT::IsAsciiSpace(*iter) &&
    7091               0 :            *iter != ';' &&
    7092               0 :            *iter != ':' &&
    7093               0 :            *iter != '=') {
    7094               0 :       ++iter;
    7095                 :     }
    7096                 : 
    7097               0 :     nsAString::const_iterator name_end = iter;
    7098                 : 
    7099                 :     // Skip whitespace.
    7100               0 :     while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
    7101               0 :       ++iter;
    7102                 :     }
    7103                 : 
    7104               0 :     if (*iter == ';') {
    7105                 :       // No value found, skip the ';' and keep going.
    7106               0 :       ++iter;
    7107                 : 
    7108               0 :       continue;
    7109                 :     }
    7110                 : 
    7111               0 :     nsAString::const_iterator value_start = iter;
    7112               0 :     nsAString::const_iterator value_end = iter;
    7113                 : 
    7114               0 :     if (*iter == ':' || *iter == '=') {
    7115                 :       // We found name followed by ':' or '='. Look for a value.
    7116                 : 
    7117               0 :       iter++; // Skip the ':' or '='
    7118                 : 
    7119                 :       // Skip whitespace.
    7120               0 :       while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
    7121               0 :         ++iter;
    7122                 :       }
    7123                 : 
    7124               0 :       value_start = iter;
    7125                 : 
    7126                 :       // Skip until we find whitespace, or ';'.
    7127               0 :       while (iter != end && !nsCRT::IsAsciiSpace(*iter) &&
    7128               0 :              *iter != ';') {
    7129               0 :         ++iter;
    7130                 :       }
    7131                 : 
    7132               0 :       value_end = iter;
    7133                 : 
    7134                 :       // Skip whitespace.
    7135               0 :       while (nsCRT::IsAsciiSpace(*iter) && iter != end) {
    7136               0 :         ++iter;
    7137                 :       }
    7138                 :     }
    7139                 : 
    7140               0 :     const nsDependentSubstring& name = Substring(name_start, name_end);
    7141               0 :     const nsDependentSubstring& value = Substring(value_start, value_end);
    7142                 : 
    7143               0 :     if (name.LowerCaseEqualsLiteral("center")) {
    7144               0 :       if (value.LowerCaseEqualsLiteral("on")  ||
    7145               0 :           value.LowerCaseEqualsLiteral("yes") ||
    7146               0 :           value.LowerCaseEqualsLiteral("1")) {
    7147               0 :         aResult.AppendLiteral(",centerscreen=1");
    7148                 :       }
    7149               0 :     } else if (name.LowerCaseEqualsLiteral("dialogwidth")) {
    7150               0 :       if (!value.IsEmpty()) {
    7151               0 :         aResult.AppendLiteral(",width=");
    7152               0 :         aResult.Append(value);
    7153                 :       }
    7154               0 :     } else if (name.LowerCaseEqualsLiteral("dialogheight")) {
    7155               0 :       if (!value.IsEmpty()) {
    7156               0 :         aResult.AppendLiteral(",height=");
    7157               0 :         aResult.Append(value);
    7158                 :       }
    7159               0 :     } else if (name.LowerCaseEqualsLiteral("dialogtop")) {
    7160               0 :       if (!value.IsEmpty()) {
    7161               0 :         aResult.AppendLiteral(",top=");
    7162               0 :         aResult.Append(value);
    7163                 :       }
    7164               0 :     } else if (name.LowerCaseEqualsLiteral("dialogleft")) {
    7165               0 :       if (!value.IsEmpty()) {
    7166               0 :         aResult.AppendLiteral(",left=");
    7167               0 :         aResult.Append(value);
    7168                 :       }
    7169               0 :     } else if (name.LowerCaseEqualsLiteral("resizable")) {
    7170               0 :       if (value.LowerCaseEqualsLiteral("on")  ||
    7171               0 :           value.LowerCaseEqualsLiteral("yes") ||
    7172               0 :           value.LowerCaseEqualsLiteral("1")) {
    7173               0 :         aResult.AppendLiteral(",resizable=1");
    7174                 :       }
    7175               0 :     } else if (name.LowerCaseEqualsLiteral("scroll")) {
    7176               0 :       if (value.LowerCaseEqualsLiteral("off")  ||
    7177               0 :           value.LowerCaseEqualsLiteral("no") ||
    7178               0 :           value.LowerCaseEqualsLiteral("0")) {
    7179               0 :         aResult.AppendLiteral(",scrollbars=0");
    7180                 :       }
    7181                 :     }
    7182                 : 
    7183               0 :     if (iter == end) {
    7184                 :       break;
    7185                 :     }
    7186                 : 
    7187               0 :     iter++;
    7188                 :   }
    7189               0 : }
    7190                 : 
    7191                 : NS_IMETHODIMP
    7192               0 : nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
    7193                 :                                 const nsAString& aOptions,
    7194                 :                                 nsIVariant **aRetVal)
    7195                 : {
    7196               0 :   FORWARD_TO_OUTER(ShowModalDialog, (aURI, aArgs, aOptions, aRetVal),
    7197                 :                    NS_ERROR_NOT_INITIALIZED);
    7198                 : 
    7199               0 :   *aRetVal = nsnull;
    7200                 : 
    7201                 :   // Before bringing up the window/dialog, unsuppress painting and flush
    7202                 :   // pending reflows.
    7203               0 :   EnsureReflowFlushAndPaint();
    7204                 : 
    7205               0 :   if (AreDialogsBlocked() || !ConfirmDialogAllowed())
    7206               0 :     return NS_ERROR_NOT_AVAILABLE;
    7207                 : 
    7208               0 :   nsCOMPtr<nsIDOMWindow> dlgWin;
    7209               0 :   nsAutoString options(NS_LITERAL_STRING("-moz-internal-modal=1,status=1"));
    7210                 : 
    7211               0 :   ConvertDialogOptions(aOptions, options);
    7212                 : 
    7213               0 :   options.AppendLiteral(",scrollbars=1,centerscreen=1,resizable=0");
    7214                 : 
    7215               0 :   nsCOMPtr<nsIDOMWindow> callerWin = EnterModalState();
    7216               0 :   nsresult rv = OpenInternal(aURI, EmptyString(), options,
    7217                 :                              false,          // aDialog
    7218                 :                              true,           // aContentModal
    7219                 :                              true,           // aCalledNoScript
    7220                 :                              true,           // aDoJSFixups
    7221                 :                              nsnull, aArgs,     // args
    7222               0 :                              GetPrincipal(),    // aCalleePrincipal
    7223                 :                              nsnull,            // aJSCallerContext
    7224               0 :                              getter_AddRefs(dlgWin));
    7225               0 :   LeaveModalState(callerWin);
    7226                 : 
    7227               0 :   NS_ENSURE_SUCCESS(rv, rv);
    7228                 :   
    7229               0 :   if (dlgWin) {
    7230               0 :     nsCOMPtr<nsIPrincipal> subjectPrincipal;
    7231               0 :     rv = nsContentUtils::GetSecurityManager()->
    7232               0 :       GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
    7233               0 :     if (NS_FAILED(rv)) {
    7234               0 :       return rv;
    7235                 :     }
    7236                 : 
    7237               0 :     bool canAccess = true;
    7238                 : 
    7239               0 :     if (subjectPrincipal) {
    7240                 :       nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
    7241               0 :         do_QueryInterface(dlgWin);
    7242               0 :       nsCOMPtr<nsIPrincipal> dialogPrincipal;
    7243                 : 
    7244               0 :       if (objPrincipal) {
    7245               0 :         dialogPrincipal = objPrincipal->GetPrincipal();
    7246                 : 
    7247               0 :         rv = subjectPrincipal->Subsumes(dialogPrincipal, &canAccess);
    7248               0 :         NS_ENSURE_SUCCESS(rv, rv);
    7249                 :       } else {
    7250                 :         // Uh, not sure what kind of dialog this is. Prevent access to
    7251                 :         // be on the safe side...
    7252                 : 
    7253               0 :         canAccess = false;
    7254                 :       }
    7255                 :     }
    7256                 : 
    7257               0 :     nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(dlgWin));
    7258                 : 
    7259               0 :     if (canAccess) {
    7260               0 :       nsPIDOMWindow *inner = win->GetCurrentInnerWindow();
    7261                 : 
    7262               0 :       nsCOMPtr<nsIDOMModalContentWindow> dlgInner(do_QueryInterface(inner));
    7263                 : 
    7264               0 :       if (dlgInner) {
    7265               0 :         dlgInner->GetReturnValue(aRetVal);
    7266                 :       }
    7267                 :     }
    7268                 : 
    7269                 :     nsRefPtr<nsGlobalWindow> winInternal =
    7270               0 :       static_cast<nsGlobalWindow*>(win.get());
    7271               0 :     if (winInternal->mCallCleanUpAfterModalDialogCloses) {
    7272               0 :       winInternal->mCallCleanUpAfterModalDialogCloses = false;
    7273               0 :       winInternal->CleanUp(true);
    7274                 :     }
    7275                 :   }
    7276                 :   
    7277               0 :   return NS_OK;
    7278                 : }
    7279                 : 
    7280                 : class CommandDispatcher : public nsRunnable
    7281               0 : {
    7282                 : public:
    7283               0 :   CommandDispatcher(nsIDOMXULCommandDispatcher* aDispatcher,
    7284                 :                     const nsAString& aAction)
    7285               0 :   : mDispatcher(aDispatcher), mAction(aAction) {}
    7286                 : 
    7287               0 :   NS_IMETHOD Run()
    7288                 :   {
    7289               0 :     return mDispatcher->UpdateCommands(mAction);
    7290                 :   }
    7291                 : 
    7292                 :   nsCOMPtr<nsIDOMXULCommandDispatcher> mDispatcher;
    7293                 :   nsString                             mAction;
    7294                 : };
    7295                 : 
    7296                 : NS_IMETHODIMP
    7297               0 : nsGlobalWindow::UpdateCommands(const nsAString& anAction)
    7298                 : {
    7299               0 :   nsPIDOMWindow *rootWindow = nsGlobalWindow::GetPrivateRoot();
    7300               0 :   if (!rootWindow)
    7301               0 :     return NS_OK;
    7302                 : 
    7303                 :   nsCOMPtr<nsIDOMXULDocument> xulDoc =
    7304               0 :     do_QueryInterface(rootWindow->GetExtantDocument());
    7305                 :   // See if we contain a XUL document.
    7306               0 :   if (xulDoc) {
    7307                 :     // Retrieve the command dispatcher and call updateCommands on it.
    7308               0 :     nsCOMPtr<nsIDOMXULCommandDispatcher> xulCommandDispatcher;
    7309               0 :     xulDoc->GetCommandDispatcher(getter_AddRefs(xulCommandDispatcher));
    7310               0 :     if (xulCommandDispatcher) {
    7311                 :       nsContentUtils::AddScriptRunner(new CommandDispatcher(xulCommandDispatcher,
    7312               0 :                                                             anAction));
    7313                 :     }
    7314                 :   }
    7315                 : 
    7316               0 :   return NS_OK;
    7317                 : }
    7318                 : 
    7319                 : NS_IMETHODIMP
    7320               0 : nsGlobalWindow::GetSelection(nsISelection** aSelection)
    7321                 : {
    7322               0 :   FORWARD_TO_OUTER(GetSelection, (aSelection), NS_ERROR_NOT_INITIALIZED);
    7323                 : 
    7324               0 :   NS_ENSURE_ARG_POINTER(aSelection);
    7325               0 :   *aSelection = nsnull;
    7326                 : 
    7327               0 :   if (!mDocShell)
    7328               0 :     return NS_OK;
    7329                 : 
    7330               0 :   nsCOMPtr<nsIPresShell> presShell;
    7331               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    7332                 : 
    7333               0 :   if (!presShell)
    7334               0 :     return NS_OK;
    7335                 :     
    7336               0 :   *aSelection = presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    7337                 :   
    7338               0 :   NS_IF_ADDREF(*aSelection);
    7339                 : 
    7340               0 :   return NS_OK;
    7341                 : }
    7342                 : 
    7343                 : NS_IMETHODIMP
    7344               0 : nsGlobalWindow::Find(const nsAString& aStr, bool aCaseSensitive,
    7345                 :                      bool aBackwards, bool aWrapAround, bool aWholeWord,
    7346                 :                      bool aSearchInFrames, bool aShowDialog,
    7347                 :                      bool *aDidFind)
    7348                 : {
    7349               0 :   FORWARD_TO_OUTER(Find, (aStr, aCaseSensitive, aBackwards, aWrapAround,
    7350                 :                           aWholeWord, aSearchInFrames, aShowDialog, aDidFind),
    7351                 :                    NS_ERROR_NOT_INITIALIZED);
    7352                 : 
    7353               0 :   nsresult rv = NS_OK;
    7354               0 :   *aDidFind = false;
    7355                 : 
    7356               0 :   nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mDocShell));
    7357               0 :   NS_ENSURE_TRUE(finder, NS_ERROR_FAILURE);
    7358                 : 
    7359                 :   // Set the options of the search
    7360               0 :   rv = finder->SetSearchString(PromiseFlatString(aStr).get());
    7361               0 :   NS_ENSURE_SUCCESS(rv, rv);
    7362               0 :   finder->SetMatchCase(aCaseSensitive);
    7363               0 :   finder->SetFindBackwards(aBackwards);
    7364               0 :   finder->SetWrapFind(aWrapAround);
    7365               0 :   finder->SetEntireWord(aWholeWord);
    7366               0 :   finder->SetSearchFrames(aSearchInFrames);
    7367                 : 
    7368                 :   // the nsIWebBrowserFind is initialized to use this window
    7369                 :   // as the search root, but uses focus to set the current search
    7370                 :   // frame. If we're being called from JS (as here), this window
    7371                 :   // should be the current search frame.
    7372               0 :   nsCOMPtr<nsIWebBrowserFindInFrames> framesFinder(do_QueryInterface(finder));
    7373               0 :   if (framesFinder) {
    7374               0 :     framesFinder->SetRootSearchFrame(this);   // paranoia
    7375               0 :     framesFinder->SetCurrentSearchFrame(this);
    7376                 :   }
    7377                 :   
    7378                 :   // The Find API does not accept empty strings. Launch the Find Dialog.
    7379               0 :   if (aStr.IsEmpty() || aShowDialog) {
    7380                 :     // See if the find dialog is already up using nsIWindowMediator
    7381                 :     nsCOMPtr<nsIWindowMediator> windowMediator =
    7382               0 :       do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
    7383                 : 
    7384               0 :     nsCOMPtr<nsIDOMWindow> findDialog;
    7385                 : 
    7386               0 :     if (windowMediator) {
    7387               0 :       windowMediator->GetMostRecentWindow(NS_LITERAL_STRING("findInPage").get(),
    7388               0 :                                           getter_AddRefs(findDialog));
    7389                 :     }
    7390                 : 
    7391               0 :     if (findDialog) {
    7392                 :       // The Find dialog is already open, bring it to the top.
    7393               0 :       rv = findDialog->Focus();
    7394                 :     } else { // Open a Find dialog
    7395               0 :       if (finder) {
    7396               0 :         nsCOMPtr<nsIDOMWindow> dialog;
    7397               0 :         rv = OpenDialog(NS_LITERAL_STRING("chrome://global/content/finddialog.xul"),
    7398               0 :                         NS_LITERAL_STRING("_blank"),
    7399               0 :                         NS_LITERAL_STRING("chrome, resizable=no, dependent=yes"),
    7400               0 :                         finder, getter_AddRefs(dialog));
    7401                 :       }
    7402                 :     }
    7403                 :   } else {
    7404                 :     // Launch the search with the passed in search string
    7405               0 :     rv = finder->FindNext(aDidFind);
    7406               0 :     NS_ENSURE_SUCCESS(rv, rv);
    7407                 :   }
    7408                 : 
    7409               0 :   return rv;
    7410                 : }
    7411                 : 
    7412                 : NS_IMETHODIMP
    7413               0 : nsGlobalWindow::Atob(const nsAString& aAsciiBase64String,
    7414                 :                      nsAString& aBinaryData)
    7415                 : {
    7416               0 :   return nsContentUtils::Atob(aAsciiBase64String, aBinaryData);
    7417                 : }
    7418                 : 
    7419                 : NS_IMETHODIMP
    7420               0 : nsGlobalWindow::Btoa(const nsAString& aBinaryData,
    7421                 :                      nsAString& aAsciiBase64String)
    7422                 : {
    7423               0 :   return nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
    7424                 : }
    7425                 : 
    7426                 : //*****************************************************************************
    7427                 : // nsGlobalWindow::nsIDOMEventTarget
    7428                 : //*****************************************************************************
    7429                 : 
    7430                 : NS_IMETHODIMP
    7431               0 : nsGlobalWindow::RemoveEventListener(const nsAString& aType,
    7432                 :                                     nsIDOMEventListener* aListener,
    7433                 :                                     bool aUseCapture)
    7434                 : {
    7435               0 :   nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
    7436               0 :   if (elm) {
    7437               0 :     elm->RemoveEventListener(aType, aListener, aUseCapture);
    7438                 :   }
    7439               0 :   return NS_OK;
    7440                 : }
    7441                 : 
    7442               0 : NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsGlobalWindow)
    7443                 : 
    7444                 : NS_IMETHODIMP
    7445               0 : nsGlobalWindow::DispatchEvent(nsIDOMEvent* aEvent, bool* aRetVal)
    7446                 : {
    7447               0 :   FORWARD_TO_INNER(DispatchEvent, (aEvent, aRetVal), NS_OK);
    7448                 : 
    7449               0 :   if (!mDoc) {
    7450               0 :     return NS_ERROR_FAILURE;
    7451                 :   }
    7452                 : 
    7453                 :   // Obtain a presentation shell
    7454               0 :   nsIPresShell *shell = mDoc->GetShell();
    7455               0 :   nsRefPtr<nsPresContext> presContext;
    7456               0 :   if (shell) {
    7457                 :     // Retrieve the context
    7458               0 :     presContext = shell->GetPresContext();
    7459                 :   }
    7460                 : 
    7461               0 :   nsEventStatus status = nsEventStatus_eIgnore;
    7462                 :   nsresult rv =
    7463               0 :     nsEventDispatcher::DispatchDOMEvent(GetOuterWindow(), nsnull, aEvent,
    7464               0 :                                         presContext, &status);
    7465                 : 
    7466               0 :   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
    7467               0 :   return rv;
    7468                 : }
    7469                 : 
    7470                 : NS_IMETHODIMP
    7471               0 : nsGlobalWindow::AddEventListener(const nsAString& aType,
    7472                 :                                  nsIDOMEventListener *aListener,
    7473                 :                                  bool aUseCapture, bool aWantsUntrusted,
    7474                 :                                  PRUint8 aOptionalArgc)
    7475                 : {
    7476               0 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
    7477                 :                "Won't check if this is chrome, you want to set "
    7478                 :                "aWantsUntrusted to false or make the aWantsUntrusted "
    7479                 :                "explicit by making optional_argc non-zero.");
    7480                 : 
    7481               0 :   if (IsOuterWindow() && mInnerWindow &&
    7482               0 :       !nsContentUtils::CanCallerAccess(mInnerWindow)) {
    7483               0 :     return NS_ERROR_DOM_SECURITY_ERR;
    7484                 :   }
    7485                 : 
    7486               0 :   if (!aWantsUntrusted &&
    7487               0 :       (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) {
    7488               0 :     aWantsUntrusted = true;
    7489                 :   }
    7490                 : 
    7491               0 :   nsEventListenerManager* manager = GetListenerManager(true);
    7492               0 :   NS_ENSURE_STATE(manager);
    7493               0 :   manager->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
    7494               0 :   return NS_OK;
    7495                 : }
    7496                 : 
    7497                 : NS_IMETHODIMP
    7498               0 : nsGlobalWindow::AddSystemEventListener(const nsAString& aType,
    7499                 :                                        nsIDOMEventListener *aListener,
    7500                 :                                        bool aUseCapture,
    7501                 :                                        bool aWantsUntrusted,
    7502                 :                                        PRUint8 aOptionalArgc)
    7503                 : {
    7504               0 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
    7505                 :                "Won't check if this is chrome, you want to set "
    7506                 :                "aWantsUntrusted to false or make the aWantsUntrusted "
    7507                 :                "explicit by making optional_argc non-zero.");
    7508                 : 
    7509               0 :   if (IsOuterWindow() && mInnerWindow &&
    7510               0 :       !nsContentUtils::CanCallerAccess(mInnerWindow)) {
    7511               0 :     return NS_ERROR_DOM_SECURITY_ERR;
    7512                 :   }
    7513                 : 
    7514               0 :   if (!aWantsUntrusted &&
    7515               0 :       (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) {
    7516               0 :     aWantsUntrusted = true;
    7517                 :   }
    7518                 : 
    7519                 :   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
    7520               0 :                                    aWantsUntrusted);
    7521                 : }
    7522                 : 
    7523                 : nsEventListenerManager*
    7524               0 : nsGlobalWindow::GetListenerManager(bool aCreateIfNotFound)
    7525                 : {
    7526               0 :   FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound), nsnull);
    7527                 : 
    7528               0 :   if (!mListenerManager && aCreateIfNotFound) {
    7529                 :     mListenerManager =
    7530               0 :       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
    7531                 :   }
    7532                 : 
    7533               0 :   return mListenerManager;
    7534                 : }
    7535                 : 
    7536                 : nsIScriptContext*
    7537               0 : nsGlobalWindow::GetContextForEventHandlers(nsresult* aRv)
    7538                 : {
    7539               0 :   *aRv = NS_ERROR_UNEXPECTED;
    7540               0 :   if (IsInnerWindow()) {
    7541               0 :     nsPIDOMWindow* outer = GetOuterWindow();
    7542               0 :     NS_ENSURE_TRUE(outer && outer->GetCurrentInnerWindow() == this, nsnull);
    7543                 :   }
    7544                 : 
    7545                 :   nsIScriptContext* scx;
    7546               0 :   if ((scx = GetContext())) {
    7547               0 :     *aRv = NS_OK;
    7548               0 :     return scx;
    7549                 :   }
    7550               0 :   return nsnull;
    7551                 : }
    7552                 : 
    7553                 : //*****************************************************************************
    7554                 : // nsGlobalWindow::nsPIDOMWindow
    7555                 : //*****************************************************************************
    7556                 : 
    7557                 : nsPIDOMWindow*
    7558               0 : nsGlobalWindow::GetPrivateParent()
    7559                 : {
    7560               0 :   FORWARD_TO_OUTER(GetPrivateParent, (), nsnull);
    7561                 : 
    7562               0 :   nsCOMPtr<nsIDOMWindow> parent;
    7563               0 :   GetParent(getter_AddRefs(parent));
    7564                 : 
    7565               0 :   if (static_cast<nsIDOMWindow *>(this) == parent.get()) {
    7566               0 :     nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
    7567               0 :     if (!chromeElement)
    7568               0 :       return nsnull;             // This is ok, just means a null parent.
    7569                 : 
    7570               0 :     nsIDocument* doc = chromeElement->GetDocument();
    7571               0 :     if (!doc)
    7572               0 :       return nsnull;             // This is ok, just means a null parent.
    7573                 : 
    7574               0 :     nsIScriptGlobalObject *globalObject = doc->GetScriptGlobalObject();
    7575               0 :     if (!globalObject)
    7576               0 :       return nsnull;             // This is ok, just means a null parent.
    7577                 : 
    7578               0 :     parent = do_QueryInterface(globalObject);
    7579                 :   }
    7580                 : 
    7581               0 :   if (parent) {
    7582                 :     return static_cast<nsGlobalWindow *>
    7583               0 :                       (static_cast<nsIDOMWindow*>(parent.get()));
    7584                 :   }
    7585                 : 
    7586               0 :   return nsnull;
    7587                 : }
    7588                 : 
    7589                 : nsPIDOMWindow*
    7590               0 : nsGlobalWindow::GetPrivateRoot()
    7591                 : {
    7592               0 :   FORWARD_TO_OUTER(GetPrivateRoot, (), nsnull);
    7593                 : 
    7594               0 :   nsCOMPtr<nsIDOMWindow> top;
    7595               0 :   GetTop(getter_AddRefs(top));
    7596                 : 
    7597               0 :   nsCOMPtr<nsPIDOMWindow> ptop = do_QueryInterface(top);
    7598               0 :   NS_ASSERTION(ptop, "cannot get ptop");
    7599               0 :   if (!ptop)
    7600               0 :     return nsnull;
    7601                 : 
    7602               0 :   nsIDocShell *docShell = ptop->GetDocShell();
    7603                 : 
    7604                 :   // Get the chrome event handler from the doc shell, since we only
    7605                 :   // want to deal with XUL chrome handlers and not the new kind of
    7606                 :   // window root handler.
    7607               0 :   nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
    7608               0 :   docShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler));
    7609                 : 
    7610               0 :   nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
    7611               0 :   if (chromeElement) {
    7612               0 :     nsIDocument* doc = chromeElement->GetDocument();
    7613               0 :     if (doc) {
    7614               0 :       nsIDOMWindow *parent = doc->GetWindow();
    7615               0 :       if (parent) {
    7616               0 :         parent->GetTop(getter_AddRefs(top));
    7617                 :       }
    7618                 :     }
    7619                 :   }
    7620                 : 
    7621                 :   return static_cast<nsGlobalWindow *>
    7622               0 :                     (static_cast<nsIDOMWindow *>(top));
    7623                 : }
    7624                 : 
    7625                 : 
    7626                 : NS_IMETHODIMP
    7627               0 : nsGlobalWindow::GetLocation(nsIDOMLocation ** aLocation)
    7628                 : {
    7629               0 :   FORWARD_TO_INNER(GetLocation, (aLocation), NS_ERROR_NOT_INITIALIZED);
    7630                 : 
    7631               0 :   *aLocation = nsnull;
    7632                 : 
    7633               0 :   nsIDocShell *docShell = GetDocShell();
    7634               0 :   if (!mLocation && docShell) {
    7635               0 :     mLocation = new nsLocation(docShell);
    7636               0 :     if (!mLocation) {
    7637               0 :       return NS_ERROR_OUT_OF_MEMORY;
    7638                 :     }
    7639                 :   }
    7640                 : 
    7641               0 :   NS_IF_ADDREF(*aLocation = mLocation);
    7642                 : 
    7643               0 :   return NS_OK;
    7644                 : }
    7645                 : 
    7646                 : void
    7647               0 : nsGlobalWindow::ActivateOrDeactivate(bool aActivate)
    7648                 : {
    7649                 :   // Set / unset mIsActive on the top level window, which is used for the
    7650                 :   // :-moz-window-inactive pseudoclass.
    7651               0 :   nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
    7652               0 :   if (!mainWidget)
    7653                 :     return;
    7654                 : 
    7655                 :   // Get the top level widget (if the main widget is a sheet, this will
    7656                 :   // be the sheet's top (non-sheet) parent).
    7657               0 :   nsCOMPtr<nsIWidget> topLevelWidget = mainWidget->GetSheetWindowParent();
    7658               0 :   if (!topLevelWidget) {
    7659               0 :     topLevelWidget = mainWidget;
    7660                 :   }
    7661                 : 
    7662                 :   // Get the top level widget's nsGlobalWindow
    7663               0 :   nsCOMPtr<nsIDOMWindow> topLevelWindow;
    7664               0 :   if (topLevelWidget == mainWidget) {
    7665               0 :     topLevelWindow = static_cast<nsIDOMWindow*>(this);
    7666                 :   } else {
    7667                 :     // This is a workaround for the following problem:
    7668                 :     // When a window with an open sheet loses focus, only the sheet window
    7669                 :     // receives the NS_DEACTIVATE event. However, it's not the sheet that
    7670                 :     // should lose the active styling, but the containing top level window.
    7671                 :     void* clientData;
    7672               0 :     topLevelWidget->GetClientData(clientData); // clientData is nsXULWindow
    7673               0 :     nsISupports* data = static_cast<nsISupports*>(clientData);
    7674               0 :     nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(data));
    7675               0 :     topLevelWindow = do_GetInterface(req);
    7676                 :   }
    7677               0 :   if (topLevelWindow) {
    7678               0 :     nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(topLevelWindow));
    7679               0 :     piWin->SetActive(aActivate);
    7680                 :   }
    7681                 : }
    7682                 : 
    7683                 : static bool
    7684               0 : NotifyDocumentTree(nsIDocument* aDocument, void* aData)
    7685                 : {
    7686               0 :   aDocument->EnumerateSubDocuments(NotifyDocumentTree, nsnull);
    7687               0 :   aDocument->DocumentStatesChanged(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
    7688               0 :   return true;
    7689                 : }
    7690                 : 
    7691                 : void
    7692               0 : nsGlobalWindow::SetActive(bool aActive)
    7693                 : {
    7694               0 :   nsPIDOMWindow::SetActive(aActive);
    7695               0 :   NotifyDocumentTree(mDoc, nsnull);
    7696               0 : }
    7697                 : 
    7698               0 : void nsGlobalWindow::SetIsBackground(bool aIsBackground)
    7699                 : {
    7700               0 :   bool resetTimers = (!aIsBackground && IsBackground());
    7701               0 :   nsPIDOMWindow::SetIsBackground(aIsBackground);
    7702               0 :   if (resetTimers) {
    7703               0 :     ResetTimersForNonBackgroundWindow();
    7704                 :   }
    7705               0 : }
    7706                 : 
    7707               0 : void nsGlobalWindow::MaybeUpdateTouchState()
    7708                 : {
    7709               0 :   FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
    7710                 : 
    7711               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    7712                 : 
    7713               0 :   nsCOMPtr<nsIDOMWindow> focusedWindow;
    7714               0 :   fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
    7715                 : 
    7716               0 :   if(this == focusedWindow) {
    7717               0 :     UpdateTouchState();
    7718                 :   }
    7719                 : 
    7720               0 :   if (mMayHaveTouchEventListener) {
    7721                 :     nsCOMPtr<nsIObserverService> observerService =
    7722               0 :       do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
    7723                 : 
    7724               0 :     if (observerService) {
    7725               0 :       observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
    7726                 :                                        DOM_TOUCH_LISTENER_ADDED,
    7727               0 :                                        nsnull);
    7728                 :     }
    7729                 :   }
    7730                 : }
    7731                 : 
    7732               0 : void nsGlobalWindow::UpdateTouchState()
    7733                 : {
    7734               0 :   FORWARD_TO_INNER_VOID(UpdateTouchState, ());
    7735                 : 
    7736               0 :   nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
    7737               0 :   if (!mainWidget) {
    7738                 :     return;
    7739                 :   }
    7740                 : 
    7741               0 :   if (mMayHaveTouchEventListener) {
    7742               0 :     mainWidget->RegisterTouchWindow();
    7743                 :   } else {
    7744               0 :     mainWidget->UnregisterTouchWindow();
    7745                 :   }
    7746                 : }
    7747                 : 
    7748                 : void
    7749               0 : nsGlobalWindow::EnableDeviceMotionUpdates()
    7750                 : {
    7751               0 :   if (mHasDeviceMotion) {
    7752                 :     nsCOMPtr<nsIDeviceMotion> ac =
    7753               0 :       do_GetService(NS_DEVICE_MOTION_CONTRACTID);
    7754               0 :     if (ac) {
    7755               0 :       ac->AddWindowListener(this);
    7756                 :     }
    7757                 :   }
    7758               0 : }
    7759                 : 
    7760                 : void
    7761               0 : nsGlobalWindow::DisableDeviceMotionUpdates()
    7762                 : {
    7763               0 :   if (mHasDeviceMotion) {
    7764                 :     nsCOMPtr<nsIDeviceMotion> ac =
    7765               0 :       do_GetService(NS_DEVICE_MOTION_CONTRACTID);
    7766               0 :     if (ac) {
    7767               0 :       ac->RemoveWindowListener(this);
    7768                 :     }
    7769                 :   }
    7770               0 : }
    7771                 : 
    7772                 : void
    7773               0 : nsGlobalWindow::SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler)
    7774                 : {
    7775               0 :   SetChromeEventHandlerInternal(aChromeEventHandler);
    7776               0 :   if (IsOuterWindow()) {
    7777                 :     // update the chrome event handler on all our inner windows
    7778               0 :     for (nsGlobalWindow *inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
    7779                 :          inner != this;
    7780               0 :          inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
    7781               0 :       NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == this,
    7782                 :                    "bad outer window pointer");
    7783               0 :       inner->SetChromeEventHandlerInternal(aChromeEventHandler);
    7784                 :     }
    7785               0 :   } else if (mOuterWindow) {
    7786                 :     // Need the cast to be able to call the protected method on a
    7787                 :     // superclass. We could make the method public instead, but it's really
    7788                 :     // better this way.
    7789               0 :     static_cast<nsGlobalWindow*>(mOuterWindow.get())->
    7790               0 :       SetChromeEventHandlerInternal(aChromeEventHandler);
    7791                 :   }
    7792               0 : }
    7793                 : 
    7794               0 : static bool IsLink(nsIContent* aContent)
    7795                 : {
    7796               0 :   nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aContent);
    7797                 :   return (anchor || (aContent &&
    7798                 :                      aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
    7799               0 :                                            nsGkAtoms::simple, eCaseMatters)));
    7800                 : }
    7801                 : 
    7802                 : void
    7803               0 : nsGlobalWindow::SetFocusedNode(nsIContent* aNode,
    7804                 :                                PRUint32 aFocusMethod,
    7805                 :                                bool aNeedsFocus)
    7806                 : {
    7807               0 :   FORWARD_TO_INNER_VOID(SetFocusedNode, (aNode, aFocusMethod, aNeedsFocus));
    7808                 : 
    7809               0 :   if (aNode && aNode->GetCurrentDoc() != mDoc) {
    7810               0 :     NS_WARNING("Trying to set focus to a node from a wrong document");
    7811               0 :     return;
    7812                 :   }
    7813                 : 
    7814               0 :   if (mCleanedUp) {
    7815               0 :     NS_ASSERTION(!aNode, "Trying to focus cleaned up window!");
    7816               0 :     aNode = nsnull;
    7817               0 :     aNeedsFocus = false;
    7818                 :   }
    7819               0 :   if (mFocusedNode != aNode) {
    7820               0 :     UpdateCanvasFocus(false, aNode);
    7821               0 :     mFocusedNode = aNode;
    7822               0 :     mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
    7823               0 :     mShowFocusRingForContent = false;
    7824                 :   }
    7825                 : 
    7826               0 :   if (mFocusedNode) {
    7827                 :     // if a node was focused by a keypress, turn on focus rings for the
    7828                 :     // window.
    7829               0 :     if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
    7830               0 :       mFocusByKeyOccurred = true;
    7831               0 :     } else if (
    7832                 :       // otherwise, we set mShowFocusRingForContent, as we don't want this to
    7833                 :       // be permanent for the window. On Windows, focus rings are only shown
    7834                 :       // when the FLAG_SHOWRING flag is used. On other platforms, focus rings
    7835                 :       // are only hidden for clicks on links.
    7836                 : #ifndef XP_WIN
    7837               0 :       !(mFocusMethod & nsIFocusManager::FLAG_BYMOUSE) || !IsLink(aNode) ||
    7838                 : #endif
    7839                 :       aFocusMethod & nsIFocusManager::FLAG_SHOWRING) {
    7840               0 :         mShowFocusRingForContent = true;
    7841                 :     }
    7842                 :   }
    7843                 : 
    7844               0 :   if (aNeedsFocus)
    7845               0 :     mNeedsFocus = aNeedsFocus;
    7846                 : }
    7847                 : 
    7848                 : PRUint32
    7849               0 : nsGlobalWindow::GetFocusMethod()
    7850                 : {
    7851               0 :   FORWARD_TO_INNER(GetFocusMethod, (), 0);
    7852                 : 
    7853               0 :   return mFocusMethod;
    7854                 : }
    7855                 : 
    7856                 : bool
    7857               0 : nsGlobalWindow::ShouldShowFocusRing()
    7858                 : {
    7859               0 :   FORWARD_TO_INNER(ShouldShowFocusRing, (), false);
    7860                 : 
    7861               0 :   return mShowFocusRings || mShowFocusRingForContent || mFocusByKeyOccurred;
    7862                 : }
    7863                 : 
    7864                 : void
    7865               0 : nsGlobalWindow::SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
    7866                 :                                       UIStateChangeType aShowFocusRings)
    7867                 : {
    7868               0 :   FORWARD_TO_INNER_VOID(SetKeyboardIndicators, (aShowAccelerators, aShowFocusRings));
    7869                 : 
    7870               0 :   bool oldShouldShowFocusRing = ShouldShowFocusRing();
    7871                 : 
    7872                 :   // only change the flags that have been modified
    7873               0 :   if (aShowAccelerators != UIStateChangeType_NoChange)
    7874               0 :     mShowAccelerators = aShowAccelerators == UIStateChangeType_Set;
    7875               0 :   if (aShowFocusRings != UIStateChangeType_NoChange)
    7876               0 :     mShowFocusRings = aShowFocusRings == UIStateChangeType_Set;
    7877                 : 
    7878                 :   // propagate the indicators to child windows
    7879               0 :   nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(GetDocShell());
    7880               0 :   if (node) {
    7881               0 :     PRInt32 childCount = 0;
    7882               0 :     node->GetChildCount(&childCount);
    7883                 : 
    7884               0 :     for (PRInt32 i = 0; i < childCount; ++i) {
    7885               0 :       nsCOMPtr<nsIDocShellTreeItem> childShell;
    7886               0 :       node->GetChildAt(i, getter_AddRefs(childShell));
    7887               0 :       nsCOMPtr<nsPIDOMWindow> childWindow = do_GetInterface(childShell);
    7888               0 :       if (childWindow) {
    7889               0 :         childWindow->SetKeyboardIndicators(aShowAccelerators, aShowFocusRings);
    7890                 :       }
    7891                 :     }
    7892                 :   }
    7893                 : 
    7894               0 :   bool newShouldShowFocusRing = ShouldShowFocusRing();
    7895               0 :   if (mHasFocus && mFocusedNode &&
    7896                 :       oldShouldShowFocusRing != newShouldShowFocusRing &&
    7897               0 :       mFocusedNode->IsElement()) {
    7898                 :     // Update mFocusedNode's state.
    7899               0 :     if (newShouldShowFocusRing) {
    7900               0 :       mFocusedNode->AsElement()->AddStates(NS_EVENT_STATE_FOCUSRING);
    7901                 :     } else {
    7902               0 :       mFocusedNode->AsElement()->RemoveStates(NS_EVENT_STATE_FOCUSRING);
    7903                 :     }
    7904                 :   }
    7905                 : }
    7906                 : 
    7907                 : void
    7908               0 : nsGlobalWindow::GetKeyboardIndicators(bool* aShowAccelerators,
    7909                 :                                       bool* aShowFocusRings)
    7910                 : {
    7911               0 :   FORWARD_TO_INNER_VOID(GetKeyboardIndicators, (aShowAccelerators, aShowFocusRings));
    7912                 : 
    7913               0 :   *aShowAccelerators = mShowAccelerators;
    7914               0 :   *aShowFocusRings = mShowFocusRings;
    7915                 : }
    7916                 : 
    7917                 : bool
    7918               0 : nsGlobalWindow::TakeFocus(bool aFocus, PRUint32 aFocusMethod)
    7919                 : {
    7920               0 :   FORWARD_TO_INNER(TakeFocus, (aFocus, aFocusMethod), false);
    7921                 : 
    7922               0 :   if (mCleanedUp) {
    7923               0 :     return false;
    7924                 :   }
    7925                 :   
    7926               0 :   if (aFocus)
    7927               0 :     mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
    7928                 : 
    7929               0 :   if (mHasFocus != aFocus) {
    7930               0 :     mHasFocus = aFocus;
    7931               0 :     UpdateCanvasFocus(true, mFocusedNode);
    7932                 :   }
    7933                 : 
    7934                 :   // if mNeedsFocus is true, then the document has not yet received a
    7935                 :   // document-level focus event. If there is a root content node, then return
    7936                 :   // true to tell the calling focus manager that a focus event is expected. If
    7937                 :   // there is no root content node, the document hasn't loaded enough yet, or
    7938                 :   // there isn't one and there is no point in firing a focus event.
    7939               0 :   if (aFocus && mNeedsFocus && mDoc && mDoc->GetRootElement() != nsnull) {
    7940               0 :     mNeedsFocus = false;
    7941               0 :     return true;
    7942                 :   }
    7943                 : 
    7944               0 :   mNeedsFocus = false;
    7945               0 :   return false;
    7946                 : }
    7947                 : 
    7948                 : void
    7949               0 : nsGlobalWindow::SetReadyForFocus()
    7950                 : {
    7951               0 :   FORWARD_TO_INNER_VOID(SetReadyForFocus, ());
    7952                 : 
    7953               0 :   bool oldNeedsFocus = mNeedsFocus;
    7954               0 :   mNeedsFocus = false;
    7955                 : 
    7956                 :   // update whether focus rings need to be shown using the state from the
    7957                 :   // root window
    7958               0 :   nsPIDOMWindow* root = GetPrivateRoot();
    7959               0 :   if (root) {
    7960                 :     bool showAccelerators, showFocusRings;
    7961               0 :     root->GetKeyboardIndicators(&showAccelerators, &showFocusRings);
    7962               0 :     mShowFocusRings = showFocusRings;
    7963                 :   }
    7964                 : 
    7965               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    7966               0 :   if (fm)
    7967               0 :     fm->WindowShown(this, oldNeedsFocus);
    7968                 : }
    7969                 : 
    7970                 : void
    7971               0 : nsGlobalWindow::PageHidden()
    7972                 : {
    7973               0 :   FORWARD_TO_INNER_VOID(PageHidden, ());
    7974                 : 
    7975                 :   // the window is being hidden, so tell the focus manager that the frame is
    7976                 :   // no longer valid. Use the persisted field to determine if the document
    7977                 :   // is being destroyed.
    7978                 : 
    7979               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    7980               0 :   if (fm)
    7981               0 :     fm->WindowHidden(this);
    7982                 : 
    7983               0 :   mNeedsFocus = true;
    7984                 : }
    7985                 : 
    7986                 : class HashchangeCallback : public nsRunnable
    7987               0 : {
    7988                 : public:
    7989               0 :   HashchangeCallback(const nsAString &aOldURL,
    7990                 :                      const nsAString &aNewURL,
    7991                 :                      nsGlobalWindow* aWindow)
    7992               0 :     : mWindow(aWindow)
    7993                 :   {
    7994               0 :     mOldURL.Assign(aOldURL);
    7995               0 :     mNewURL.Assign(aNewURL);
    7996               0 :   }
    7997                 : 
    7998               0 :   NS_IMETHOD Run()
    7999                 :   {
    8000               0 :     NS_PRECONDITION(NS_IsMainThread(), "Should be called on the main thread.");
    8001               0 :     return mWindow->FireHashchange(mOldURL, mNewURL);
    8002                 :   }
    8003                 : 
    8004                 : private:
    8005                 :   nsString mOldURL;
    8006                 :   nsString mNewURL;
    8007                 :   nsRefPtr<nsGlobalWindow> mWindow;
    8008                 : };
    8009                 : 
    8010                 : nsresult
    8011               0 : nsGlobalWindow::DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI)
    8012                 : {
    8013               0 :   FORWARD_TO_INNER(DispatchAsyncHashchange, (aOldURI, aNewURI), NS_OK);
    8014                 : 
    8015                 :   // Make sure that aOldURI and aNewURI are identical up to the '#', and that
    8016                 :   // their hashes are different.
    8017               0 :   nsCAutoString oldBeforeHash, oldHash, newBeforeHash, newHash;
    8018               0 :   nsContentUtils::SplitURIAtHash(aOldURI, oldBeforeHash, oldHash);
    8019               0 :   nsContentUtils::SplitURIAtHash(aNewURI, newBeforeHash, newHash);
    8020                 : 
    8021               0 :   NS_ENSURE_STATE(oldBeforeHash.Equals(newBeforeHash));
    8022               0 :   NS_ENSURE_STATE(!oldHash.Equals(newHash));
    8023                 : 
    8024               0 :   nsCAutoString oldSpec, newSpec;
    8025               0 :   aOldURI->GetSpec(oldSpec);
    8026               0 :   aNewURI->GetSpec(newSpec);
    8027                 : 
    8028               0 :   NS_ConvertUTF8toUTF16 oldWideSpec(oldSpec);
    8029               0 :   NS_ConvertUTF8toUTF16 newWideSpec(newSpec);
    8030                 : 
    8031                 :   nsCOMPtr<nsIRunnable> callback =
    8032               0 :     new HashchangeCallback(oldWideSpec, newWideSpec, this);
    8033               0 :   return NS_DispatchToMainThread(callback);
    8034                 : }
    8035                 : 
    8036                 : nsresult
    8037               0 : nsGlobalWindow::FireHashchange(const nsAString &aOldURL,
    8038                 :                                const nsAString &aNewURL)
    8039                 : {
    8040               0 :   NS_ENSURE_TRUE(IsInnerWindow(), NS_ERROR_FAILURE);
    8041                 : 
    8042                 :   // Don't do anything if the window is frozen.
    8043               0 :   if (IsFrozen())
    8044               0 :     return NS_OK;
    8045                 : 
    8046                 :   // Get a presentation shell for use in creating the hashchange event.
    8047               0 :   NS_ENSURE_STATE(mDoc);
    8048                 : 
    8049               0 :   nsIPresShell *shell = mDoc->GetShell();
    8050               0 :   nsRefPtr<nsPresContext> presContext;
    8051               0 :   if (shell) {
    8052               0 :     presContext = shell->GetPresContext();
    8053                 :   }
    8054                 : 
    8055                 :   // Create a new hashchange event.
    8056               0 :   nsCOMPtr<nsIDOMEvent> domEvent;
    8057                 :   nsresult rv =
    8058                 :     nsEventDispatcher::CreateEvent(presContext, nsnull,
    8059               0 :                                    NS_LITERAL_STRING("hashchangeevent"),
    8060               0 :                                    getter_AddRefs(domEvent));
    8061               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8062                 : 
    8063               0 :   nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
    8064               0 :   NS_ENSURE_TRUE(privateEvent, NS_ERROR_UNEXPECTED);
    8065                 : 
    8066               0 :   nsCOMPtr<nsIDOMHashChangeEvent> hashchangeEvent = do_QueryInterface(domEvent);
    8067               0 :   NS_ENSURE_TRUE(hashchangeEvent, NS_ERROR_UNEXPECTED);
    8068                 : 
    8069                 :   // The hashchange event bubbles and isn't cancellable.
    8070               0 :   rv = hashchangeEvent->InitHashChangeEvent(NS_LITERAL_STRING("hashchange"),
    8071                 :                                             true, false,
    8072               0 :                                             aOldURL, aNewURL);
    8073               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8074                 : 
    8075               0 :   rv = privateEvent->SetTrusted(true);
    8076               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8077                 : 
    8078                 :   bool dummy;
    8079               0 :   return DispatchEvent(hashchangeEvent, &dummy);
    8080                 : }
    8081                 : 
    8082                 : nsresult
    8083               0 : nsGlobalWindow::DispatchSyncPopState()
    8084                 : {
    8085               0 :   FORWARD_TO_INNER(DispatchSyncPopState, (), NS_OK);
    8086                 : 
    8087               0 :   NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
    8088                 :                "Must be safe to run script here.");
    8089                 : 
    8090                 :   // Check that PopState hasn't been pref'ed off.
    8091               0 :   if (!Preferences::GetBool(sPopStatePrefStr, false)) {
    8092               0 :     return NS_OK;
    8093                 :   }
    8094                 : 
    8095               0 :   nsresult rv = NS_OK;
    8096                 : 
    8097                 :   // Bail if the window is frozen.
    8098               0 :   if (IsFrozen()) {
    8099               0 :     return NS_OK;
    8100                 :   }
    8101                 : 
    8102                 :   // Get the document's pending state object -- it contains the data we're
    8103                 :   // going to send along with the popstate event.  The object is serialized
    8104                 :   // using structured clone.
    8105               0 :   nsCOMPtr<nsIVariant> stateObj;
    8106               0 :   rv = mDoc->GetStateObject(getter_AddRefs(stateObj));
    8107               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8108                 : 
    8109                 :   // Obtain a presentation shell for use in creating a popstate event.
    8110               0 :   nsIPresShell *shell = mDoc->GetShell();
    8111               0 :   nsRefPtr<nsPresContext> presContext;
    8112               0 :   if (shell) {
    8113               0 :     presContext = shell->GetPresContext();
    8114                 :   }
    8115                 : 
    8116                 :   // Create a new popstate event
    8117               0 :   nsCOMPtr<nsIDOMEvent> domEvent;
    8118                 :   rv = nsEventDispatcher::CreateEvent(presContext, nsnull,
    8119               0 :                                       NS_LITERAL_STRING("popstateevent"),
    8120               0 :                                       getter_AddRefs(domEvent));
    8121               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8122                 : 
    8123               0 :   nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
    8124               0 :   NS_ENSURE_TRUE(privateEvent, NS_ERROR_FAILURE);
    8125                 : 
    8126                 :   // Initialize the popstate event, which does bubble but isn't cancellable.
    8127               0 :   nsCOMPtr<nsIDOMPopStateEvent> popstateEvent = do_QueryInterface(domEvent);
    8128               0 :   rv = popstateEvent->InitPopStateEvent(NS_LITERAL_STRING("popstate"),
    8129                 :                                         true, false,
    8130               0 :                                         stateObj);
    8131               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8132                 : 
    8133               0 :   rv = privateEvent->SetTrusted(true);
    8134               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8135                 : 
    8136                 :   nsCOMPtr<nsIDOMEventTarget> outerWindow =
    8137               0 :     do_QueryInterface(GetOuterWindow());
    8138               0 :   NS_ENSURE_TRUE(outerWindow, NS_ERROR_UNEXPECTED);
    8139                 : 
    8140               0 :   rv = privateEvent->SetTarget(outerWindow);
    8141               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8142                 : 
    8143                 :   bool dummy; // default action
    8144               0 :   return DispatchEvent(popstateEvent, &dummy);
    8145                 : }
    8146                 : 
    8147                 : // Find an nsICanvasFrame under aFrame.  Only search the principal
    8148                 : // child lists.  aFrame must be non-null.
    8149               0 : static nsCanvasFrame* FindCanvasFrame(nsIFrame* aFrame)
    8150                 : {
    8151               0 :     nsCanvasFrame* canvasFrame = do_QueryFrame(aFrame);
    8152               0 :     if (canvasFrame) {
    8153               0 :         return canvasFrame;
    8154                 :     }
    8155                 : 
    8156               0 :     nsIFrame* kid = aFrame->GetFirstPrincipalChild();
    8157               0 :     while (kid) {
    8158               0 :         canvasFrame = FindCanvasFrame(kid);
    8159               0 :         if (canvasFrame) {
    8160               0 :             return canvasFrame;
    8161                 :         }
    8162               0 :         kid = kid->GetNextSibling();
    8163                 :     }
    8164                 : 
    8165               0 :     return nsnull;
    8166                 : }
    8167                 : 
    8168                 : //-------------------------------------------------------
    8169                 : // Tells the HTMLFrame/CanvasFrame that is now has focus
    8170                 : void
    8171               0 : nsGlobalWindow::UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent)
    8172                 : {
    8173                 :   // this is called from the inner window so use GetDocShell
    8174               0 :   nsIDocShell* docShell = GetDocShell();
    8175               0 :   if (!docShell)
    8176               0 :     return;
    8177                 : 
    8178               0 :   nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(docShell);
    8179               0 :   if (editorDocShell) {
    8180                 :     bool editable;
    8181               0 :     editorDocShell->GetEditable(&editable);
    8182               0 :     if (editable)
    8183                 :       return;
    8184                 :   }
    8185                 : 
    8186               0 :   nsCOMPtr<nsIPresShell> presShell;
    8187               0 :   docShell->GetPresShell(getter_AddRefs(presShell));
    8188               0 :   if (!presShell || !mDocument)
    8189                 :     return;
    8190                 : 
    8191               0 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
    8192               0 :   Element *rootElement = doc->GetRootElement();
    8193               0 :   if (rootElement) {
    8194               0 :       if ((mHasFocus || aFocusChanged) &&
    8195               0 :           (mFocusedNode == rootElement || aNewContent == rootElement)) {
    8196               0 :           nsIFrame* frame = rootElement->GetPrimaryFrame();
    8197               0 :           if (frame) {
    8198               0 :               frame = frame->GetParent();
    8199               0 :               nsCanvasFrame* canvasFrame = do_QueryFrame(frame);
    8200               0 :               if (canvasFrame) {
    8201               0 :                   canvasFrame->SetHasFocus(mHasFocus && rootElement == aNewContent);
    8202                 :               }
    8203                 :           }
    8204                 :       }
    8205                 :   } else {
    8206                 :       // Look for the frame the hard way
    8207               0 :       nsIFrame* frame = presShell->GetRootFrame();
    8208               0 :       if (frame) {
    8209               0 :           nsCanvasFrame* canvasFrame = FindCanvasFrame(frame);
    8210               0 :           if (canvasFrame) {
    8211               0 :               canvasFrame->SetHasFocus(false);
    8212                 :           }
    8213                 :       }      
    8214                 :   }
    8215                 : }
    8216                 : 
    8217                 : NS_IMETHODIMP
    8218               0 : nsGlobalWindow::GetComputedStyle(nsIDOMElement* aElt,
    8219                 :                                  const nsAString& aPseudoElt,
    8220                 :                                  nsIDOMCSSStyleDeclaration** aReturn)
    8221                 : {
    8222               0 :   FORWARD_TO_OUTER(GetComputedStyle, (aElt, aPseudoElt, aReturn),
    8223                 :                    NS_ERROR_NOT_INITIALIZED);
    8224                 : 
    8225               0 :   NS_ENSURE_ARG_POINTER(aReturn);
    8226               0 :   *aReturn = nsnull;
    8227                 : 
    8228               0 :   if (!aElt) {
    8229               0 :     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    8230                 :   }
    8231                 : 
    8232               0 :   if (!mDocShell) {
    8233               0 :     return NS_OK;
    8234                 :   }
    8235                 : 
    8236               0 :   nsCOMPtr<nsIPresShell> presShell;
    8237               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    8238                 : 
    8239               0 :   if (!presShell) {
    8240               0 :     return NS_OK;
    8241                 :   }
    8242                 : 
    8243               0 :   nsRefPtr<nsComputedDOMStyle> compStyle;
    8244                 :   nsresult rv = NS_NewComputedDOMStyle(aElt, aPseudoElt, presShell,
    8245               0 :                                        getter_AddRefs(compStyle));
    8246               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8247                 : 
    8248               0 :   *aReturn = compStyle.forget().get();
    8249                 : 
    8250               0 :   return NS_OK;
    8251                 : }
    8252                 : 
    8253                 : NS_IMETHODIMP
    8254               0 : nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
    8255                 : {
    8256               0 :   FORWARD_TO_INNER(GetSessionStorage, (aSessionStorage), NS_ERROR_UNEXPECTED);
    8257                 : 
    8258               0 :   nsIPrincipal *principal = GetPrincipal();
    8259               0 :   nsIDocShell* docShell = GetDocShell();
    8260                 : 
    8261               0 :   if (!principal || !docShell) {
    8262               0 :     *aSessionStorage = nsnull;
    8263               0 :     return NS_OK;
    8264                 :   }
    8265                 : 
    8266               0 :   if (!Preferences::GetBool(kStorageEnabled)) {
    8267               0 :     *aSessionStorage = nsnull;
    8268               0 :     return NS_OK;
    8269                 :   }
    8270                 : 
    8271               0 :   if (mSessionStorage) {
    8272                 : #ifdef PR_LOGGING
    8273               0 :     if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
    8274               0 :       PR_LogPrint("nsGlobalWindow %p has %p sessionStorage", this, mSessionStorage.get());
    8275                 :     }
    8276                 : #endif
    8277               0 :     nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(mSessionStorage);
    8278               0 :     if (piStorage) {
    8279               0 :       bool canAccess = piStorage->CanAccess(principal);
    8280               0 :       NS_ASSERTION(canAccess,
    8281                 :                    "window %x owned sessionStorage "
    8282                 :                    "that could not be accessed!");
    8283               0 :       if (!canAccess) {
    8284               0 :           mSessionStorage = nsnull;
    8285                 :       }
    8286                 :     }
    8287                 :   }
    8288                 : 
    8289               0 :   if (!mSessionStorage) {
    8290               0 :     *aSessionStorage = nsnull;
    8291                 : 
    8292               0 :     nsString documentURI;
    8293               0 :     if (mDocument) {
    8294               0 :       mDocument->GetDocumentURI(documentURI);
    8295                 :     }
    8296                 : 
    8297                 :     nsresult rv = docShell->GetSessionStorageForPrincipal(principal,
    8298                 :                                                           documentURI,
    8299                 :                                                           true,
    8300               0 :                                                           getter_AddRefs(mSessionStorage));
    8301               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8302                 : 
    8303                 : #ifdef PR_LOGGING
    8304               0 :     if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
    8305               0 :       PR_LogPrint("nsGlobalWindow %p tried to get a new sessionStorage %p", this, mSessionStorage.get());
    8306                 :     }
    8307                 : #endif
    8308                 : 
    8309               0 :     if (!mSessionStorage) {
    8310               0 :       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    8311                 :     }
    8312                 :   }
    8313                 : 
    8314                 : #ifdef PR_LOGGING
    8315               0 :     if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
    8316               0 :       PR_LogPrint("nsGlobalWindow %p returns %p sessionStorage", this, mSessionStorage.get());
    8317                 :     }
    8318                 : #endif
    8319                 : 
    8320               0 :   NS_ADDREF(*aSessionStorage = mSessionStorage);
    8321               0 :   return NS_OK;
    8322                 : }
    8323                 : 
    8324                 : NS_IMETHODIMP
    8325               0 : nsGlobalWindow::GetGlobalStorage(nsIDOMStorageList ** aGlobalStorage)
    8326                 : {
    8327               0 :   NS_ENSURE_ARG_POINTER(aGlobalStorage);
    8328                 : 
    8329               0 :   nsCOMPtr<nsIDocument> document = do_QueryInterface(GetExtantDocument());
    8330               0 :   if (document) {
    8331               0 :     document->WarnOnceAbout(nsIDocument::eGlobalStorage);
    8332                 :   }
    8333                 : 
    8334               0 :   if (!Preferences::GetBool(kStorageEnabled)) {
    8335               0 :     *aGlobalStorage = nsnull;
    8336               0 :     return NS_OK;
    8337                 :   }
    8338                 : 
    8339               0 :   if (!sGlobalStorageList) {
    8340               0 :     nsresult rv = NS_NewDOMStorageList(&sGlobalStorageList);
    8341               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8342                 :   }
    8343                 : 
    8344               0 :   *aGlobalStorage = sGlobalStorageList;
    8345               0 :   NS_IF_ADDREF(*aGlobalStorage);
    8346                 : 
    8347               0 :   return NS_OK;
    8348                 : }
    8349                 : 
    8350                 : NS_IMETHODIMP
    8351               0 : nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
    8352                 : {
    8353               0 :   FORWARD_TO_INNER(GetLocalStorage, (aLocalStorage), NS_ERROR_UNEXPECTED);
    8354                 : 
    8355               0 :   NS_ENSURE_ARG(aLocalStorage);
    8356                 : 
    8357               0 :   if (!Preferences::GetBool(kStorageEnabled)) {
    8358               0 :     *aLocalStorage = nsnull;
    8359               0 :     return NS_OK;
    8360                 :   }
    8361                 : 
    8362               0 :   if (!mLocalStorage) {
    8363               0 :     *aLocalStorage = nsnull;
    8364                 : 
    8365                 :     nsresult rv;
    8366                 : 
    8367                 :     bool unused;
    8368               0 :     if (!nsDOMStorage::CanUseStorage(&unused))
    8369               0 :       return NS_ERROR_DOM_SECURITY_ERR;
    8370                 : 
    8371               0 :     nsIPrincipal *principal = GetPrincipal();
    8372               0 :     if (!principal)
    8373               0 :       return NS_OK;
    8374                 : 
    8375                 :     nsCOMPtr<nsIDOMStorageManager> storageManager =
    8376               0 :       do_GetService("@mozilla.org/dom/storagemanager;1", &rv);
    8377               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8378                 : 
    8379               0 :     nsString documentURI;
    8380               0 :     if (mDocument) {
    8381               0 :       mDocument->GetDocumentURI(documentURI);
    8382                 :     }
    8383                 : 
    8384               0 :     rv = storageManager->GetLocalStorageForPrincipal(principal,
    8385                 :                                                      documentURI,
    8386               0 :                                                      getter_AddRefs(mLocalStorage));
    8387               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8388                 :   }
    8389                 : 
    8390               0 :   NS_ADDREF(*aLocalStorage = mLocalStorage);
    8391               0 :   return NS_OK;
    8392                 : }
    8393                 : 
    8394                 : //*****************************************************************************
    8395                 : // nsGlobalWindow::nsIDOMStorageIndexedDB
    8396                 : //*****************************************************************************
    8397                 : 
    8398                 : NS_IMETHODIMP
    8399               0 : nsGlobalWindow::GetMozIndexedDB(nsIIDBFactory** _retval)
    8400                 : {
    8401               0 :   if (!mIndexedDB) {
    8402               0 :     if (!IsChromeWindow()) {
    8403                 :       nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
    8404               0 :         do_GetService(THIRDPARTYUTIL_CONTRACTID);
    8405               0 :       NS_ENSURE_TRUE(thirdPartyUtil, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    8406                 : 
    8407                 :       bool isThirdParty;
    8408               0 :       nsresult rv = thirdPartyUtil->IsThirdPartyWindow(this, nsnull,
    8409               0 :                                                        &isThirdParty);
    8410               0 :       NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    8411                 : 
    8412               0 :       if (isThirdParty) {
    8413               0 :         NS_WARNING("IndexedDB is not permitted in a third-party window.");
    8414               0 :         *_retval = nsnull;
    8415               0 :         return NS_OK;
    8416                 :       }
    8417                 :     }
    8418                 : 
    8419               0 :     mIndexedDB = indexedDB::IDBFactory::Create(this);
    8420               0 :     NS_ENSURE_TRUE(mIndexedDB, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    8421                 :   }
    8422                 : 
    8423               0 :   nsCOMPtr<nsIIDBFactory> request(mIndexedDB);
    8424               0 :   request.forget(_retval);
    8425               0 :   return NS_OK;
    8426                 : }
    8427                 : 
    8428                 : //*****************************************************************************
    8429                 : // nsGlobalWindow::nsIInterfaceRequestor
    8430                 : //*****************************************************************************
    8431                 : 
    8432                 : NS_IMETHODIMP
    8433               0 : nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
    8434                 : {
    8435               0 :   NS_ENSURE_ARG_POINTER(aSink);
    8436               0 :   *aSink = nsnull;
    8437                 : 
    8438               0 :   if (aIID.Equals(NS_GET_IID(nsIDocCharset))) {
    8439               0 :     FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
    8440                 : 
    8441               0 :     if (mDocShell) {
    8442               0 :       nsCOMPtr<nsIDocCharset> docCharset(do_QueryInterface(mDocShell));
    8443               0 :       if (docCharset) {
    8444               0 :         NS_WARNING("Using deprecated nsIDocCharset: use nsIDocShell.GetCharset() instead ");
    8445               0 :         *aSink = docCharset;
    8446               0 :         NS_ADDREF(((nsISupports *) *aSink));
    8447                 :       }
    8448                 :     }
    8449                 :   }
    8450               0 :   else if (aIID.Equals(NS_GET_IID(nsIWebNavigation))) {
    8451               0 :     FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
    8452                 : 
    8453               0 :     if (mDocShell) {
    8454               0 :       nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
    8455               0 :       if (webNav) {
    8456               0 :         *aSink = webNav;
    8457               0 :         NS_ADDREF(((nsISupports *) *aSink));
    8458                 :       }
    8459                 :     }
    8460                 :   }
    8461                 : #ifdef NS_PRINTING
    8462               0 :   else if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
    8463               0 :     FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
    8464                 : 
    8465               0 :     if (mDocShell) {
    8466               0 :       nsCOMPtr<nsIContentViewer> viewer;
    8467               0 :       mDocShell->GetContentViewer(getter_AddRefs(viewer));
    8468               0 :       if (viewer) {
    8469               0 :         nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
    8470               0 :         if (webBrowserPrint) {
    8471               0 :           *aSink = webBrowserPrint;
    8472               0 :           NS_ADDREF(((nsISupports *) *aSink));
    8473                 :         }
    8474                 :       }
    8475                 :     }
    8476                 :   }
    8477                 : #endif
    8478               0 :   else if (aIID.Equals(NS_GET_IID(nsIDOMWindowUtils))) {
    8479               0 :     FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
    8480                 : 
    8481               0 :     nsCOMPtr<nsISupports> utils(do_QueryReferent(mWindowUtils));
    8482               0 :     if (utils) {
    8483               0 :       *aSink = utils;
    8484               0 :       NS_ADDREF(((nsISupports *) *aSink));
    8485                 :     } else {
    8486               0 :       nsDOMWindowUtils *utilObj = new nsDOMWindowUtils(this);
    8487                 :       nsCOMPtr<nsISupports> utilsIfc =
    8488               0 :                               NS_ISUPPORTS_CAST(nsIDOMWindowUtils *, utilObj);
    8489               0 :       if (utilsIfc) {
    8490               0 :         mWindowUtils = do_GetWeakReference(utilsIfc);
    8491               0 :         *aSink = utilsIfc;
    8492               0 :         NS_ADDREF(((nsISupports *) *aSink));
    8493                 :       }
    8494                 :     }
    8495                 :   }
    8496                 :   else {
    8497               0 :     return QueryInterface(aIID, aSink);
    8498                 :   }
    8499                 : 
    8500               0 :   return *aSink ? NS_OK : NS_ERROR_NO_INTERFACE;
    8501                 : }
    8502                 : 
    8503                 : void
    8504               0 : nsGlobalWindow::FireOfflineStatusEvent()
    8505                 : {
    8506               0 :   if (!mDoc)
    8507               0 :     return;
    8508               0 :   nsAutoString name;
    8509               0 :   if (NS_IsOffline()) {
    8510               0 :     name.AssignLiteral("offline");
    8511                 :   } else {
    8512               0 :     name.AssignLiteral("online");
    8513                 :   }
    8514                 :   // The event is fired at the body element, or if there is no body element,
    8515                 :   // at the document.
    8516               0 :   nsCOMPtr<nsISupports> eventTarget = mDoc.get();
    8517               0 :   nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDoc);
    8518               0 :   if (htmlDoc) {
    8519               0 :     nsCOMPtr<nsIDOMHTMLElement> body;
    8520               0 :     htmlDoc->GetBody(getter_AddRefs(body));
    8521               0 :     if (body) {
    8522               0 :       eventTarget = body;
    8523                 :     }
    8524                 :   }
    8525                 :   else {
    8526               0 :     nsCOMPtr<nsIDOMElement> documentElement;
    8527               0 :     mDocument->GetDocumentElement(getter_AddRefs(documentElement));
    8528               0 :     if(documentElement) {        
    8529               0 :       eventTarget = documentElement;
    8530                 :     }
    8531                 :   }
    8532               0 :   nsContentUtils::DispatchTrustedEvent(mDoc, eventTarget, name, true, false);
    8533                 : }
    8534                 : 
    8535                 : nsresult
    8536               0 : nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
    8537                 :                         const PRUnichar* aData)
    8538                 : {
    8539               0 :   if (!nsCRT::strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC)) {
    8540               0 :     if (IsFrozen()) {
    8541                 :       // if an even number of notifications arrive while we're frozen,
    8542                 :       // we don't need to fire.
    8543               0 :       mFireOfflineStatusChangeEventOnThaw = !mFireOfflineStatusChangeEventOnThaw;
    8544                 :     } else {
    8545               0 :       FireOfflineStatusEvent();
    8546                 :     }
    8547               0 :     return NS_OK;
    8548                 :   }
    8549                 : 
    8550               0 :   if (IsInnerWindow() && !nsCRT::strcmp(aTopic, "dom-storage-changed")) {
    8551                 :     nsIPrincipal *principal;
    8552                 :     nsresult rv;
    8553                 : 
    8554               0 :     principal = GetPrincipal();
    8555               0 :     if (principal) {
    8556                 :       // A global storage object changed, check to see if it's one
    8557                 :       // this window can access.
    8558                 : 
    8559               0 :       nsCOMPtr<nsIURI> codebase;
    8560               0 :       principal->GetURI(getter_AddRefs(codebase));
    8561                 : 
    8562               0 :       if (!codebase) {
    8563               0 :         return NS_OK;
    8564                 :       }
    8565                 : 
    8566               0 :       nsCAutoString currentDomain;
    8567               0 :       rv = codebase->GetAsciiHost(currentDomain);
    8568               0 :       if (NS_FAILED(rv)) {
    8569               0 :         return NS_OK;
    8570                 :       }
    8571                 : 
    8572               0 :       if (!nsDOMStorageList::CanAccessDomain(NS_ConvertUTF16toUTF8(aData),
    8573               0 :                                              currentDomain)) {
    8574                 :         // This window can't reach the global storage object for the
    8575                 :         // domain for which the change happened, so don't fire any
    8576                 :         // events in this window.
    8577                 : 
    8578               0 :         return NS_OK;
    8579                 :       }
    8580                 :     }
    8581                 : 
    8582               0 :     nsAutoString domain(aData);
    8583                 : 
    8584               0 :     if (IsFrozen()) {
    8585                 :       // This window is frozen, rather than firing the events here,
    8586                 :       // store the domain in which the change happened and fire the
    8587                 :       // events if we're ever thawed.
    8588                 : 
    8589               0 :       if (!mPendingStorageEventsObsolete) {
    8590               0 :         mPendingStorageEventsObsolete = new nsDataHashtable<nsStringHashKey, bool>;
    8591               0 :         NS_ENSURE_TRUE(mPendingStorageEventsObsolete, NS_ERROR_OUT_OF_MEMORY);
    8592                 : 
    8593               0 :         rv = mPendingStorageEventsObsolete->Init();
    8594               0 :         NS_ENSURE_SUCCESS(rv, rv);
    8595                 :       }
    8596                 : 
    8597               0 :       mPendingStorageEventsObsolete->Put(domain, true);
    8598                 : 
    8599               0 :       return NS_OK;
    8600                 :     }
    8601                 : 
    8602               0 :     nsRefPtr<nsDOMStorageEventObsolete> event = new nsDOMStorageEventObsolete();
    8603               0 :     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
    8604                 : 
    8605               0 :     rv = event->InitStorageEvent(NS_LITERAL_STRING("storage"), false, false, domain);
    8606               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8607                 : 
    8608               0 :     nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
    8609                 : 
    8610               0 :     nsCOMPtr<nsIDOMEventTarget> target;
    8611                 : 
    8612               0 :     if (htmlDoc) {
    8613               0 :       nsCOMPtr<nsIDOMHTMLElement> body;
    8614               0 :       htmlDoc->GetBody(getter_AddRefs(body));
    8615                 : 
    8616               0 :       target = do_QueryInterface(body);
    8617                 :     }
    8618                 : 
    8619               0 :     if (!target) {
    8620               0 :       target = this;
    8621                 :     }
    8622                 : 
    8623                 :     bool defaultActionEnabled;
    8624               0 :     target->DispatchEvent((nsIDOMStorageEventObsolete *)event, &defaultActionEnabled);
    8625                 : 
    8626               0 :     return NS_OK;
    8627                 :   }
    8628                 : 
    8629               0 :   if (IsInnerWindow() && !nsCRT::strcmp(aTopic, "dom-storage2-changed")) {
    8630                 :     nsIPrincipal *principal;
    8631                 :     nsresult rv;
    8632                 : 
    8633               0 :     nsCOMPtr<nsIDOMStorageEvent> event = do_QueryInterface(aSubject, &rv);
    8634               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8635                 : 
    8636               0 :     nsCOMPtr<nsIDOMStorage> changingStorage;
    8637               0 :     rv = event->GetStorageArea(getter_AddRefs(changingStorage));
    8638               0 :     NS_ENSURE_SUCCESS(rv, rv);
    8639                 : 
    8640               0 :     nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(changingStorage);
    8641               0 :     nsPIDOMStorage::nsDOMStorageType storageType = pistorage->StorageType();
    8642                 : 
    8643               0 :     principal = GetPrincipal();
    8644               0 :     switch (storageType)
    8645                 :     {
    8646                 :     case nsPIDOMStorage::SessionStorage:
    8647                 :     {
    8648               0 :       if (SameCOMIdentity(mSessionStorage, changingStorage)) {
    8649                 :         // Do not fire any events for the same storage object, it's not shared
    8650                 :         // among windows, see nsGlobalWindow::GetSessionStoarge()
    8651               0 :         return NS_OK;
    8652                 :       }
    8653                 : 
    8654               0 :       nsCOMPtr<nsIDOMStorage> storage = mSessionStorage;
    8655               0 :       if (!storage) {
    8656               0 :         nsIDocShell* docShell = GetDocShell();
    8657               0 :         if (principal && docShell) {
    8658                 :           // No need to pass documentURI here, it's only needed when we want
    8659                 :           // to create a new storage, the third paramater would be true
    8660                 :           docShell->GetSessionStorageForPrincipal(principal,
    8661               0 :                                                   EmptyString(),
    8662                 :                                                   false,
    8663               0 :                                                   getter_AddRefs(storage));
    8664                 :         }
    8665                 :       }
    8666                 : 
    8667               0 :       if (!pistorage->IsForkOf(storage)) {
    8668                 :         // This storage event is coming from a different doc shell,
    8669                 :         // i.e. it is a clone, ignore this event.
    8670               0 :         return NS_OK;
    8671                 :       }
    8672                 : 
    8673                 : #ifdef PR_LOGGING
    8674               0 :       if (PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) {
    8675               0 :         PR_LogPrint("nsGlobalWindow %p with sessionStorage %p passing event from %p", this, mSessionStorage.get(), pistorage.get());
    8676                 :       }
    8677                 : #endif
    8678                 : 
    8679               0 :       break;
    8680                 :     }
    8681                 :     case nsPIDOMStorage::LocalStorage:
    8682                 :     {
    8683               0 :       if (SameCOMIdentity(mLocalStorage, changingStorage)) {
    8684                 :         // Do not fire any events for the same storage object, it's not shared
    8685                 :         // among windows, see nsGlobalWindow::GetLocalStoarge()
    8686               0 :         return NS_OK;
    8687                 :       }
    8688                 : 
    8689                 :       // Allow event fire only for the same principal storages
    8690                 :       // XXX We have to use EqualsIgnoreDomain after bug 495337 lands
    8691               0 :       nsIPrincipal *storagePrincipal = pistorage->Principal();
    8692                 :       bool equals;
    8693                 : 
    8694               0 :       rv = storagePrincipal->Equals(principal, &equals);
    8695               0 :       NS_ENSURE_SUCCESS(rv, rv);
    8696                 : 
    8697               0 :       if (!equals)
    8698               0 :         return NS_OK;
    8699                 : 
    8700               0 :       break;
    8701                 :     }
    8702                 :     default:
    8703               0 :       return NS_OK;
    8704                 :     }
    8705                 : 
    8706               0 :     if (IsFrozen()) {
    8707                 :       // This window is frozen, rather than firing the events here,
    8708                 :       // store the domain in which the change happened and fire the
    8709                 :       // events if we're ever thawed.
    8710                 : 
    8711               0 :       mPendingStorageEvents.AppendObject(event);
    8712               0 :       return NS_OK;
    8713                 :     }
    8714                 : 
    8715                 :     bool defaultActionEnabled;
    8716               0 :     DispatchEvent((nsIDOMStorageEvent *)event, &defaultActionEnabled);
    8717                 : 
    8718               0 :     return NS_OK;
    8719                 :   }
    8720                 : 
    8721               0 :   if (!nsCRT::strcmp(aTopic, "offline-cache-update-added")) {
    8722               0 :     if (mApplicationCache)
    8723               0 :       return NS_OK;
    8724                 : 
    8725                 :     // Instantiate the application object now. It observes update belonging to
    8726                 :     // this window's document and correctly updates the applicationCache object
    8727                 :     // state.
    8728               0 :     nsCOMPtr<nsIDOMOfflineResourceList> applicationCache;
    8729               0 :     GetApplicationCache(getter_AddRefs(applicationCache));
    8730               0 :     nsCOMPtr<nsIObserver> observer = do_QueryInterface(applicationCache);
    8731               0 :     if (observer)
    8732               0 :       observer->Observe(aSubject, aTopic, aData);
    8733                 : 
    8734               0 :     return NS_OK;
    8735                 :   }
    8736                 : 
    8737               0 :   NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
    8738               0 :   return NS_ERROR_FAILURE;
    8739                 : }
    8740                 : 
    8741                 : static PLDHashOperator
    8742               0 : FirePendingStorageEvents(const nsAString& aKey, bool aData, void *userArg)
    8743                 : {
    8744               0 :   nsGlobalWindow *win = static_cast<nsGlobalWindow *>(userArg);
    8745                 : 
    8746               0 :   nsCOMPtr<nsIDOMStorage> storage;
    8747               0 :   win->GetSessionStorage(getter_AddRefs(storage));
    8748                 : 
    8749               0 :   if (storage) {
    8750                 :     win->Observe(storage, "dom-storage-changed",
    8751               0 :                  aKey.IsEmpty() ? nsnull : PromiseFlatString(aKey).get());
    8752                 :   }
    8753                 : 
    8754               0 :   return PL_DHASH_NEXT;
    8755                 : }
    8756                 : 
    8757                 : nsresult
    8758               0 : nsGlobalWindow::FireDelayedDOMEvents()
    8759                 : {
    8760               0 :   FORWARD_TO_INNER(FireDelayedDOMEvents, (), NS_ERROR_UNEXPECTED);
    8761                 : 
    8762               0 :   for (PRInt32 i = 0; i < mPendingStorageEvents.Count(); ++i) {
    8763               0 :     Observe(mPendingStorageEvents[i], "dom-storage2-changed", nsnull);
    8764                 :   }
    8765                 : 
    8766               0 :   if (mPendingStorageEventsObsolete) {
    8767                 :     // Fire pending storage events.
    8768               0 :     mPendingStorageEventsObsolete->EnumerateRead(FirePendingStorageEvents, this);
    8769               0 :     mPendingStorageEventsObsolete = nsnull;
    8770                 :   }
    8771                 : 
    8772               0 :   if (mApplicationCache) {
    8773               0 :     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->FirePendingEvents();
    8774                 :   }
    8775                 : 
    8776               0 :   if (mFireOfflineStatusChangeEventOnThaw) {
    8777               0 :     mFireOfflineStatusChangeEventOnThaw = false;
    8778               0 :     FireOfflineStatusEvent();
    8779                 :   }
    8780                 : 
    8781                 :   nsCOMPtr<nsIDocShellTreeNode> node =
    8782               0 :     do_QueryInterface(GetDocShell());
    8783               0 :   if (node) {
    8784               0 :     PRInt32 childCount = 0;
    8785               0 :     node->GetChildCount(&childCount);
    8786                 : 
    8787               0 :     for (PRInt32 i = 0; i < childCount; ++i) {
    8788               0 :       nsCOMPtr<nsIDocShellTreeItem> childShell;
    8789               0 :       node->GetChildAt(i, getter_AddRefs(childShell));
    8790               0 :       NS_ASSERTION(childShell, "null child shell");
    8791                 : 
    8792               0 :       nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
    8793               0 :       if (pWin) {
    8794                 :         nsGlobalWindow *win =
    8795                 :           static_cast<nsGlobalWindow*>
    8796               0 :                      (static_cast<nsPIDOMWindow*>(pWin));
    8797               0 :         win->FireDelayedDOMEvents();
    8798                 :       }
    8799                 :     }
    8800                 :   }
    8801                 : 
    8802               0 :   return NS_OK;
    8803                 : }
    8804                 : 
    8805                 : //*****************************************************************************
    8806                 : // nsGlobalWindow: Window Control Functions
    8807                 : //*****************************************************************************
    8808                 : 
    8809                 : nsIDOMWindow *
    8810               0 : nsGlobalWindow::GetParentInternal()
    8811                 : {
    8812               0 :   FORWARD_TO_OUTER(GetParentInternal, (), nsnull);
    8813                 : 
    8814               0 :   nsCOMPtr<nsIDOMWindow> parent;
    8815               0 :   GetParent(getter_AddRefs(parent));
    8816                 : 
    8817               0 :   if (parent && parent != static_cast<nsIDOMWindow *>(this)) {
    8818               0 :     return parent;
    8819                 :   }
    8820                 : 
    8821               0 :   return NULL;
    8822                 : }
    8823                 : 
    8824                 : // static
    8825                 : void
    8826               0 : nsGlobalWindow::CloseBlockScriptTerminationFunc(nsISupports *aRef)
    8827                 : {
    8828                 :   nsGlobalWindow* pwin = static_cast<nsGlobalWindow*>
    8829               0 :                                     (static_cast<nsPIDOMWindow*>(aRef));
    8830               0 :   pwin->mBlockScriptedClosingFlag = false;
    8831               0 : }
    8832                 : 
    8833                 : nsresult
    8834               0 : nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
    8835                 :                              const nsAString& aOptions, bool aDialog,
    8836                 :                              bool aContentModal, bool aCalledNoScript,
    8837                 :                              bool aDoJSFixups, nsIArray *argv,
    8838                 :                              nsISupports *aExtraArgument,
    8839                 :                              nsIPrincipal *aCalleePrincipal,
    8840                 :                              JSContext *aJSCallerContext,
    8841                 :                              nsIDOMWindow **aReturn)
    8842                 : {
    8843               0 :   FORWARD_TO_OUTER(OpenInternal, (aUrl, aName, aOptions, aDialog,
    8844                 :                                   aContentModal, aCalledNoScript, aDoJSFixups,
    8845                 :                                   argv, aExtraArgument, aCalleePrincipal,
    8846                 :                                   aJSCallerContext, aReturn),
    8847                 :                    NS_ERROR_NOT_INITIALIZED);
    8848                 : 
    8849                 : #ifdef NS_DEBUG
    8850               0 :   PRUint32 argc = 0;
    8851               0 :   if (argv)
    8852               0 :       argv->GetLength(&argc);
    8853                 : #endif
    8854               0 :   NS_PRECONDITION(!aExtraArgument || (!argv && argc == 0),
    8855                 :                   "Can't pass in arguments both ways");
    8856               0 :   NS_PRECONDITION(!aCalledNoScript || (!argv && argc == 0),
    8857                 :                   "Can't pass JS args when called via the noscript methods");
    8858               0 :   NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript,
    8859                 :                   "Shouldn't have caller context when called noscript");
    8860                 : 
    8861               0 :   *aReturn = nsnull;
    8862                 : 
    8863               0 :   nsCOMPtr<nsIWebBrowserChrome> chrome;
    8864               0 :   GetWebBrowserChrome(getter_AddRefs(chrome));
    8865               0 :   if (!chrome) {
    8866                 :     // No chrome means we don't want to go through with this open call
    8867                 :     // -- see nsIWindowWatcher.idl
    8868               0 :     return NS_ERROR_NOT_AVAILABLE;
    8869                 :   }
    8870                 : 
    8871               0 :   NS_ASSERTION(mDocShell, "Must have docshell here");
    8872                 : 
    8873               0 :   const bool checkForPopup = !nsContentUtils::IsCallerChrome() &&
    8874               0 :     !aDialog && !WindowExists(aName, !aCalledNoScript);
    8875                 : 
    8876                 :   // Note: it's very important that this be an nsXPIDLCString, since we want
    8877                 :   // .get() on it to return nsnull until we write stuff to it.  The window
    8878                 :   // watcher expects a null URL string if there is no URL to load.
    8879               0 :   nsXPIDLCString url;
    8880               0 :   nsresult rv = NS_OK;
    8881                 : 
    8882                 :   // It's important to do this security check before determining whether this
    8883                 :   // window opening should be blocked, to ensure that we don't FireAbuseEvents
    8884                 :   // for a window opening that wouldn't have succeeded in the first place.
    8885               0 :   if (!aUrl.IsEmpty()) {
    8886               0 :     AppendUTF16toUTF8(aUrl, url);
    8887                 : 
    8888                 :     /* Check whether the URI is allowed, but not for dialogs --
    8889                 :        see bug 56851. The security of this function depends on
    8890                 :        window.openDialog being inaccessible from web scripts */
    8891               0 :     if (url.get() && !aDialog)
    8892               0 :       rv = SecurityCheckURL(url.get());
    8893                 :   }
    8894                 : 
    8895               0 :   if (NS_FAILED(rv))
    8896               0 :     return rv;
    8897                 : 
    8898               0 :   PopupControlState abuseLevel = gPopupControlState;
    8899               0 :   if (checkForPopup) {
    8900               0 :     abuseLevel = RevisePopupAbuseLevel(abuseLevel);
    8901               0 :     if (abuseLevel >= openAbused) {
    8902               0 :       if (aJSCallerContext) {
    8903                 :         // If script in some other window is doing a window.open on us and
    8904                 :         // it's being blocked, then it's OK to close us afterwards, probably.
    8905                 :         // But if we're doing a window.open on ourselves and block the popup,
    8906                 :         // prevent this window from closing until after this script terminates
    8907                 :         // so that whatever popup blocker UI the app has will be visible.
    8908               0 :         if (mContext == GetScriptContextFromJSContext(aJSCallerContext)) {
    8909               0 :           mBlockScriptedClosingFlag = true;
    8910               0 :           mContext->SetTerminationFunction(CloseBlockScriptTerminationFunc,
    8911               0 :                                            this);
    8912                 :         }
    8913                 :       }
    8914                 : 
    8915               0 :       FireAbuseEvents(true, false, aUrl, aName, aOptions);
    8916               0 :       return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
    8917                 :     }
    8918                 :   }    
    8919                 : 
    8920               0 :   nsCOMPtr<nsIDOMWindow> domReturn;
    8921                 : 
    8922                 :   nsCOMPtr<nsIWindowWatcher> wwatch =
    8923               0 :     do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
    8924               0 :   NS_ENSURE_TRUE(wwatch, rv);
    8925                 : 
    8926               0 :   NS_ConvertUTF16toUTF8 options(aOptions);
    8927               0 :   NS_ConvertUTF16toUTF8 name(aName);
    8928                 : 
    8929               0 :   const char *options_ptr = aOptions.IsEmpty() ? nsnull : options.get();
    8930               0 :   const char *name_ptr = aName.IsEmpty() ? nsnull : name.get();
    8931                 : 
    8932                 :   {
    8933                 :     // Reset popup state while opening a window to prevent the
    8934                 :     // current state from being active the whole time a modal
    8935                 :     // dialog is open.
    8936               0 :     nsAutoPopupStatePusher popupStatePusher(openAbused, true);
    8937                 : 
    8938               0 :     if (!aCalledNoScript) {
    8939               0 :       nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
    8940               0 :       NS_ASSERTION(pwwatch,
    8941                 :                    "Unable to open windows from JS because window watcher "
    8942                 :                    "is broken");
    8943               0 :       NS_ENSURE_TRUE(pwwatch, NS_ERROR_UNEXPECTED);
    8944                 :         
    8945               0 :       rv = pwwatch->OpenWindowJS(this, url.get(), name_ptr, options_ptr,
    8946                 :                                  aDialog, argv,
    8947               0 :                                  getter_AddRefs(domReturn));
    8948                 :     } else {
    8949                 :       // Push a null JSContext here so that the window watcher won't screw us
    8950                 :       // up.  We do NOT want this case looking at the JS context on the stack
    8951                 :       // when searching.  Compare comments on
    8952                 :       // nsIDOMWindow::OpenWindow and nsIWindowWatcher::OpenWindow.
    8953               0 :       nsCOMPtr<nsIJSContextStack> stack;
    8954                 : 
    8955               0 :       if (!aContentModal) {
    8956               0 :         stack = do_GetService(sJSStackContractID);
    8957                 :       }
    8958                 : 
    8959               0 :       if (stack) {
    8960               0 :         rv = stack->Push(nsnull);
    8961               0 :         NS_ENSURE_SUCCESS(rv, rv);
    8962                 :       }
    8963                 :         
    8964               0 :       rv = wwatch->OpenWindow(this, url.get(), name_ptr, options_ptr,
    8965               0 :                               aExtraArgument, getter_AddRefs(domReturn));
    8966                 : 
    8967               0 :       if (stack) {
    8968                 :         JSContext* cx;
    8969               0 :         stack->Pop(&cx);
    8970               0 :         NS_ASSERTION(!cx, "Unexpected JSContext popped!");
    8971                 :       }
    8972                 :     }
    8973                 :   }
    8974                 : 
    8975               0 :   NS_ENSURE_SUCCESS(rv, rv);
    8976                 : 
    8977                 :   // success!
    8978                 : 
    8979               0 :   domReturn.swap(*aReturn);
    8980                 : 
    8981               0 :   if (aDoJSFixups) {      
    8982               0 :     nsCOMPtr<nsIDOMChromeWindow> chrome_win(do_QueryInterface(*aReturn));
    8983               0 :     if (!chrome_win) {
    8984                 :       // A new non-chrome window was created from a call to
    8985                 :       // window.open() from JavaScript, make sure there's a document in
    8986                 :       // the new window. We do this by simply asking the new window for
    8987                 :       // its document, this will synchronously create an empty document
    8988                 :       // if there is no document in the window.
    8989                 :       // XXXbz should this just use EnsureInnerWindow()?
    8990                 : #ifdef DEBUG_jst
    8991                 :       {
    8992                 :         nsCOMPtr<nsPIDOMWindow> pidomwin(do_QueryInterface(*aReturn));
    8993                 : 
    8994                 :         nsIDOMDocument *temp = pidomwin->GetExtantDocument();
    8995                 : 
    8996                 :         NS_ASSERTION(temp, "No document in new window!!!");
    8997                 :       }
    8998                 : #endif
    8999                 : 
    9000               0 :       nsCOMPtr<nsIDOMDocument> doc;
    9001               0 :       (*aReturn)->GetDocument(getter_AddRefs(doc));
    9002                 :     }
    9003                 :   }
    9004                 :     
    9005               0 :   if (checkForPopup) {
    9006               0 :     if (abuseLevel >= openControlled) {
    9007               0 :       nsGlobalWindow *opened = static_cast<nsGlobalWindow *>(*aReturn);
    9008               0 :       if (!opened->IsPopupSpamWindow()) {
    9009               0 :         opened->SetPopupSpamWindow(true);
    9010               0 :         ++gOpenPopupSpamCount;
    9011                 :       }
    9012                 :     }
    9013               0 :     if (abuseLevel >= openAbused)
    9014               0 :       FireAbuseEvents(false, true, aUrl, aName, aOptions);
    9015                 :   }
    9016                 : 
    9017               0 :   return rv;
    9018                 : }
    9019                 : 
    9020                 : // static
    9021                 : void
    9022               0 : nsGlobalWindow::CloseWindow(nsISupports *aWindow)
    9023                 : {
    9024               0 :   nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aWindow));
    9025                 : 
    9026                 :   nsGlobalWindow* globalWin =
    9027                 :     static_cast<nsGlobalWindow *>
    9028               0 :                (static_cast<nsPIDOMWindow*>(win));
    9029                 : 
    9030                 :   // Need to post an event for closing, otherwise window and 
    9031                 :   // presshell etc. may get destroyed while creating frames, bug 338897.
    9032               0 :   nsCloseEvent::PostCloseEvent(globalWin);
    9033                 :   // else if OOM, better not to close. That might cause a crash.
    9034               0 : }
    9035                 : 
    9036                 : //*****************************************************************************
    9037                 : // nsGlobalWindow: Timeout Functions
    9038                 : //*****************************************************************************
    9039                 : 
    9040                 : PRUint32 sNestingLevel;
    9041                 : 
    9042                 : nsresult
    9043               0 : nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
    9044                 :                                      PRInt32 interval,
    9045                 :                                      bool aIsInterval, PRInt32 *aReturn)
    9046                 : {
    9047               0 :   FORWARD_TO_INNER(SetTimeoutOrInterval, (aHandler, interval, aIsInterval, aReturn),
    9048                 :                    NS_ERROR_NOT_INITIALIZED);
    9049                 : 
    9050                 :   // If we don't have a document (we could have been unloaded since
    9051                 :   // the call to setTimeout was made), do nothing.
    9052               0 :   if (!mDocument) {
    9053               0 :     return NS_OK;
    9054                 :   }
    9055                 : 
    9056                 :   // Disallow negative intervals.  If aIsInterval also disallow 0,
    9057                 :   // because we use that as a "don't repeat" flag.
    9058               0 :   interval = NS_MAX(aIsInterval ? 1 : 0, interval);
    9059                 : 
    9060                 :   // Make sure we don't proceed with an interval larger than our timer
    9061                 :   // code can handle. (Note: we already forced |interval| to be non-negative,
    9062                 :   // so the PRUint32 cast (to avoid compiler warnings) is ok.)
    9063               0 :   PRUint32 maxTimeoutMs = PR_IntervalToMilliseconds(DOM_MAX_TIMEOUT_VALUE);
    9064               0 :   if (static_cast<PRUint32>(interval) > maxTimeoutMs) {
    9065               0 :     interval = maxTimeoutMs;
    9066                 :   }
    9067                 : 
    9068               0 :   nsRefPtr<nsTimeout> timeout = new nsTimeout();
    9069               0 :   timeout->mIsInterval = aIsInterval;
    9070               0 :   timeout->mInterval = interval;
    9071               0 :   timeout->mScriptHandler = aHandler;
    9072                 : 
    9073                 :   // Now clamp the actual interval we will use for the timer based on
    9074               0 :   PRUint32 nestingLevel = sNestingLevel + 1;
    9075               0 :   PRInt32 realInterval = interval;
    9076               0 :   if (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL) {
    9077                 :     // Don't allow timeouts less than DOMMinTimeoutValue() from
    9078                 :     // now...
    9079               0 :     realInterval = NS_MAX(realInterval, DOMMinTimeoutValue());
    9080                 :   }
    9081                 : 
    9082                 :   // Get principal of currently executing code, save for execution of timeout.
    9083                 :   // If our principals subsume the subject principal then use the subject
    9084                 :   // principal. Otherwise, use our principal to avoid running script in
    9085                 :   // elevated principals.
    9086                 : 
    9087               0 :   nsCOMPtr<nsIPrincipal> subjectPrincipal;
    9088                 :   nsresult rv;
    9089               0 :   rv = nsContentUtils::GetSecurityManager()->
    9090               0 :     GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
    9091               0 :   if (NS_FAILED(rv)) {
    9092               0 :     return NS_ERROR_FAILURE;
    9093                 :   }
    9094                 : 
    9095               0 :   bool subsumes = false;
    9096               0 :   nsCOMPtr<nsIPrincipal> ourPrincipal = GetPrincipal();
    9097                 : 
    9098                 :   // Note the direction of this test: We don't allow setTimeouts running with
    9099                 :   // chrome privileges on content windows, but we do allow setTimeouts running
    9100                 :   // with content privileges on chrome windows (where they can't do very much,
    9101                 :   // of course).
    9102               0 :   rv = ourPrincipal->Subsumes(subjectPrincipal, &subsumes);
    9103               0 :   if (NS_FAILED(rv)) {
    9104               0 :     return NS_ERROR_FAILURE;
    9105                 :   }
    9106                 : 
    9107               0 :   if (subsumes) {
    9108               0 :     timeout->mPrincipal = subjectPrincipal;
    9109                 :   } else {
    9110               0 :     timeout->mPrincipal = ourPrincipal;
    9111                 :   }
    9112                 : 
    9113               0 :   ++gTimeoutsRecentlySet;
    9114               0 :   TimeDuration delta = TimeDuration::FromMilliseconds(realInterval);
    9115                 : 
    9116               0 :   if (!IsFrozen() && !mTimeoutsSuspendDepth) {
    9117                 :     // If we're not currently frozen, then we set timeout->mWhen to be the
    9118                 :     // actual firing time of the timer (i.e., now + delta). We also actually
    9119                 :     // create a timer and fire it off.
    9120                 : 
    9121               0 :     timeout->mWhen = TimeStamp::Now() + delta;
    9122                 : 
    9123               0 :     timeout->mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
    9124               0 :     if (NS_FAILED(rv)) {
    9125               0 :       return rv;
    9126                 :     }
    9127                 : 
    9128               0 :     nsRefPtr<nsTimeout> copy = timeout;
    9129                 : 
    9130               0 :     rv = timeout->mTimer->InitWithFuncCallback(TimerCallback, timeout,
    9131                 :                                                realInterval,
    9132               0 :                                                nsITimer::TYPE_ONE_SHOT);
    9133               0 :     if (NS_FAILED(rv)) {
    9134               0 :       return rv;
    9135                 :     }
    9136                 : 
    9137                 :     // The timeout is now also held in the timer's closure.
    9138               0 :     copy.forget();
    9139                 :   } else {
    9140                 :     // If we are frozen, however, then we instead simply set
    9141                 :     // timeout->mTimeRemaining to be the "time remaining" in the timeout (i.e.,
    9142                 :     // the interval itself). We don't create a timer for it, since that will
    9143                 :     // happen when we are thawed and the timeout will then get a timer and run
    9144                 :     // to completion.
    9145                 : 
    9146               0 :     timeout->mTimeRemaining = delta;
    9147                 :   }
    9148                 : 
    9149               0 :   timeout->mWindow = this;
    9150                 : 
    9151               0 :   if (!aIsInterval) {
    9152               0 :     timeout->mNestingLevel = nestingLevel;
    9153                 :   }
    9154                 : 
    9155                 :   // No popups from timeouts by default
    9156               0 :   timeout->mPopupState = openAbused;
    9157                 : 
    9158               0 :   if (gRunningTimeoutDepth == 0 && gPopupControlState < openAbused) {
    9159                 :     // This timeout is *not* set from another timeout and it's set
    9160                 :     // while popups are enabled. Propagate the state to the timeout if
    9161                 :     // its delay (interval) is equal to or less than what
    9162                 :     // "dom.disable_open_click_delay" is set to (in ms).
    9163                 : 
    9164                 :     PRInt32 delay =
    9165               0 :       Preferences::GetInt("dom.disable_open_click_delay");
    9166                 : 
    9167                 :     // This is checking |interval|, not realInterval, on purpose,
    9168                 :     // because our lower bound for |realInterval| could be pretty high
    9169                 :     // in some cases.
    9170               0 :     if (interval <= delay) {
    9171               0 :       timeout->mPopupState = gPopupControlState;
    9172                 :     }
    9173                 :   }
    9174                 : 
    9175               0 :   InsertTimeoutIntoList(timeout);
    9176                 : 
    9177               0 :   timeout->mPublicId = ++mTimeoutPublicIdCounter;
    9178               0 :   *aReturn = timeout->mPublicId;
    9179                 : 
    9180               0 :   return NS_OK;
    9181                 : 
    9182                 : }
    9183                 : 
    9184                 : nsresult
    9185               0 : nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, PRInt32 *aReturn)
    9186                 : {
    9187                 :   // This needs to forward to the inner window, but since the current
    9188                 :   // inner may not be the inner in the calling scope, we need to treat
    9189                 :   // this specially here as we don't want timeouts registered in a
    9190                 :   // dying inner window to get registered and run on the current inner
    9191                 :   // window. To get this right, we need to forward this call to the
    9192                 :   // inner window that's calling window.setTimeout().
    9193                 : 
    9194               0 :   if (IsOuterWindow()) {
    9195               0 :     nsGlobalWindow* callerInner = CallerInnerWindow();
    9196               0 :     NS_ENSURE_TRUE(callerInner, NS_ERROR_NOT_AVAILABLE);
    9197                 : 
    9198                 :     // If the caller and the callee share the same outer window,
    9199                 :     // forward to the callee inner. Else, we forward to the current
    9200                 :     // inner (e.g. someone is calling setTimeout() on a reference to
    9201                 :     // some other window).
    9202                 : 
    9203               0 :     if (callerInner->GetOuterWindow() == this &&
    9204               0 :         callerInner->IsInnerWindow()) {
    9205               0 :       return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
    9206                 :     }
    9207                 : 
    9208               0 :     FORWARD_TO_INNER(SetTimeoutOrInterval, (aIsInterval, aReturn),
    9209                 :                      NS_ERROR_NOT_INITIALIZED);
    9210                 :   }
    9211                 : 
    9212               0 :   PRInt32 interval = 0;
    9213               0 :   bool isInterval = aIsInterval;
    9214               0 :   nsCOMPtr<nsIScriptTimeoutHandler> handler;
    9215                 :   nsresult rv = NS_CreateJSTimeoutHandler(this,
    9216                 :                                           &isInterval,
    9217                 :                                           &interval,
    9218               0 :                                           getter_AddRefs(handler));
    9219               0 :   if (NS_FAILED(rv))
    9220               0 :     return (rv == NS_ERROR_DOM_TYPE_ERR) ? NS_OK : rv;
    9221                 : 
    9222               0 :   return SetTimeoutOrInterval(handler, interval, isInterval, aReturn);
    9223                 : }
    9224                 : 
    9225                 : // static
    9226                 : void
    9227               0 : nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
    9228                 : {
    9229                 :   // If a modal dialog is open for this window, return early. Pending
    9230                 :   // timeouts will run when the modal dialog is dismissed.
    9231               0 :   if (IsInModalState() || mTimeoutsSuspendDepth) {
    9232               0 :     return;
    9233                 :   }
    9234                 : 
    9235                 :   NS_TIME_FUNCTION;
    9236                 : 
    9237               0 :   NS_ASSERTION(IsInnerWindow(), "Timeout running on outer window!");
    9238               0 :   NS_ASSERTION(!IsFrozen(), "Timeout running on a window in the bfcache!");
    9239                 : 
    9240                 :   nsTimeout *nextTimeout, *timeout;
    9241                 :   nsTimeout *last_expired_timeout, *last_insertion_point;
    9242               0 :   nsTimeout dummy_timeout;
    9243               0 :   PRUint32 firingDepth = mTimeoutFiringDepth + 1;
    9244                 : 
    9245                 :   // Make sure that the window and the script context don't go away as
    9246                 :   // a result of running timeouts
    9247               0 :   nsCOMPtr<nsIScriptGlobalObject> windowKungFuDeathGrip(this);
    9248                 : 
    9249                 :   // A native timer has gone off. See which of our timeouts need
    9250                 :   // servicing
    9251               0 :   TimeStamp now = TimeStamp::Now();
    9252               0 :   TimeStamp deadline;
    9253                 : 
    9254               0 :   if (aTimeout && aTimeout->mWhen > now) {
    9255                 :     // The OS timer fired early (yikes!), and possibly out of order
    9256                 :     // too. Set |deadline| to be the time when the OS timer *should*
    9257                 :     // have fired so that any timers that *should* have fired before
    9258                 :     // aTimeout *will* be fired now. This happens most of the time on
    9259                 :     // Win2k.
    9260                 : 
    9261               0 :     deadline = aTimeout->mWhen;
    9262                 :   } else {
    9263               0 :     deadline = now;
    9264                 :   }
    9265                 : 
    9266                 :   // The timeout list is kept in deadline order. Discover the latest
    9267                 :   // timeout whose deadline has expired. On some platforms, native
    9268                 :   // timeout events fire "early", so we need to test the timer as well
    9269                 :   // as the deadline.
    9270               0 :   last_expired_timeout = nsnull;
    9271               0 :   for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) {
    9272               0 :     if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
    9273                 :         (timeout->mFiringDepth == 0)) {
    9274                 :       // Mark any timeouts that are on the list to be fired with the
    9275                 :       // firing depth so that we can reentrantly run timeouts
    9276               0 :       timeout->mFiringDepth = firingDepth;
    9277               0 :       last_expired_timeout = timeout;
    9278                 :     }
    9279                 :   }
    9280                 : 
    9281                 :   // Maybe the timeout that the event was fired for has been deleted
    9282                 :   // and there are no others timeouts with deadlines that make them
    9283                 :   // eligible for execution yet. Go away.
    9284               0 :   if (!last_expired_timeout) {
    9285                 :     return;
    9286                 :   }
    9287                 : 
    9288                 :   // Record telemetry information about timers set recently.
    9289               0 :   TimeDuration recordingInterval = TimeDuration::FromMilliseconds(STATISTICS_INTERVAL);
    9290               0 :   if (gLastRecordedRecentTimeouts.IsNull() ||
    9291               0 :       now - gLastRecordedRecentTimeouts > recordingInterval) {
    9292               0 :     PRUint32 count = gTimeoutsRecentlySet;
    9293               0 :     gTimeoutsRecentlySet = 0;
    9294               0 :     Telemetry::Accumulate(Telemetry::DOM_TIMERS_RECENTLY_SET, count);
    9295               0 :     gLastRecordedRecentTimeouts = now;
    9296                 :   }
    9297                 : 
    9298                 :   // Insert a dummy timeout into the list of timeouts between the
    9299                 :   // portion of the list that we are about to process now and those
    9300                 :   // timeouts that will be processed in a future call to
    9301                 :   // win_run_timeout(). This dummy timeout serves as the head of the
    9302                 :   // list for any timeouts inserted as a result of running a timeout.
    9303               0 :   dummy_timeout.mFiringDepth = firingDepth;
    9304               0 :   dummy_timeout.mWhen = now;
    9305               0 :   PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout);
    9306                 : 
    9307                 :   // Don't let ClearWindowTimeouts throw away our stack-allocated
    9308                 :   // dummy timeout.
    9309               0 :   dummy_timeout.AddRef();
    9310               0 :   dummy_timeout.AddRef();
    9311                 : 
    9312               0 :   last_insertion_point = mTimeoutInsertionPoint;
    9313                 :   // If we ever start setting mTimeoutInsertionPoint to a non-dummy timeout,
    9314                 :   // the logic in ResetTimersForNonBackgroundWindow will need to change.
    9315               0 :   mTimeoutInsertionPoint = &dummy_timeout;
    9316                 : 
    9317               0 :   Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
    9318                 : 
    9319               0 :   for (timeout = FirstTimeout();
    9320               0 :        timeout != &dummy_timeout && !IsFrozen();
    9321                 :        timeout = nextTimeout) {
    9322               0 :     nextTimeout = timeout->Next();
    9323                 : 
    9324               0 :     if (timeout->mFiringDepth != firingDepth) {
    9325                 :       // We skip the timeout since it's on the list to run at another
    9326                 :       // depth.
    9327                 : 
    9328               0 :       continue;
    9329                 :     }
    9330                 : 
    9331               0 :     if (mTimeoutsSuspendDepth) {
    9332                 :       // Some timer did suspend us. Make sure the
    9333                 :       // rest of the timers get executed later.
    9334               0 :       timeout->mFiringDepth = 0;
    9335               0 :       continue;
    9336                 :     }
    9337                 : 
    9338                 :     // The timeout is on the list to run at this depth, go ahead and
    9339                 :     // process it.
    9340                 : 
    9341                 :     // Get the script context (a strong ref to prevent it going away)
    9342                 :     // for this timeout and ensure the script language is enabled.
    9343                 :     nsCOMPtr<nsIScriptContext> scx = GetScriptContextInternal(
    9344               0 :                                 timeout->mScriptHandler->GetScriptTypeID());
    9345                 : 
    9346               0 :     if (!scx) {
    9347                 :       // No context means this window was closed or never properly
    9348                 :       // initialized for this language.
    9349               0 :       continue;
    9350                 :     }
    9351                 : 
    9352                 :     // The "scripts disabled" concept is still a little vague wrt
    9353                 :     // multiple languages.  Prepare for the day when languages can be
    9354                 :     // disabled independently of the other languages...
    9355               0 :     if (!scx->GetScriptsEnabled()) {
    9356                 :       // Scripts were enabled once in this window (unless aTimeout ==
    9357                 :       // nsnull) but now scripts are disabled (we might be in
    9358                 :       // print-preview, for instance), this means we shouldn't run any
    9359                 :       // timeouts at this point.
    9360                 :       //
    9361                 :       // If scripts are enabled for this language in this window again
    9362                 :       // we'll fire the timeouts that are due at that point.
    9363               0 :       continue;
    9364                 :     }
    9365                 : 
    9366                 :     // This timeout is good to run
    9367               0 :     nsTimeout *last_running_timeout = mRunningTimeout;
    9368               0 :     mRunningTimeout = timeout;
    9369               0 :     timeout->mRunning = true;
    9370               0 :     ++timeoutsRan;
    9371                 : 
    9372                 :     // Push this timeout's popup control state, which should only be
    9373                 :     // eabled the first time a timeout fires that was created while
    9374                 :     // popups were enabled and with a delay less than
    9375                 :     // "dom.disable_open_click_delay".
    9376               0 :     nsAutoPopupStatePusher popupStatePusher(timeout->mPopupState);
    9377                 : 
    9378                 :     // Clear the timeout's popup state, if any, to prevent interval
    9379                 :     // timeouts from repeatedly opening poups.
    9380               0 :     timeout->mPopupState = openAbused;
    9381                 : 
    9382                 :     // Hold on to the timeout in case mExpr or mFunObj releases its
    9383                 :     // doc.
    9384               0 :     timeout->AddRef();
    9385                 : 
    9386               0 :     ++gRunningTimeoutDepth;
    9387               0 :     ++mTimeoutFiringDepth;
    9388                 : 
    9389               0 :     bool trackNestingLevel = !timeout->mIsInterval;
    9390                 :     PRUint32 nestingLevel;
    9391               0 :     if (trackNestingLevel) {
    9392               0 :       nestingLevel = sNestingLevel;
    9393               0 :       sNestingLevel = timeout->mNestingLevel;
    9394                 :     }
    9395                 : 
    9396               0 :     nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
    9397               0 :     JSObject* scriptObject = handler->GetScriptObject();
    9398               0 :     if (!scriptObject) {
    9399                 :       // Evaluate the timeout expression.
    9400               0 :       const PRUnichar *script = handler->GetHandlerText();
    9401               0 :       NS_ASSERTION(script, "timeout has no script nor handler text!");
    9402                 : 
    9403               0 :       const char *filename = nsnull;
    9404               0 :       PRUint32 lineNo = 0;
    9405               0 :       handler->GetLocation(&filename, &lineNo);
    9406                 : 
    9407                 :       NS_TIME_FUNCTION_MARK("(file: %s, line: %d)", filename, lineNo);
    9408                 : 
    9409                 :       bool is_undefined;
    9410               0 :       scx->EvaluateString(nsDependentString(script), FastGetGlobalJSObject(),
    9411                 :                           timeout->mPrincipal, timeout->mPrincipal,
    9412                 :                           filename, lineNo,
    9413               0 :                           handler->GetScriptVersion(), nsnull,
    9414               0 :                           &is_undefined);
    9415                 :     } else {
    9416               0 :       nsCOMPtr<nsIVariant> dummy;
    9417               0 :       nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
    9418               0 :       scx->CallEventHandler(me, FastGetGlobalJSObject(),
    9419               0 :                             scriptObject, handler->GetArgv(),
    9420                 :                             // XXXmarkh - consider allowing CallEventHandler to
    9421                 :                             // accept nsnull?
    9422               0 :                             getter_AddRefs(dummy));
    9423                 : 
    9424                 :     }
    9425               0 :     handler = nsnull; // drop reference before dropping timeout refs.
    9426                 : 
    9427               0 :     if (trackNestingLevel) {
    9428               0 :       sNestingLevel = nestingLevel;
    9429                 :     }
    9430                 : 
    9431               0 :     --mTimeoutFiringDepth;
    9432               0 :     --gRunningTimeoutDepth;
    9433                 : 
    9434               0 :     mRunningTimeout = last_running_timeout;
    9435               0 :     timeout->mRunning = false;
    9436                 : 
    9437                 :     // We ignore any failures from calling EvaluateString() or
    9438                 :     // CallEventHandler() on the context here since we're in a loop
    9439                 :     // where we're likely to be running timeouts whose OS timers
    9440                 :     // didn't fire in time and we don't want to not fire those timers
    9441                 :     // now just because execution of one timer failed. We can't
    9442                 :     // propagate the error to anyone who cares about it from this
    9443                 :     // point anyway, and the script context should have already reported
    9444                 :     // the script error in the usual way - so we just drop it.
    9445                 : 
    9446                 :     // If all timeouts were cleared and |timeout != aTimeout| then
    9447                 :     // |timeout| may be the last reference to the timeout so check if
    9448                 :     // it was cleared before releasing it.
    9449               0 :     bool timeout_was_cleared = timeout->mCleared;
    9450                 : 
    9451               0 :     timeout->Release();
    9452                 : 
    9453               0 :     if (timeout_was_cleared) {
    9454                 :       // The running timeout's window was cleared, this means that
    9455                 :       // ClearAllTimeouts() was called from a *nested* call, possibly
    9456                 :       // through a timeout that fired while a modal (to this window)
    9457                 :       // dialog was open or through other non-obvious paths.
    9458                 : 
    9459               0 :       mTimeoutInsertionPoint = last_insertion_point;
    9460                 : 
    9461                 :       return;
    9462                 :     }
    9463                 : 
    9464               0 :     bool isInterval = false;
    9465                 : 
    9466                 :     // If we have a regular interval timer, we re-schedule the
    9467                 :     // timeout, accounting for clock drift.
    9468               0 :     if (timeout->mIsInterval) {
    9469                 :       // Compute time to next timeout for interval timer.
    9470                 :       // Make sure nextInterval is at least DOMMinTimeoutValue().
    9471                 :       TimeDuration nextInterval =
    9472                 :         TimeDuration::FromMilliseconds(NS_MAX(timeout->mInterval,
    9473               0 :                                               PRUint32(DOMMinTimeoutValue())));
    9474                 : 
    9475                 :       // If we're running pending timeouts because they've been temporarily
    9476                 :       // disabled (!aTimeout), set the next interval to be relative to "now",
    9477                 :       // and not to when the timeout that was pending should have fired.
    9478               0 :       TimeStamp firingTime;
    9479               0 :       if (!aTimeout)
    9480               0 :         firingTime = now + nextInterval;
    9481                 :       else
    9482               0 :         firingTime = timeout->mWhen + nextInterval;
    9483                 : 
    9484               0 :       TimeStamp currentNow = TimeStamp::Now();
    9485               0 :       TimeDuration delay = firingTime - currentNow;
    9486                 : 
    9487                 :       // And make sure delay is nonnegative; that might happen if the timer
    9488                 :       // thread is firing our timers somewhat early or if they're taking a long
    9489                 :       // time to run the callback.
    9490               0 :       if (delay < TimeDuration(0)) {
    9491               0 :         delay = TimeDuration(0);
    9492                 :       }
    9493                 : 
    9494               0 :       if (timeout->mTimer) {
    9495               0 :         timeout->mWhen = currentNow + delay; // firingTime unless delay got
    9496                 :                                              // clamped, in which case it's
    9497                 :                                              // currentNow.
    9498                 : 
    9499                 :         // Reschedule the OS timer. Don't bother returning any error
    9500                 :         // codes if this fails since the callers of this method
    9501                 :         // doesn't care about them nobody who cares about them
    9502                 :         // anyways.
    9503                 : 
    9504                 :         // Make sure to cast the unsigned PR_USEC_PER_MSEC to signed
    9505                 :         // PRTime to make the division do the right thing on 64-bit
    9506                 :         // platforms whether delay is positive or negative (which we
    9507                 :         // know is always positive here, but cast anyways for
    9508                 :         // consistency).
    9509               0 :         nsresult rv = timeout->mTimer->
    9510                 :           InitWithFuncCallback(TimerCallback, timeout,
    9511               0 :                                delay.ToMilliseconds(),
    9512               0 :                                nsITimer::TYPE_ONE_SHOT);
    9513                 : 
    9514               0 :         if (NS_FAILED(rv)) {
    9515               0 :           NS_ERROR("Error initializing timer for DOM timeout!");
    9516                 : 
    9517                 :           // We failed to initialize the new OS timer, this timer does
    9518                 :           // us no good here so we just cancel it (just in case) and
    9519                 :           // null out the pointer to the OS timer, this will release the
    9520                 :           // OS timer. As we continue executing the code below we'll end
    9521                 :           // up deleting the timeout since it's not an interval timeout
    9522                 :           // any more (since timeout->mTimer == nsnull).
    9523               0 :           timeout->mTimer->Cancel();
    9524               0 :           timeout->mTimer = nsnull;
    9525                 : 
    9526                 :           // Now that the OS timer no longer has a reference to the
    9527                 :           // timeout we need to drop that reference.
    9528               0 :           timeout->Release();
    9529                 :         }
    9530                 :       } else {
    9531               0 :         NS_ASSERTION(IsFrozen() || mTimeoutsSuspendDepth,
    9532                 :                      "How'd our timer end up null if we're not frozen or "
    9533                 :                      "suspended?");
    9534                 : 
    9535               0 :         timeout->mTimeRemaining = delay;
    9536               0 :         isInterval = true;
    9537                 :       }
    9538                 :     }
    9539                 : 
    9540               0 :     if (timeout->mTimer) {
    9541               0 :       if (timeout->mIsInterval) {
    9542               0 :         isInterval = true;
    9543                 :       } else {
    9544                 :         // The timeout still has an OS timer, and it's not an
    9545                 :         // interval, that means that the OS timer could still fire (if
    9546                 :         // it didn't already, i.e. aTimeout == timeout), cancel the OS
    9547                 :         // timer and release its reference to the timeout.
    9548               0 :         timeout->mTimer->Cancel();
    9549               0 :         timeout->mTimer = nsnull;
    9550                 : 
    9551               0 :         timeout->Release();
    9552                 :       }
    9553                 :     }
    9554                 : 
    9555                 :     // Running a timeout can cause another timeout to be deleted, so
    9556                 :     // we need to reset the pointer to the following timeout.
    9557               0 :     nextTimeout = timeout->Next();
    9558                 : 
    9559               0 :     PR_REMOVE_LINK(timeout);
    9560                 : 
    9561               0 :     if (isInterval) {
    9562                 :       // Reschedule an interval timeout. Insert interval timeout
    9563                 :       // onto list sorted in deadline order.
    9564                 :       // AddRefs timeout.
    9565               0 :       InsertTimeoutIntoList(timeout);
    9566                 :     }
    9567                 : 
    9568                 :     // Release the timeout struct since it's possibly out of the list
    9569               0 :     timeout->Release();
    9570                 :   }
    9571                 : 
    9572                 :   // Take the dummy timeout off the head of the list
    9573               0 :   PR_REMOVE_LINK(&dummy_timeout);
    9574                 : 
    9575               0 :   mTimeoutInsertionPoint = last_insertion_point;
    9576                 : }
    9577                 : 
    9578                 : nsrefcnt
    9579               0 : nsTimeout::Release()
    9580                 : {
    9581               0 :   if (--mRefCnt > 0)
    9582               0 :     return mRefCnt;
    9583                 : 
    9584                 :   // language specific cleanup done as mScriptHandler destructs...
    9585                 : 
    9586                 :   // Kill the timer if it is still alive.
    9587               0 :   if (mTimer) {
    9588               0 :     mTimer->Cancel();
    9589               0 :     mTimer = nsnull;
    9590                 :   }
    9591                 : 
    9592               0 :   delete this;
    9593               0 :   return 0;
    9594                 : }
    9595                 : 
    9596                 : nsrefcnt
    9597               0 : nsTimeout::AddRef()
    9598                 : {
    9599               0 :   return ++mRefCnt;
    9600                 : }
    9601                 : 
    9602                 : 
    9603                 : nsresult
    9604               0 : nsGlobalWindow::ClearTimeoutOrInterval(PRInt32 aTimerID)
    9605                 : {
    9606               0 :   FORWARD_TO_INNER(ClearTimeoutOrInterval, (aTimerID), NS_ERROR_NOT_INITIALIZED);
    9607                 : 
    9608               0 :   PRUint32 public_id = (PRUint32)aTimerID;
    9609                 :   nsTimeout *timeout;
    9610                 : 
    9611               0 :   for (timeout = FirstTimeout();
    9612               0 :        IsTimeout(timeout);
    9613                 :        timeout = timeout->Next()) {
    9614               0 :     if (timeout->mPublicId == public_id) {
    9615               0 :       if (timeout->mRunning) {
    9616                 :         /* We're running from inside the timeout. Mark this
    9617                 :            timeout for deferred deletion by the code in
    9618                 :            RunTimeout() */
    9619               0 :         timeout->mIsInterval = false;
    9620                 :       }
    9621                 :       else {
    9622                 :         /* Delete the timeout from the pending timeout list */
    9623               0 :         PR_REMOVE_LINK(timeout);
    9624                 : 
    9625               0 :         if (timeout->mTimer) {
    9626               0 :           timeout->mTimer->Cancel();
    9627               0 :           timeout->mTimer = nsnull;
    9628               0 :           timeout->Release();
    9629                 :         }
    9630               0 :         timeout->Release();
    9631                 :       }
    9632               0 :       break;
    9633                 :     }
    9634                 :   }
    9635                 : 
    9636               0 :   return NS_OK;
    9637                 : }
    9638                 : 
    9639               0 : nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
    9640                 : {
    9641               0 :   FORWARD_TO_INNER(ResetTimersForNonBackgroundWindow, (),
    9642                 :                    NS_ERROR_NOT_INITIALIZED);
    9643                 : 
    9644               0 :   if (IsFrozen() || mTimeoutsSuspendDepth) {
    9645               0 :     return NS_OK;
    9646                 :   }
    9647                 : 
    9648               0 :   TimeStamp now = TimeStamp::Now();
    9649                 : 
    9650                 :   // If mTimeoutInsertionPoint is non-null, we're in the middle of firing
    9651                 :   // timers and the timers we're planning to fire all come before
    9652                 :   // mTimeoutInsertionPoint; mTimeoutInsertionPoint itself is a dummy timeout
    9653                 :   // with an mWhen that may be semi-bogus.  In that case, we don't need to do
    9654                 :   // anything with mTimeoutInsertionPoint or anything before it, so should
    9655                 :   // start at the timer after mTimeoutInsertionPoint, if there is one.
    9656                 :   // Otherwise, start at the beginning of the list.
    9657               0 :   for (nsTimeout *timeout = mTimeoutInsertionPoint ?
    9658               0 :          mTimeoutInsertionPoint->Next() : FirstTimeout();
    9659               0 :        IsTimeout(timeout); ) {
    9660                 :     // It's important that this check be <= so that we guarantee that
    9661                 :     // taking NS_MAX with |now| won't make a quantity equal to
    9662                 :     // timeout->mWhen below.
    9663               0 :     if (timeout->mWhen <= now) {
    9664               0 :       timeout = timeout->Next();
    9665               0 :       continue;
    9666                 :     }
    9667                 : 
    9668               0 :     if (timeout->mWhen - now >
    9669               0 :         TimeDuration::FromMilliseconds(gMinBackgroundTimeoutValue)) {
    9670                 :       // No need to loop further.  Timeouts are sorted in mWhen order
    9671                 :       // and the ones after this point were all set up for at least
    9672                 :       // gMinBackgroundTimeoutValue ms and hence were not clamped.
    9673               0 :       break;
    9674                 :     }
    9675                 : 
    9676                 :     /* We switched from background. Re-init the timer appropriately */
    9677                 :     // Compute the interval the timer should have had if it had not been set in a
    9678                 :     // background window
    9679                 :     TimeDuration interval =
    9680                 :       TimeDuration::FromMilliseconds(NS_MAX(timeout->mInterval,
    9681               0 :                                             PRUint32(DOMMinTimeoutValue())));
    9682               0 :     PRUint32 oldIntervalMillisecs = 0;
    9683               0 :     timeout->mTimer->GetDelay(&oldIntervalMillisecs);
    9684               0 :     TimeDuration oldInterval = TimeDuration::FromMilliseconds(oldIntervalMillisecs);
    9685               0 :     if (oldInterval > interval) {
    9686                 :       // unclamp
    9687                 :       TimeStamp firingTime =
    9688               0 :         NS_MAX(timeout->mWhen - oldInterval + interval, now);
    9689                 : 
    9690               0 :       NS_ASSERTION(firingTime < timeout->mWhen,
    9691                 :                    "Our firing time should strictly decrease!");
    9692                 : 
    9693               0 :       TimeDuration delay = firingTime - now;
    9694               0 :       timeout->mWhen = firingTime;
    9695                 : 
    9696                 :       // Since we reset mWhen we need to move |timeout| to the right
    9697                 :       // place in the list so that it remains sorted by mWhen.
    9698                 :       
    9699                 :       // Get the pointer to the next timeout now, before we move the
    9700                 :       // current timeout in the list.
    9701               0 :       nsTimeout* nextTimeout = timeout->Next();
    9702                 : 
    9703                 :       // It is safe to remove and re-insert because mWhen is now
    9704                 :       // strictly smaller than it used to be, so we know we'll insert
    9705                 :       // |timeout| before nextTimeout.
    9706               0 :       NS_ASSERTION(!IsTimeout(nextTimeout) ||
    9707                 :                    timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
    9708               0 :       PR_REMOVE_LINK(timeout);
    9709                 :       // InsertTimeoutIntoList will addref |timeout| and reset
    9710                 :       // mFiringDepth.  Make sure to undo that after calling it.
    9711               0 :       PRUint32 firingDepth = timeout->mFiringDepth;
    9712               0 :       InsertTimeoutIntoList(timeout);
    9713               0 :       timeout->mFiringDepth = firingDepth;
    9714               0 :       timeout->Release();
    9715                 : 
    9716                 :       nsresult rv =
    9717               0 :         timeout->mTimer->InitWithFuncCallback(TimerCallback,
    9718                 :                                               timeout,
    9719               0 :                                               delay.ToMilliseconds(),
    9720               0 :                                               nsITimer::TYPE_ONE_SHOT);
    9721                 : 
    9722               0 :       if (NS_FAILED(rv)) {
    9723               0 :         NS_WARNING("Error resetting non background timer for DOM timeout!");
    9724               0 :         return rv;
    9725                 :       }
    9726                 : 
    9727               0 :       timeout = nextTimeout;
    9728                 :     } else {
    9729               0 :       timeout = timeout->Next();
    9730                 :     }
    9731                 :   }
    9732                 : 
    9733               0 :   return NS_OK;
    9734                 : }
    9735                 : 
    9736                 : void
    9737               0 : nsGlobalWindow::ClearAllTimeouts()
    9738                 : {
    9739                 :   nsTimeout *timeout, *nextTimeout;
    9740                 : 
    9741               0 :   for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
    9742                 :     /* If RunTimeout() is higher up on the stack for this
    9743                 :        window, e.g. as a result of document.write from a timeout,
    9744                 :        then we need to reset the list insertion point for
    9745                 :        newly-created timeouts in case the user adds a timeout,
    9746                 :        before we pop the stack back to RunTimeout. */
    9747               0 :     if (mRunningTimeout == timeout)
    9748               0 :       mTimeoutInsertionPoint = nsnull;
    9749                 : 
    9750               0 :     nextTimeout = timeout->Next();
    9751                 : 
    9752               0 :     if (timeout->mTimer) {
    9753               0 :       timeout->mTimer->Cancel();
    9754               0 :       timeout->mTimer = nsnull;
    9755                 : 
    9756                 :       // Drop the count since the timer isn't going to hold on
    9757                 :       // anymore.
    9758               0 :       timeout->Release();
    9759                 :     }
    9760                 : 
    9761                 :     // Set timeout->mCleared to true to indicate that the timeout was
    9762                 :     // cleared and taken out of the list of timeouts
    9763               0 :     timeout->mCleared = true;
    9764                 : 
    9765                 :     // Drop the count since we're removing it from the list.
    9766               0 :     timeout->Release();
    9767                 :   }
    9768                 : 
    9769                 :   // Clear out our list
    9770               0 :   PR_INIT_CLIST(&mTimeouts);
    9771               0 : }
    9772                 : 
    9773                 : void
    9774               0 : nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
    9775                 : {
    9776               0 :   NS_ASSERTION(IsInnerWindow(),
    9777                 :                "InsertTimeoutIntoList() called on outer window!");
    9778                 : 
    9779                 :   // Start at mLastTimeout and go backwards.  Don't go further than
    9780                 :   // mTimeoutInsertionPoint, though.  This optimizes for the common case of
    9781                 :   // insertion at the end.
    9782                 :   nsTimeout* prevSibling;
    9783               0 :   for (prevSibling = LastTimeout();
    9784               0 :        IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint &&
    9785                 :          // This condition needs to match the one in SetTimeoutOrInterval that
    9786                 :          // determines whether to set mWhen or mTimeRemaining.
    9787               0 :          ((IsFrozen() || mTimeoutsSuspendDepth) ?
    9788               0 :           prevSibling->mTimeRemaining > aTimeout->mTimeRemaining :
    9789               0 :           prevSibling->mWhen > aTimeout->mWhen);
    9790                 :        prevSibling = prevSibling->Prev()) {
    9791                 :     /* Do nothing; just searching */
    9792                 :   }
    9793                 : 
    9794                 :   // Now link in aTimeout after prevSibling.
    9795               0 :   PR_INSERT_AFTER(aTimeout, prevSibling);
    9796                 : 
    9797               0 :   aTimeout->mFiringDepth = 0;
    9798                 : 
    9799                 :   // Increment the timeout's reference count since it's now held on to
    9800                 :   // by the list
    9801               0 :   aTimeout->AddRef();
    9802               0 : }
    9803                 : 
    9804                 : // static
    9805                 : void
    9806               0 : nsGlobalWindow::TimerCallback(nsITimer *aTimer, void *aClosure)
    9807                 : {
    9808               0 :   nsRefPtr<nsTimeout> timeout = (nsTimeout *)aClosure;
    9809                 : 
    9810               0 :   timeout->mWindow->RunTimeout(timeout);
    9811               0 : }
    9812                 : 
    9813                 : //*****************************************************************************
    9814                 : // nsGlobalWindow: Helper Functions
    9815                 : //*****************************************************************************
    9816                 : 
    9817                 : nsresult
    9818               0 : nsGlobalWindow::GetTreeOwner(nsIDocShellTreeOwner **aTreeOwner)
    9819                 : {
    9820               0 :   FORWARD_TO_OUTER(GetTreeOwner, (aTreeOwner), NS_ERROR_NOT_INITIALIZED);
    9821                 : 
    9822               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    9823                 : 
    9824                 :   // If there's no docShellAsItem, this window must have been closed,
    9825                 :   // in that case there is no tree owner.
    9826                 : 
    9827               0 :   if (!docShellAsItem) {
    9828               0 :     *aTreeOwner = nsnull;
    9829                 : 
    9830               0 :     return NS_OK;
    9831                 :   }
    9832                 : 
    9833               0 :   return docShellAsItem->GetTreeOwner(aTreeOwner);
    9834                 : }
    9835                 : 
    9836                 : nsresult
    9837               0 : nsGlobalWindow::GetTreeOwner(nsIBaseWindow **aTreeOwner)
    9838                 : {
    9839               0 :   FORWARD_TO_OUTER(GetTreeOwner, (aTreeOwner), NS_ERROR_NOT_INITIALIZED);
    9840                 : 
    9841               0 :   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
    9842               0 :   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    9843                 : 
    9844                 :   // If there's no docShellAsItem, this window must have been closed,
    9845                 :   // in that case there is no tree owner.
    9846                 : 
    9847               0 :   if (docShellAsItem) {
    9848               0 :     docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
    9849                 :   }
    9850                 : 
    9851               0 :   if (!treeOwner) {
    9852               0 :     *aTreeOwner = nsnull;
    9853               0 :     return NS_OK;
    9854                 :   }
    9855                 : 
    9856               0 :   return CallQueryInterface(treeOwner, aTreeOwner);
    9857                 : }
    9858                 : 
    9859                 : nsresult
    9860               0 : nsGlobalWindow::GetWebBrowserChrome(nsIWebBrowserChrome **aBrowserChrome)
    9861                 : {
    9862               0 :   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
    9863               0 :   GetTreeOwner(getter_AddRefs(treeOwner));
    9864                 : 
    9865               0 :   nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
    9866               0 :   NS_IF_ADDREF(*aBrowserChrome = browserChrome);
    9867                 : 
    9868               0 :   return NS_OK;
    9869                 : }
    9870                 : 
    9871                 : nsIScrollableFrame *
    9872               0 : nsGlobalWindow::GetScrollFrame()
    9873                 : {
    9874               0 :   FORWARD_TO_OUTER(GetScrollFrame, (), nsnull);
    9875                 : 
    9876               0 :   if (!mDocShell) {
    9877               0 :     return nsnull;
    9878                 :   }
    9879                 : 
    9880               0 :   nsCOMPtr<nsIPresShell> presShell;
    9881               0 :   mDocShell->GetPresShell(getter_AddRefs(presShell));
    9882               0 :   if (presShell) {
    9883               0 :     return presShell->GetRootScrollFrameAsScrollable();
    9884                 :   }
    9885               0 :   return nsnull;
    9886                 : }
    9887                 : 
    9888                 : nsresult
    9889               0 : nsGlobalWindow::BuildURIfromBase(const char *aURL, nsIURI **aBuiltURI,
    9890                 :                                  bool *aFreeSecurityPass,
    9891                 :                                  JSContext **aCXused)
    9892                 : {
    9893               0 :   nsIScriptContext *scx = GetContextInternal();
    9894               0 :   JSContext *cx = nsnull;
    9895                 : 
    9896               0 :   *aBuiltURI = nsnull;
    9897               0 :   *aFreeSecurityPass = false;
    9898               0 :   if (aCXused)
    9899               0 :     *aCXused = nsnull;
    9900                 : 
    9901                 :   // get JSContext
    9902               0 :   NS_ASSERTION(scx, "opening window missing its context");
    9903               0 :   NS_ASSERTION(mDocument, "opening window missing its document");
    9904               0 :   if (!scx || !mDocument)
    9905               0 :     return NS_ERROR_FAILURE;
    9906                 : 
    9907               0 :   nsCOMPtr<nsIDOMChromeWindow> chrome_win = do_QueryObject(this);
    9908                 : 
    9909               0 :   if (nsContentUtils::IsCallerChrome() && !chrome_win) {
    9910                 :     // If open() is called from chrome on a non-chrome window, we'll
    9911                 :     // use the context from the window on which open() is being called
    9912                 :     // to prevent giving chrome priveleges to new windows opened in
    9913                 :     // such a way. This also makes us get the appropriate base URI for
    9914                 :     // the below URI resolution code.
    9915                 : 
    9916               0 :     cx = scx->GetNativeContext();
    9917                 :   } else {
    9918                 :     // get the JSContext from the call stack
    9919               0 :     nsCOMPtr<nsIThreadJSContextStack> stack(do_GetService(sJSStackContractID));
    9920               0 :     if (stack)
    9921               0 :       stack->Peek(&cx);
    9922                 :   }
    9923                 : 
    9924                 :   /* resolve the URI, which could be relative to the calling window
    9925                 :      (note the algorithm to get the base URI should match the one
    9926                 :      used to actually kick off the load in nsWindowWatcher.cpp). */
    9927               0 :   nsCAutoString charset(NS_LITERAL_CSTRING("UTF-8")); // default to utf-8
    9928               0 :   nsIURI* baseURI = nsnull;
    9929               0 :   nsCOMPtr<nsIURI> uriToLoad;
    9930               0 :   nsCOMPtr<nsIDOMWindow> sourceWindow;
    9931                 : 
    9932               0 :   if (cx) {
    9933               0 :     nsIScriptContext *scriptcx = nsJSUtils::GetDynamicScriptContext(cx);
    9934               0 :     if (scriptcx)
    9935               0 :       sourceWindow = do_QueryInterface(scriptcx->GetGlobalObject());
    9936                 :   }
    9937                 : 
    9938               0 :   if (!sourceWindow) {
    9939               0 :     sourceWindow = do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMWindow *, this));
    9940               0 :     *aFreeSecurityPass = true;
    9941                 :   }
    9942                 : 
    9943               0 :   if (sourceWindow) {
    9944               0 :     nsCOMPtr<nsIDOMDocument> domDoc;
    9945               0 :     sourceWindow->GetDocument(getter_AddRefs(domDoc));
    9946               0 :     nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
    9947               0 :     if (doc) {
    9948               0 :       baseURI = doc->GetDocBaseURI();
    9949               0 :       charset = doc->GetDocumentCharacterSet();
    9950                 :     }
    9951                 :   }
    9952                 : 
    9953               0 :   if (aCXused)
    9954               0 :     *aCXused = cx;
    9955               0 :   return NS_NewURI(aBuiltURI, nsDependentCString(aURL), charset.get(), baseURI);
    9956                 : }
    9957                 : 
    9958                 : nsresult
    9959               0 : nsGlobalWindow::SecurityCheckURL(const char *aURL)
    9960                 : {
    9961                 :   JSContext       *cx;
    9962                 :   bool             freePass;
    9963               0 :   nsCOMPtr<nsIURI> uri;
    9964                 : 
    9965               0 :   if (NS_FAILED(BuildURIfromBase(aURL, getter_AddRefs(uri), &freePass, &cx)))
    9966               0 :     return NS_ERROR_FAILURE;
    9967                 : 
    9968               0 :   if (!freePass && NS_FAILED(nsContentUtils::GetSecurityManager()->
    9969                 :         CheckLoadURIFromScript(cx, uri)))
    9970               0 :     return NS_ERROR_FAILURE;
    9971                 : 
    9972               0 :   return NS_OK;
    9973                 : }
    9974                 : 
    9975                 : void
    9976               0 : nsGlobalWindow::FlushPendingNotifications(mozFlushType aType)
    9977                 : {
    9978               0 :   if (mDoc) {
    9979               0 :     mDoc->FlushPendingNotifications(aType);
    9980                 :   }
    9981               0 : }
    9982                 : 
    9983                 : void
    9984               0 : nsGlobalWindow::EnsureSizeUpToDate()
    9985                 : {
    9986                 :   // If we're a subframe, make sure our size is up to date.  It's OK that this
    9987                 :   // crosses the content/chrome boundary, since chrome can have pending reflows
    9988                 :   // too.
    9989                 :   nsGlobalWindow *parent =
    9990               0 :     static_cast<nsGlobalWindow *>(GetPrivateParent());
    9991               0 :   if (parent) {
    9992               0 :     parent->FlushPendingNotifications(Flush_Layout);
    9993                 :   }
    9994               0 : }
    9995                 : 
    9996                 : nsresult
    9997               0 : nsGlobalWindow::SaveWindowState(nsISupports **aState)
    9998                 : {
    9999               0 :   NS_PRECONDITION(IsOuterWindow(), "Can't save the inner window's state");
   10000                 : 
   10001               0 :   *aState = nsnull;
   10002                 : 
   10003               0 :   if (!mContext || !mJSObject) {
   10004                 :     // The window may be getting torn down; don't bother saving state.
   10005               0 :     return NS_OK;
   10006                 :   }
   10007                 : 
   10008               0 :   nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
   10009               0 :   NS_ASSERTION(inner, "No inner window to save");
   10010                 : 
   10011                 :   // Don't do anything else to this inner window! After this point, all
   10012                 :   // calls to SetTimeoutOrInterval will create entries in the timeout
   10013                 :   // list that will only run after this window has come out of the bfcache.
   10014                 :   // Also, while we're frozen, we won't dispatch online/offline events
   10015                 :   // to the page.
   10016               0 :   inner->Freeze();
   10017                 : 
   10018                 :   // Remember the outer window's prototype.
   10019               0 :   JSContext *cx = mContext->GetNativeContext();
   10020               0 :   JSAutoRequest req(cx);
   10021                 : 
   10022               0 :   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   10023                 : 
   10024                 :   nsCOMPtr<nsIClassInfo> ci =
   10025               0 :     do_QueryInterface((nsIScriptGlobalObject *)this);
   10026               0 :   nsCOMPtr<nsIXPConnectJSObjectHolder> proto;
   10027                 :   nsresult rv = xpc->GetWrappedNativePrototype(cx, mJSObject, ci,
   10028               0 :                                                getter_AddRefs(proto));
   10029               0 :   NS_ENSURE_SUCCESS(rv, rv);
   10030                 : 
   10031               0 :   JSObject *realProto = JS_GetPrototype(mJSObject);
   10032               0 :   nsCOMPtr<nsIXPConnectJSObjectHolder> realProtoHolder;
   10033               0 :   if (realProto) {
   10034               0 :     rv = xpc->HoldObject(cx, realProto, getter_AddRefs(realProtoHolder));
   10035               0 :     NS_ENSURE_SUCCESS(rv, rv);
   10036                 :   }
   10037                 : 
   10038                 :   nsCOMPtr<nsISupports> state = new WindowStateHolder(inner,
   10039                 :                                                       mInnerWindowHolder,
   10040                 :                                                       proto,
   10041               0 :                                                       realProtoHolder);
   10042               0 :   NS_ENSURE_TRUE(state, NS_ERROR_OUT_OF_MEMORY);
   10043                 : 
   10044                 :   JSObject *wnProto;
   10045               0 :   proto->GetJSObject(&wnProto);
   10046               0 :   if (!JS_SetPrototype(cx, mJSObject, wnProto)) {
   10047               0 :     return NS_ERROR_FAILURE;
   10048                 :   }
   10049                 : 
   10050                 : #ifdef DEBUG_PAGE_CACHE
   10051                 :   printf("saving window state, state = %p\n", (void*)state);
   10052                 : #endif
   10053                 : 
   10054               0 :   state.swap(*aState);
   10055               0 :   return NS_OK;
   10056                 : }
   10057                 : 
   10058                 : nsresult
   10059               0 : nsGlobalWindow::RestoreWindowState(nsISupports *aState)
   10060                 : {
   10061               0 :   NS_ASSERTION(IsOuterWindow(), "Cannot restore an inner window");
   10062                 : 
   10063               0 :   if (!mContext || !mJSObject) {
   10064                 :     // The window may be getting torn down; don't bother restoring state.
   10065               0 :     return NS_OK;
   10066                 :   }
   10067                 : 
   10068               0 :   nsCOMPtr<WindowStateHolder> holder = do_QueryInterface(aState);
   10069               0 :   NS_ENSURE_TRUE(holder, NS_ERROR_FAILURE);
   10070                 : 
   10071                 : #ifdef DEBUG_PAGE_CACHE
   10072                 :   printf("restoring window state, state = %p\n", (void*)holder);
   10073                 : #endif
   10074                 : 
   10075                 :   // And we're ready to go!
   10076               0 :   nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
   10077                 : 
   10078                 :   // if a link is focused, refocus with the FLAG_SHOWRING flag set. This makes
   10079                 :   // it easy to tell which link was last clicked when going back a page.
   10080               0 :   nsIContent* focusedNode = inner->GetFocusedNode();
   10081               0 :   if (IsLink(focusedNode)) {
   10082               0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   10083               0 :     if (fm) {
   10084               0 :       nsCOMPtr<nsIDOMElement> focusedElement(do_QueryInterface(focusedNode));
   10085                 :       fm->SetFocus(focusedElement, nsIFocusManager::FLAG_NOSCROLL |
   10086               0 :                                    nsIFocusManager::FLAG_SHOWRING);
   10087                 :     }
   10088                 :   }
   10089                 : 
   10090               0 :   inner->Thaw();
   10091                 : 
   10092               0 :   holder->DidRestoreWindow();
   10093                 : 
   10094               0 :   return NS_OK;
   10095                 : }
   10096                 : 
   10097                 : void
   10098               0 : nsGlobalWindow::SuspendTimeouts(PRUint32 aIncrease,
   10099                 :                                 bool aFreezeChildren)
   10100                 : {
   10101               0 :   FORWARD_TO_INNER_VOID(SuspendTimeouts, (aIncrease, aFreezeChildren));
   10102                 : 
   10103               0 :   bool suspended = (mTimeoutsSuspendDepth != 0);
   10104               0 :   mTimeoutsSuspendDepth += aIncrease;
   10105                 : 
   10106               0 :   if (!suspended) {
   10107               0 :     DisableDeviceMotionUpdates();
   10108                 : 
   10109                 :     // Suspend all of the workers for this window.
   10110               0 :     nsIScriptContext *scx = GetContextInternal();
   10111               0 :     JSContext *cx = scx ? scx->GetNativeContext() : nsnull;
   10112               0 :     mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
   10113                 : 
   10114               0 :     TimeStamp now = TimeStamp::Now();
   10115               0 :     for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
   10116                 :       // Set mTimeRemaining to be the time remaining for this timer.
   10117               0 :       if (t->mWhen > now)
   10118               0 :         t->mTimeRemaining = t->mWhen - now;
   10119                 :       else
   10120               0 :         t->mTimeRemaining = TimeDuration(0);
   10121                 :   
   10122                 :       // Drop the XPCOM timer; we'll reschedule when restoring the state.
   10123               0 :       if (t->mTimer) {
   10124               0 :         t->mTimer->Cancel();
   10125               0 :         t->mTimer = nsnull;
   10126                 :   
   10127                 :         // Drop the reference that the timer's closure had on this timeout, we'll
   10128                 :         // add it back in ResumeTimeouts. Note that it shouldn't matter that we're
   10129                 :         // passing null for the context, since this shouldn't actually release this
   10130                 :         // timeout.
   10131               0 :         t->Release();
   10132                 :       }
   10133                 :     }
   10134                 :   }
   10135                 : 
   10136                 :   // Suspend our children as well.
   10137               0 :   nsCOMPtr<nsIDocShellTreeNode> node(do_QueryInterface(GetDocShell()));
   10138               0 :   if (node) {
   10139               0 :     PRInt32 childCount = 0;
   10140               0 :     node->GetChildCount(&childCount);
   10141                 : 
   10142               0 :     for (PRInt32 i = 0; i < childCount; ++i) {
   10143               0 :       nsCOMPtr<nsIDocShellTreeItem> childShell;
   10144               0 :       node->GetChildAt(i, getter_AddRefs(childShell));
   10145               0 :       NS_ASSERTION(childShell, "null child shell");
   10146                 : 
   10147               0 :       nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
   10148               0 :       if (pWin) {
   10149                 :         nsGlobalWindow *win =
   10150                 :           static_cast<nsGlobalWindow*>
   10151               0 :                      (static_cast<nsPIDOMWindow*>(pWin));
   10152               0 :         NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
   10153               0 :         nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
   10154                 : 
   10155                 :         // This is a bit hackish. Only freeze/suspend windows which are truly our
   10156                 :         // subwindows.
   10157               0 :         nsCOMPtr<nsIContent> frame = do_QueryInterface(pWin->GetFrameElementInternal());
   10158               0 :         if (!mDoc || !frame || mDoc != frame->OwnerDoc() || !inner) {
   10159               0 :           continue;
   10160                 :         }
   10161                 : 
   10162               0 :         win->SuspendTimeouts(aIncrease, aFreezeChildren);
   10163                 : 
   10164               0 :         if (inner && aFreezeChildren) {
   10165               0 :           inner->Freeze();
   10166                 :         }
   10167                 :       }
   10168                 :     }
   10169                 :   }
   10170                 : }
   10171                 : 
   10172                 : nsresult
   10173               0 : nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
   10174                 : {
   10175               0 :   FORWARD_TO_INNER(ResumeTimeouts, (), NS_ERROR_NOT_INITIALIZED);
   10176                 : 
   10177               0 :   NS_ASSERTION(mTimeoutsSuspendDepth, "Mismatched calls to ResumeTimeouts!");
   10178               0 :   --mTimeoutsSuspendDepth;
   10179               0 :   bool shouldResume = (mTimeoutsSuspendDepth == 0);
   10180                 :   nsresult rv;
   10181                 : 
   10182               0 :   if (shouldResume) {
   10183               0 :     EnableDeviceMotionUpdates();
   10184                 : 
   10185                 :     // Resume all of the workers for this window.
   10186               0 :     nsIScriptContext *scx = GetContextInternal();
   10187               0 :     JSContext *cx = scx ? scx->GetNativeContext() : nsnull;
   10188               0 :     mozilla::dom::workers::ResumeWorkersForWindow(cx, this);
   10189                 : 
   10190                 :     // Restore all of the timeouts, using the stored time remaining
   10191                 :     // (stored in timeout->mTimeRemaining).
   10192                 : 
   10193               0 :     TimeStamp now = TimeStamp::Now();
   10194                 : 
   10195                 : #ifdef DEBUG
   10196               0 :     bool _seenDummyTimeout = false;
   10197                 : #endif
   10198                 : 
   10199               0 :     for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
   10200                 :       // There's a chance we're being called with RunTimeout on the stack in which
   10201                 :       // case we have a dummy timeout in the list that *must not* be resumed. It
   10202                 :       // can be identified by a null mWindow.
   10203               0 :       if (!t->mWindow) {
   10204                 : #ifdef DEBUG
   10205               0 :         NS_ASSERTION(!_seenDummyTimeout, "More than one dummy timeout?!");
   10206               0 :         _seenDummyTimeout = true;
   10207                 : #endif
   10208               0 :         continue;
   10209                 :       }
   10210                 : 
   10211                 :       // XXXbz the combination of the way |delay| and |t->mWhen| are set here
   10212                 :       // makes no sense.  Are we trying to impose that min timeout value or
   10213                 :       // not???
   10214                 :       PRUint32 delay =
   10215               0 :         NS_MAX(PRInt32(t->mTimeRemaining.ToMilliseconds()),
   10216               0 :                DOMMinTimeoutValue());
   10217                 : 
   10218                 :       // Set mWhen back to the time when the timer is supposed to
   10219                 :       // fire.
   10220               0 :       t->mWhen = now + t->mTimeRemaining;
   10221                 : 
   10222               0 :       t->mTimer = do_CreateInstance("@mozilla.org/timer;1");
   10223               0 :       NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY);
   10224                 : 
   10225               0 :       rv = t->mTimer->InitWithFuncCallback(TimerCallback, t, delay,
   10226               0 :                                            nsITimer::TYPE_ONE_SHOT);
   10227               0 :       if (NS_FAILED(rv)) {
   10228               0 :         t->mTimer = nsnull;
   10229               0 :         return rv;
   10230                 :       }
   10231                 : 
   10232                 :       // Add a reference for the new timer's closure.
   10233               0 :       t->AddRef();
   10234                 :     }
   10235                 :   }
   10236                 : 
   10237                 :   // Resume our children as well.
   10238                 :   nsCOMPtr<nsIDocShellTreeNode> node =
   10239               0 :     do_QueryInterface(GetDocShell());
   10240               0 :   if (node) {
   10241               0 :     PRInt32 childCount = 0;
   10242               0 :     node->GetChildCount(&childCount);
   10243                 : 
   10244               0 :     for (PRInt32 i = 0; i < childCount; ++i) {
   10245               0 :       nsCOMPtr<nsIDocShellTreeItem> childShell;
   10246               0 :       node->GetChildAt(i, getter_AddRefs(childShell));
   10247               0 :       NS_ASSERTION(childShell, "null child shell");
   10248                 : 
   10249               0 :       nsCOMPtr<nsPIDOMWindow> pWin = do_GetInterface(childShell);
   10250               0 :       if (pWin) {
   10251                 :         nsGlobalWindow *win =
   10252                 :           static_cast<nsGlobalWindow*>
   10253               0 :                      (static_cast<nsPIDOMWindow*>(pWin));
   10254                 : 
   10255               0 :         NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
   10256               0 :         nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
   10257                 : 
   10258                 :         // This is a bit hackish. Only thaw/resume windows which are truly our
   10259                 :         // subwindows.
   10260               0 :         nsCOMPtr<nsIContent> frame = do_QueryInterface(pWin->GetFrameElementInternal());
   10261               0 :         if (!mDoc || !frame || mDoc != frame->OwnerDoc() || !inner) {
   10262               0 :           continue;
   10263                 :         }
   10264                 : 
   10265               0 :         if (inner && aThawChildren) {
   10266               0 :           inner->Thaw();
   10267                 :         }
   10268                 : 
   10269               0 :         rv = win->ResumeTimeouts(aThawChildren);
   10270               0 :         NS_ENSURE_SUCCESS(rv, rv);
   10271                 :       }
   10272                 :     }
   10273                 :   }
   10274                 : 
   10275               0 :   return NS_OK;
   10276                 : }
   10277                 : 
   10278                 : PRUint32
   10279               0 : nsGlobalWindow::TimeoutSuspendCount()
   10280                 : {
   10281               0 :   FORWARD_TO_INNER(TimeoutSuspendCount, (), 0);
   10282               0 :   return mTimeoutsSuspendDepth;
   10283                 : }
   10284                 : 
   10285                 : void
   10286               0 : nsGlobalWindow::SetHasOrientationEventListener()
   10287                 : {
   10288               0 :   mHasDeviceMotion = true;
   10289               0 :   EnableDeviceMotionUpdates();
   10290               0 : }
   10291                 : 
   10292                 : void
   10293               0 : nsGlobalWindow::RemoveOrientationEventListener() {
   10294               0 :   DisableDeviceMotionUpdates();
   10295               0 : }
   10296                 : 
   10297                 : NS_IMETHODIMP
   10298               0 : nsGlobalWindow::GetURL(nsIDOMMozURLProperty** aURL)
   10299                 : {
   10300               0 :   FORWARD_TO_INNER(GetURL, (aURL), NS_ERROR_UNEXPECTED);
   10301                 : 
   10302               0 :   if (!mURLProperty) {
   10303               0 :     mURLProperty = new nsDOMMozURLProperty(this);
   10304                 :   }
   10305                 : 
   10306               0 :   NS_ADDREF(*aURL = mURLProperty);
   10307                 : 
   10308               0 :   return NS_OK;
   10309                 : }
   10310                 : 
   10311                 : // static
   10312                 : bool
   10313             612 : nsGlobalWindow::HasIndexedDBSupport()
   10314                 : {
   10315             612 :   return Preferences::GetBool("indexedDB.feature.enabled", true);
   10316                 : }
   10317                 : 
   10318                 : // static
   10319                 : bool
   10320            1836 : nsGlobalWindow::HasPerformanceSupport() 
   10321                 : {
   10322            1836 :   return Preferences::GetBool("dom.enable_performance", false);
   10323                 : }
   10324                 : 
   10325                 : void
   10326               0 : nsGlobalWindow::SizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
   10327                 : {
   10328               0 :   aWindowSizes->mDOM += aWindowSizes->mMallocSizeOf(this);
   10329                 : 
   10330               0 :   if (IsInnerWindow()) {
   10331                 :     nsEventListenerManager* elm =
   10332               0 :       const_cast<nsGlobalWindow*>(this)->GetListenerManager(false);
   10333               0 :     if (elm) {
   10334                 :       aWindowSizes->mDOM +=
   10335               0 :         elm->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf);
   10336                 :     }
   10337               0 :     if (mDoc) {
   10338               0 :       mDoc->DocSizeOfIncludingThis(aWindowSizes);
   10339                 :     }
   10340                 :   }
   10341                 : 
   10342                 :   aWindowSizes->mDOM +=
   10343                 :     mNavigator ?
   10344               0 :       mNavigator->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf) : 0;
   10345               0 : }
   10346                 : 
   10347                 : // nsGlobalChromeWindow implementation
   10348                 : 
   10349            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
   10350               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
   10351                 :                                                   nsGlobalWindow)
   10352               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBrowserDOMWindow)
   10353               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
   10354               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   10355                 : 
   10356                 : 
   10357               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
   10358                 :                                                 nsGlobalWindow)
   10359               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBrowserDOMWindow)
   10360               0 :   if (tmp->mMessageManager) {
   10361                 :     static_cast<nsFrameMessageManager*>(
   10362               0 :       tmp->mMessageManager.get())->Disconnect();
   10363               0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
   10364                 :   }
   10365               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   10366                 : 
   10367                 : DOMCI_DATA(ChromeWindow, nsGlobalChromeWindow)
   10368                 : 
   10369                 : // QueryInterface implementation for nsGlobalChromeWindow
   10370               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalChromeWindow)
   10371               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMChromeWindow)
   10372               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ChromeWindow)
   10373               0 : NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
   10374                 : 
   10375               0 : NS_IMPL_ADDREF_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
   10376               0 : NS_IMPL_RELEASE_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
   10377                 : 
   10378                 : NS_IMETHODIMP
   10379               0 : nsGlobalChromeWindow::GetWindowState(PRUint16* aWindowState)
   10380                 : {
   10381               0 :   *aWindowState = nsIDOMChromeWindow::STATE_NORMAL;
   10382                 : 
   10383               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   10384                 : 
   10385               0 :   PRInt32 aMode = 0;
   10386                 : 
   10387               0 :   if (widget) {
   10388               0 :     nsresult rv = widget->GetSizeMode(&aMode);
   10389               0 :     NS_ENSURE_SUCCESS(rv, rv);
   10390                 :   }
   10391                 : 
   10392               0 :   switch (aMode) {
   10393                 :     case nsSizeMode_Minimized:
   10394               0 :       *aWindowState = nsIDOMChromeWindow::STATE_MINIMIZED;
   10395               0 :       break;
   10396                 :     case nsSizeMode_Maximized:
   10397               0 :       *aWindowState = nsIDOMChromeWindow::STATE_MAXIMIZED;
   10398               0 :       break;
   10399                 :     case nsSizeMode_Fullscreen:
   10400               0 :       *aWindowState = nsIDOMChromeWindow::STATE_FULLSCREEN;
   10401               0 :       break;
   10402                 :     case nsSizeMode_Normal:
   10403               0 :       *aWindowState = nsIDOMChromeWindow::STATE_NORMAL;
   10404               0 :       break;
   10405                 :     default:
   10406               0 :       NS_WARNING("Illegal window state for this chrome window");
   10407               0 :       break;
   10408                 :   }
   10409                 : 
   10410               0 :   return NS_OK;
   10411                 : }
   10412                 : 
   10413                 : NS_IMETHODIMP
   10414               0 : nsGlobalChromeWindow::Maximize()
   10415                 : {
   10416               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   10417               0 :   nsresult rv = NS_OK;
   10418                 : 
   10419               0 :   if (widget) {
   10420               0 :     rv = widget->SetSizeMode(nsSizeMode_Maximized);
   10421                 :   }
   10422                 : 
   10423               0 :   return rv;
   10424                 : }
   10425                 : 
   10426                 : NS_IMETHODIMP
   10427               0 : nsGlobalChromeWindow::Minimize()
   10428                 : {
   10429               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   10430               0 :   nsresult rv = NS_OK;
   10431                 : 
   10432               0 :   if (widget)
   10433               0 :     rv = widget->SetSizeMode(nsSizeMode_Minimized);
   10434                 : 
   10435               0 :   return rv;
   10436                 : }
   10437                 : 
   10438                 : NS_IMETHODIMP
   10439               0 : nsGlobalChromeWindow::Restore()
   10440                 : {
   10441               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   10442               0 :   nsresult rv = NS_OK;
   10443                 : 
   10444               0 :   if (widget) {
   10445               0 :     rv = widget->SetSizeMode(nsSizeMode_Normal);
   10446                 :   }
   10447                 : 
   10448               0 :   return rv;
   10449                 : }
   10450                 : 
   10451                 : NS_IMETHODIMP
   10452               0 : nsGlobalChromeWindow::GetAttention()
   10453                 : {
   10454               0 :   return GetAttentionWithCycleCount(-1);
   10455                 : }
   10456                 : 
   10457                 : NS_IMETHODIMP
   10458               0 : nsGlobalChromeWindow::GetAttentionWithCycleCount(PRInt32 aCycleCount)
   10459                 : {
   10460               0 :   nsCOMPtr<nsIWidget> widget = GetMainWidget();
   10461               0 :   nsresult rv = NS_OK;
   10462                 : 
   10463               0 :   if (widget) {
   10464               0 :     rv = widget->GetAttention(aCycleCount);
   10465                 :   }
   10466                 : 
   10467               0 :   return rv;
   10468                 : }
   10469                 : 
   10470                 : NS_IMETHODIMP
   10471               0 : nsGlobalChromeWindow::BeginWindowMove(nsIDOMEvent *aMouseDownEvent, nsIDOMElement* aPanel)
   10472                 : {
   10473               0 :   nsCOMPtr<nsIWidget> widget;
   10474                 : 
   10475                 :   // if a panel was supplied, use its widget instead.
   10476                 : #ifdef MOZ_XUL
   10477               0 :   if (aPanel) {
   10478               0 :     nsCOMPtr<nsIContent> panel = do_QueryInterface(aPanel);
   10479               0 :     NS_ENSURE_TRUE(panel, NS_ERROR_FAILURE);
   10480                 : 
   10481               0 :     nsIFrame* frame = panel->GetPrimaryFrame();
   10482               0 :     NS_ENSURE_TRUE(frame && frame->GetType() == nsGkAtoms::menuPopupFrame, NS_OK);
   10483                 : 
   10484               0 :     widget = (static_cast<nsMenuPopupFrame*>(frame))->GetWidget();
   10485                 :   }
   10486                 :   else {
   10487                 : #endif
   10488               0 :     widget = GetMainWidget();
   10489                 : #ifdef MOZ_XUL
   10490                 :   }
   10491                 : #endif
   10492                 : 
   10493               0 :   if (!widget) {
   10494               0 :     return NS_OK;
   10495                 :   }
   10496                 : 
   10497               0 :   nsCOMPtr<nsIPrivateDOMEvent> privEvent = do_QueryInterface(aMouseDownEvent);
   10498               0 :   NS_ENSURE_TRUE(privEvent, NS_ERROR_FAILURE);
   10499               0 :   nsEvent *internalEvent = privEvent->GetInternalNSEvent();
   10500               0 :   NS_ENSURE_TRUE(internalEvent &&
   10501                 :                  internalEvent->eventStructType == NS_MOUSE_EVENT,
   10502                 :                  NS_ERROR_FAILURE);
   10503               0 :   nsMouseEvent *mouseEvent = static_cast<nsMouseEvent*>(internalEvent);
   10504                 : 
   10505               0 :   return widget->BeginMoveDrag(mouseEvent);
   10506                 : }
   10507                 : 
   10508                 : //Note: This call will lock the cursor, it will not change as it moves.
   10509                 : //To unlock, the cursor must be set back to CURSOR_AUTO.
   10510                 : NS_IMETHODIMP
   10511               0 : nsGlobalChromeWindow::SetCursor(const nsAString& aCursor)
   10512                 : {
   10513               0 :   FORWARD_TO_OUTER_CHROME(SetCursor, (aCursor), NS_ERROR_NOT_INITIALIZED);
   10514                 : 
   10515               0 :   nsresult rv = NS_OK;
   10516                 :   PRInt32 cursor;
   10517                 : 
   10518                 :   // use C strings to keep the code/data size down
   10519               0 :   NS_ConvertUTF16toUTF8 cursorString(aCursor);
   10520                 : 
   10521               0 :   if (cursorString.Equals("auto"))
   10522               0 :     cursor = NS_STYLE_CURSOR_AUTO;
   10523                 :   else {
   10524               0 :     nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(aCursor);
   10525               0 :     if (eCSSKeyword_UNKNOWN == keyword ||
   10526               0 :         !nsCSSProps::FindKeyword(keyword, nsCSSProps::kCursorKTable, cursor)) {
   10527                 :       // XXX remove the following three values (leave return NS_OK) after 1.8
   10528                 :       // XXX since they should have been -moz- prefixed (covered by FindKeyword).
   10529                 :       // XXX (also remove |cursorString| at that point?).
   10530               0 :       if (cursorString.Equals("grab"))
   10531               0 :         cursor = NS_STYLE_CURSOR_GRAB;
   10532               0 :       else if (cursorString.Equals("grabbing"))
   10533               0 :         cursor = NS_STYLE_CURSOR_GRABBING;
   10534               0 :       else if (cursorString.Equals("spinning"))
   10535               0 :         cursor = NS_STYLE_CURSOR_SPINNING;
   10536                 :       else
   10537               0 :         return NS_OK;
   10538                 :     }
   10539                 :   }
   10540                 : 
   10541               0 :   nsRefPtr<nsPresContext> presContext;
   10542               0 :   if (mDocShell) {
   10543               0 :     mDocShell->GetPresContext(getter_AddRefs(presContext));
   10544                 :   }
   10545                 : 
   10546               0 :   if (presContext) {
   10547                 :     // Need root widget.
   10548               0 :     nsCOMPtr<nsIPresShell> presShell;
   10549               0 :     mDocShell->GetPresShell(getter_AddRefs(presShell));
   10550               0 :     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
   10551                 : 
   10552               0 :     nsIViewManager* vm = presShell->GetViewManager();
   10553               0 :     NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
   10554                 : 
   10555               0 :     nsIView* rootView = vm->GetRootView();
   10556               0 :     NS_ENSURE_TRUE(rootView, NS_ERROR_FAILURE);
   10557                 : 
   10558               0 :     nsIWidget* widget = rootView->GetNearestWidget(nsnull);
   10559               0 :     NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
   10560                 : 
   10561                 :     // Call esm and set cursor.
   10562                 :     rv = presContext->EventStateManager()->SetCursor(cursor, nsnull,
   10563                 :                                                      false, 0.0f, 0.0f,
   10564               0 :                                                      widget, true);
   10565                 :   }
   10566                 : 
   10567               0 :   return rv;
   10568                 : }
   10569                 : 
   10570                 : NS_IMETHODIMP
   10571               0 : nsGlobalChromeWindow::GetBrowserDOMWindow(nsIBrowserDOMWindow **aBrowserWindow)
   10572                 : {
   10573               0 :   FORWARD_TO_OUTER_CHROME(GetBrowserDOMWindow, (aBrowserWindow),
   10574                 :                           NS_ERROR_NOT_INITIALIZED);
   10575                 : 
   10576               0 :   NS_ENSURE_ARG_POINTER(aBrowserWindow);
   10577                 : 
   10578               0 :   *aBrowserWindow = mBrowserDOMWindow;
   10579               0 :   NS_IF_ADDREF(*aBrowserWindow);
   10580               0 :   return NS_OK;
   10581                 : }
   10582                 : 
   10583                 : NS_IMETHODIMP
   10584               0 : nsGlobalChromeWindow::SetBrowserDOMWindow(nsIBrowserDOMWindow *aBrowserWindow)
   10585                 : {
   10586               0 :   FORWARD_TO_OUTER_CHROME(SetBrowserDOMWindow, (aBrowserWindow),
   10587                 :                           NS_ERROR_NOT_INITIALIZED);
   10588                 : 
   10589               0 :   mBrowserDOMWindow = aBrowserWindow;
   10590               0 :   return NS_OK;
   10591                 : }
   10592                 : 
   10593                 : NS_IMETHODIMP
   10594               0 : nsGlobalChromeWindow::NotifyDefaultButtonLoaded(nsIDOMElement* aDefaultButton)
   10595                 : {
   10596                 : #ifdef MOZ_XUL
   10597               0 :   NS_ENSURE_ARG(aDefaultButton);
   10598                 : 
   10599                 :   // Don't snap to a disabled button.
   10600                 :   nsCOMPtr<nsIDOMXULControlElement> xulControl =
   10601               0 :                                       do_QueryInterface(aDefaultButton);
   10602               0 :   NS_ENSURE_TRUE(xulControl, NS_ERROR_FAILURE);
   10603                 :   bool disabled;
   10604               0 :   nsresult rv = xulControl->GetDisabled(&disabled);
   10605               0 :   NS_ENSURE_SUCCESS(rv, rv);
   10606               0 :   if (disabled)
   10607               0 :     return NS_OK;
   10608                 : 
   10609                 :   // Get the button rect in screen coordinates.
   10610               0 :   nsCOMPtr<nsIContent> content(do_QueryInterface(aDefaultButton));
   10611               0 :   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
   10612               0 :   nsIFrame *frame = content->GetPrimaryFrame();
   10613               0 :   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
   10614               0 :   nsIntRect buttonRect = frame->GetScreenRect();
   10615                 : 
   10616                 :   // Get the widget rect in screen coordinates.
   10617               0 :   nsIWidget *widget = GetNearestWidget();
   10618               0 :   NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
   10619               0 :   nsIntRect widgetRect;
   10620               0 :   rv = widget->GetScreenBounds(widgetRect);
   10621               0 :   NS_ENSURE_SUCCESS(rv, rv);
   10622                 : 
   10623                 :   // Convert the buttonRect coordinates from screen to the widget.
   10624               0 :   buttonRect -= widgetRect.TopLeft();
   10625               0 :   rv = widget->OnDefaultButtonLoaded(buttonRect);
   10626               0 :   if (rv == NS_ERROR_NOT_IMPLEMENTED)
   10627               0 :     return NS_OK;
   10628               0 :   return rv;
   10629                 : #else
   10630                 :   return NS_ERROR_NOT_IMPLEMENTED;
   10631                 : #endif
   10632                 : }
   10633                 : 
   10634                 : NS_IMETHODIMP
   10635               0 : nsGlobalChromeWindow::GetMessageManager(nsIChromeFrameMessageManager** aManager)
   10636                 : {
   10637               0 :   FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_FAILURE);
   10638               0 :   if (!mMessageManager) {
   10639               0 :     nsIScriptContext* scx = GetContextInternal();
   10640               0 :     NS_ENSURE_STATE(scx);
   10641               0 :     JSContext* cx = scx->GetNativeContext();
   10642               0 :     NS_ENSURE_STATE(cx);
   10643                 :     nsCOMPtr<nsIChromeFrameMessageManager> globalMM =
   10644               0 :       do_GetService("@mozilla.org/globalmessagemanager;1");
   10645                 :     mMessageManager =
   10646                 :       new nsFrameMessageManager(true,
   10647                 :                                 nsnull,
   10648                 :                                 nsnull,
   10649                 :                                 nsnull,
   10650                 :                                 nsnull,
   10651               0 :                                 static_cast<nsFrameMessageManager*>(globalMM.get()),
   10652               0 :                                 cx);
   10653               0 :     NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
   10654                 :   }
   10655               0 :   CallQueryInterface(mMessageManager, aManager);
   10656               0 :   return NS_OK;
   10657                 : }
   10658                 : 
   10659                 : // nsGlobalModalWindow implementation
   10660                 : 
   10661                 : // QueryInterface implementation for nsGlobalModalWindow
   10662            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalModalWindow)
   10663               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalModalWindow,
   10664                 :                                                   nsGlobalWindow)
   10665               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReturnValue)
   10666               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   10667                 : 
   10668                 : DOMCI_DATA(ModalContentWindow, nsGlobalModalWindow)
   10669                 : 
   10670               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsGlobalModalWindow)
   10671               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMModalContentWindow)
   10672               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ModalContentWindow)
   10673               0 : NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
   10674                 : 
   10675               0 : NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
   10676               0 : NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
   10677                 : 
   10678                 : 
   10679               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalModalWindow,
   10680                 :                                                 nsGlobalWindow)
   10681               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReturnValue)
   10682               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   10683                 : 
   10684                 : 
   10685                 : NS_IMETHODIMP
   10686               0 : nsGlobalModalWindow::GetDialogArguments(nsIArray **aArguments)
   10687                 : {
   10688               0 :   FORWARD_TO_INNER_MODAL_CONTENT_WINDOW(GetDialogArguments, (aArguments),
   10689                 :                                         NS_ERROR_NOT_INITIALIZED);
   10690                 : 
   10691               0 :   bool subsumes = false;
   10692               0 :   nsIPrincipal *self = GetPrincipal();
   10693               0 :   if (self && NS_SUCCEEDED(self->Subsumes(mArgumentsOrigin, &subsumes)) &&
   10694                 :       subsumes) {
   10695               0 :     NS_IF_ADDREF(*aArguments = mArguments);
   10696                 :   } else {
   10697               0 :     *aArguments = nsnull;
   10698                 :   }
   10699                 : 
   10700               0 :   return NS_OK;
   10701                 : }
   10702                 : 
   10703                 : NS_IMETHODIMP
   10704               0 : nsGlobalModalWindow::GetReturnValue(nsIVariant **aRetVal)
   10705                 : {
   10706               0 :   FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(GetReturnValue, (aRetVal), NS_OK);
   10707                 : 
   10708               0 :   NS_IF_ADDREF(*aRetVal = mReturnValue);
   10709                 : 
   10710               0 :   return NS_OK;
   10711                 : }
   10712                 : 
   10713                 : NS_IMETHODIMP
   10714               0 : nsGlobalModalWindow::SetReturnValue(nsIVariant *aRetVal)
   10715                 : {
   10716               0 :   FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(SetReturnValue, (aRetVal), NS_OK);
   10717                 : 
   10718               0 :   mReturnValue = aRetVal;
   10719                 : 
   10720               0 :   return NS_OK;
   10721                 : }
   10722                 : 
   10723                 : nsresult
   10724               0 : nsGlobalModalWindow::SetNewDocument(nsIDocument *aDocument,
   10725                 :                                     nsISupports *aState,
   10726                 :                                     bool aForceReuseInnerWindow)
   10727                 : {
   10728                 :   // If we're loading a new document into a modal dialog, clear the
   10729                 :   // return value that was set, if any, by the current document.
   10730               0 :   if (aDocument) {
   10731               0 :     mReturnValue = nsnull;
   10732                 :   }
   10733                 : 
   10734                 :   return nsGlobalWindow::SetNewDocument(aDocument, aState,
   10735               0 :                                         aForceReuseInnerWindow);
   10736                 : }
   10737                 : 
   10738                 : void
   10739               0 : nsGlobalWindow::SetHasAudioAvailableEventListeners()
   10740                 : {
   10741               0 :   if (mDoc) {
   10742               0 :     mDoc->NotifyAudioAvailableListener();
   10743                 :   }
   10744               0 : }
   10745                 : 
   10746                 : //*****************************************************************************
   10747                 : // nsGlobalWindow: Creator Function (This should go away)
   10748                 : //*****************************************************************************
   10749                 : 
   10750                 : nsresult
   10751               0 : NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow,
   10752                 :                          nsIScriptGlobalObject **aResult)
   10753                 : {
   10754               0 :   *aResult = nsnull;
   10755                 : 
   10756                 :   nsGlobalWindow *global;
   10757                 : 
   10758               0 :   if (aIsChrome) {
   10759               0 :     global = new nsGlobalChromeWindow(nsnull);
   10760               0 :   } else if (aIsModalContentWindow) {
   10761               0 :     global = new nsGlobalModalWindow(nsnull);
   10762                 :   } else {
   10763               0 :     global = new nsGlobalWindow(nsnull);
   10764                 :   }
   10765                 : 
   10766               0 :   NS_ENSURE_TRUE(global, NS_ERROR_OUT_OF_MEMORY);
   10767                 : 
   10768               0 :   NS_ADDREF(*aResult = global);
   10769                 : 
   10770               0 :   return NS_OK;
   10771                 : }
   10772                 : 
   10773                 : #define EVENT(name_, id_, type_, struct_)                                    \
   10774                 :   NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx,                  \
   10775                 :                                              jsval *vp) {                    \
   10776                 :     nsEventListenerManager *elm = GetListenerManager(false);              \
   10777                 :     if (elm) {                                                               \
   10778                 :       elm->GetJSEventListener(nsGkAtoms::on##name_, vp);                     \
   10779                 :     } else {                                                                 \
   10780                 :       *vp = JSVAL_NULL;                                                      \
   10781                 :     }                                                                        \
   10782                 :     return NS_OK;                                                            \
   10783                 :   }                                                                          \
   10784                 :   NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx,                  \
   10785                 :                                              const jsval &v) {               \
   10786                 :     nsEventListenerManager *elm = GetListenerManager(true);               \
   10787                 :     if (!elm) {                                                              \
   10788                 :       return NS_ERROR_OUT_OF_MEMORY;                                         \
   10789                 :     }                                                                        \
   10790                 :                                                                              \
   10791                 :     JSObject *obj = mJSObject;                                               \
   10792                 :     if (!obj) {                                                              \
   10793                 :       return NS_ERROR_UNEXPECTED;                                            \
   10794                 :     }                                                                        \
   10795                 :     return elm->SetJSEventListenerToJsval(nsGkAtoms::on##name_, cx, obj, v); \
   10796                 :   }
   10797                 : #define WINDOW_ONLY_EVENT EVENT
   10798                 : #define TOUCH_EVENT EVENT
   10799                 : #include "nsEventNameList.h"
   10800                 : #undef TOUCH_EVENT
   10801                 : #undef WINDOW_ONLY_EVENT
   10802                 : #undef EVENT
   10803                 : 

Generated by: LCOV version 1.7