Bug 585224 - Move the location object to the inner window (though still parenting the JS object to the outer). r=jst
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 06 Aug 2010 17:17:33 -0700
changeset 50477 ed744bdf2aaa48b0b0f39df9e8f5d9ca6f173d24
parent 50476 0486278c8eea75631ff4cef9608ea4a44444daf0
child 50478 6d977009d79f814b27c755a075737e4e8765a7ba
child 50481 e66ff070ccfaf45bc3d9475d99be97cec943654d
push idunknown
push userunknown
push dateunknown
reviewersjst
bugs585224
milestone2.0b4pre
Bug 585224 - Move the location object to the inner window (though still parenting the JS object to the outer). r=jst
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -921,17 +921,17 @@ nsGlobalWindow::CleanUp(PRBool aIgnoreMo
       return;
     }
   }
 
   // Guarantee idempotence.
   if (mCleanedUp)
     return;
   mCleanedUp = PR_TRUE;
-    
+
   mNavigator = nsnull;
   mScreen = nsnull;
   mHistory = nsnull;
   mMenubar = nsnull;
   mToolbar = nsnull;
   mLocationbar = nsnull;
   mPersonalbar = nsnull;
   mStatusbar = nsnull;
@@ -1072,16 +1072,18 @@ nsGlobalWindow::FreeInnerObjects(PRBool 
 
   mChromeEventHandler = nsnull;
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nsnull;
   }
 
+  mLocation = nsnull;
+
   if (mDocument) {
     NS_ASSERTION(mDoc, "Why is mDoc null?");
 
     // Remember the document's principal.
     mDocumentPrincipal = mDoc->NodePrincipal();
   }
 
 #ifdef DEBUG
@@ -1505,59 +1507,53 @@ class WindowStateHolder : public nsISupp
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(WINDOWSTATEHOLDER_IID)
   NS_DECL_ISUPPORTS
 
   WindowStateHolder(nsGlobalWindow *aWindow,
                     nsIXPConnectJSObjectHolder *aHolder,
                     nsNavigator *aNavigator,
-                    nsLocation *aLocation,
                     nsIXPConnectJSObjectHolder *aOuterProto);
 
   nsGlobalWindow* GetInnerWindow() { return mInnerWindow; }
   nsIXPConnectJSObjectHolder *GetInnerWindowHolder()
   { return mInnerWindowHolder; }
 
   nsNavigator* GetNavigator() { return mNavigator; }
-  nsLocation* GetLocation() { return mLocation; }
   nsIXPConnectJSObjectHolder* GetOuterProto() { return mOuterProto; }
 
   void DidRestoreWindow()
   {
     mInnerWindow = nsnull;
 
     mInnerWindowHolder = nsnull;
     mNavigator = nsnull;
-    mLocation = nsnull;
     mOuterProto = nsnull;
   }
 
 protected:
   ~WindowStateHolder();
 
   nsGlobalWindow *mInnerWindow;
   // We hold onto this to make sure the inner window doesn't go away. The outer
   // window ends up recalculating it anyway.
   nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
   nsRefPtr<nsNavigator> mNavigator;
-  nsRefPtr<nsLocation> mLocation;
   nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterProto;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID)
 
 WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow,
                                      nsIXPConnectJSObjectHolder *aHolder,
                                      nsNavigator *aNavigator,
-                                     nsLocation *aLocation,
                                      nsIXPConnectJSObjectHolder *aOuterProto)
   : mInnerWindow(aWindow),
     mNavigator(aNavigator),
-    mLocation(aLocation),
     mOuterProto(aOuterProto)
 {
   NS_PRECONDITION(aWindow, "null window");
   NS_PRECONDITION(aWindow->IsInnerWindow(), "Saving an outer window");
 
   mInnerWindowHolder = aHolder;
 
   aWindow->SuspendTimeouts();
@@ -1749,17 +1745,16 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
       NS_ASSERTION(wsh, "What kind of weird state are you giving me here?");
 
       newInnerWindow = wsh->GetInnerWindow();
       mInnerWindowHolder = wsh->GetInnerWindowHolder();
 
       // These assignments addref.
       mNavigator = wsh->GetNavigator();
-      mLocation = wsh->GetLocation();
 
       if (mNavigator) {
         // Update mNavigator's docshell pointer now.
         mNavigator->SetDocShell(mDocShell);
         mNavigator->LoadingNewDocument();
       }
     } else {
       if (thisChrome) {
@@ -1768,18 +1763,16 @@ nsGlobalWindow::SetNewDocument(nsIDocume
         isChrome = PR_TRUE;
       } else {
         if (mIsModalContentWindow) {
           newInnerWindow = new nsGlobalModalWindow(this);
         } else {
           newInnerWindow = new nsGlobalWindow(this);
         }
       }
-
-      mLocation = nsnull;
     }
 
     if (!newInnerWindow) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     if (currentInner && currentInner->mJSObject) {
       if (mNavigator && !aState) {
@@ -2186,18 +2179,16 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
     nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsIScriptGlobalObject*>(this));
 #endif
   }
 
   mDocShell = aDocShell;        // Weak Reference
 
   if (mNavigator)
     mNavigator->SetDocShell(aDocShell);
-  if (mLocation)
-    mLocation->SetDocShell(aDocShell);
   if (mHistory)
     mHistory->SetDocShell(aDocShell);
   if (mFrames)
     mFrames->SetDocShell(aDocShell);
   if (mScreen)
     mScreen->SetDocShell(aDocShell);
 
   if (!mDocShell) {
@@ -6806,22 +6797,23 @@ nsGlobalWindow::GetPrivateRoot()
   return static_cast<nsGlobalWindow *>
                     (static_cast<nsIDOMWindow *>(top));
 }
 
 
 NS_IMETHODIMP
 nsGlobalWindow::GetLocation(nsIDOMLocation ** aLocation)
 {
-  FORWARD_TO_OUTER(GetLocation, (aLocation), NS_ERROR_NOT_INITIALIZED);
+  FORWARD_TO_INNER(GetLocation, (aLocation), NS_ERROR_NOT_INITIALIZED);
 
   *aLocation = nsnull;
 
-  if (!mLocation && mDocShell) {
-    mLocation = new nsLocation(mDocShell);
+  nsIDocShell *docShell = GetDocShell();
+  if (!mLocation && docShell) {
+    mLocation = new nsLocation(docShell);
     if (!mLocation) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   NS_IF_ADDREF(*aLocation = mLocation);
 
   return NS_OK;
@@ -9088,17 +9080,16 @@ nsGlobalWindow::SaveWindowState(nsISuppo
   nsresult rv = nsContentUtils::XPConnect()->
     GetWrappedNativePrototype((JSContext *)mContext->GetNativeContext(),
                               mJSObject, ci, getter_AddRefs(proto));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> state = new WindowStateHolder(inner,
                                                       mInnerWindowHolder,
                                                       mNavigator,
-                                                      mLocation,
                                                       proto);
   NS_ENSURE_TRUE(state, NS_ERROR_OUT_OF_MEMORY);
 
 #ifdef DEBUG_PAGE_CACHE
   printf("saving window state, state = %p\n", (void*)state);
 #endif
 
   state.swap(*aState);
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -781,17 +781,16 @@ protected:
   nsRefPtr<nsDOMWindowList>     mFrames;
   nsRefPtr<nsBarProp>           mMenubar;
   nsRefPtr<nsBarProp>           mToolbar;
   nsRefPtr<nsBarProp>           mLocationbar;
   nsRefPtr<nsBarProp>           mPersonalbar;
   nsRefPtr<nsBarProp>           mStatusbar;
   nsRefPtr<nsBarProp>           mScrollbars;
   nsCOMPtr<nsIWeakReference>    mWindowUtils;
-  nsRefPtr<nsLocation>          mLocation;
   nsString                      mStatus;
   nsString                      mDefaultStatus;
   // index 0->language_id 1, so index MAX-1 == language_id MAX
   nsGlobalWindowObserver*       mObserver;
 
   nsCOMPtr<nsIDOMCrypto>        mCrypto;
 
   nsCOMPtr<nsIDOMStorage>      mLocalStorage;
@@ -803,16 +802,17 @@ protected:
 
   // These member variable are used only on inner windows.
   nsCOMPtr<nsIEventListenerManager> mListenerManager;
   PRCList                       mTimeouts;
   // If mTimeoutInsertionPoint is non-null, insertions should happen after it.
   nsTimeout*                    mTimeoutInsertionPoint;
   PRUint32                      mTimeoutPublicIdCounter;
   PRUint32                      mTimeoutFiringDepth;
+  nsRefPtr<nsLocation>          mLocation;
 
   // Holder of the dummy java plugin, used to expose window.java and
   // window.packages.
   nsRefPtr<nsDummyJavaPluginOwner> mDummyJavaPluginOwner;
 
   // These member variables are used on both inner and the outer windows.
   nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
   nsCOMPtr<nsIDocument> mDoc;  // For fast access to principals