Bug 429172. Return the docshell's script global object as soon as the document's content viewer has been Closed(). r+sr=sicking,a=beltzner
authorroc+@cs.cmu.edu
Fri, 18 Apr 2008 03:02:03 -0700
changeset 14469 df88a5a126900accc6ba234b22c6a3576071f084
parent 14468 c60df3cab31eaaf2f2432249d6efcdd9306be32a
child 14470 a80678978911e76397ac0d85893fb7e5e6e76792
push id14
push userbsmedberg@mozilla.com
push dateTue, 29 Apr 2008 14:30:10 +0000
treeherdermozilla-central@78e482f2d4be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbeltzner
bugs429172
milestone1.9pre
Bug 429172. Return the docshell's script global object as soon as the document's content viewer has been Closed(). r+sr=sicking,a=beltzner
content/base/public/nsIDocument.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
layout/base/nsDocumentViewer.cpp
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -92,18 +92,18 @@ class nsIDocumentObserver;
 class nsBindingManager;
 class nsIDOMNodeList;
 class mozAutoSubtreeModified;
 struct JSObject;
 class nsFrameLoader;
 
 // IID for the nsIDocument interface
 #define NS_IDOCUMENT_IID      \
-{ 0xaa79d9ba, 0x73a3, 0x42af, \
-  { 0xad, 0xb0, 0x3a, 0x57, 0xe1, 0x8d, 0xa8, 0xa2 } }
+{ 0x680f5dac, 0x8863, 0x4c80, \
+  { 0xbb, 0xe4, 0x21, 0x35, 0xbd, 0x8f, 0x83, 0x9a } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
@@ -784,17 +784,23 @@ public:
 
   /**
    * Notify the document that its associated ContentViewer is being destroyed.
    * This releases circular references so that the document can go away.
    * Destroy() is only called on documents that have a content viewer.
    */
   virtual void Destroy() = 0;
 
-  virtual void SaveState() = 0;
+  /**
+   * Notify the document that its associated ContentViewer is no longer
+   * the current viewer for the docshell. The document might still
+   * be rendered in "zombie state" until the next document is ready.
+   * The document should save form control state.
+   */
+  virtual void RemovedFromDocShell() = 0;
   
   /**
    * Get the layout history state that should be used to save and restore state
    * for nodes in this document.  This may return null; if that happens state
    * saving and restoration is not possible.
    */
   virtual already_AddRefed<nsILayoutHistoryState> GetLayoutHistoryState() const = 0;
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2548,17 +2548,20 @@ nsDocument::EnsureCatalogStyleSheet(cons
 
 nsIScriptGlobalObject*
 nsDocument::GetScriptGlobalObject() const
 {
    // If we're going away, we've already released the reference to our
    // ScriptGlobalObject.  We can, however, try to obtain it for the
    // caller through our docshell.
 
-   if (mIsGoingAway) {
+   // We actually need to start returning the docshell's script global
+   // object as soon as nsDocumentViewer::Close has called
+   // RemovedFromDocShell on us.
+   if (mRemovedFromDocShell) {
      nsCOMPtr<nsIInterfaceRequestor> requestor =
        do_QueryReferent(mDocumentContainer);
      if (requestor) {
        nsCOMPtr<nsIScriptGlobalObject> globalObject = do_GetInterface(requestor);
        return globalObject;
      }
    }
 
@@ -5575,17 +5578,17 @@ nsDocument::Destroy()
 {
   // The ContentViewer wants to release the document now.  So, tell our content
   // to drop any references to the document so that it can be destroyed.
   if (mIsGoingAway)
     return;
 
   mIsGoingAway = PR_TRUE;
 
-  SaveState();
+  RemovedFromDocShell();
 
   PRUint32 i, count = mChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     mChildren.ChildAt(i)->DestroyContent();
   }
 
   mLayoutHistoryState = nsnull;
 
@@ -5595,22 +5598,22 @@ nsDocument::Destroy()
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
   //     When we start relying on cycle collection again we should remove the
   //     check for mScriptGlobalObject in AddReference.
   delete mContentWrapperHash;
   mContentWrapperHash = nsnull;
 }
 
 void
-nsDocument::SaveState()
-{
-  if (mSavedState)
+nsDocument::RemovedFromDocShell()
+{
+  if (mRemovedFromDocShell)
     return;
 
-  mSavedState = PR_TRUE;
+  mRemovedFromDocShell = PR_TRUE;
 
   PRUint32 i, count = mChildren.ChildCount();
   for (i = 0; i < count; ++i) {
     mChildren.ChildAt(i)->SaveSubtreeState();
   }
 }
 
 already_AddRefed<nsILayoutHistoryState>
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -626,17 +626,17 @@ public:
 
   virtual NS_HIDDEN_(nsresult) Sanitize();
 
   virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
                                                  void *aData);
 
   virtual NS_HIDDEN_(PRBool) CanSavePresentation(nsIRequest *aNewRequest);
   virtual NS_HIDDEN_(void) Destroy();
-  virtual NS_HIDDEN_(void) SaveState();
+  virtual NS_HIDDEN_(void) RemovedFromDocShell();
   virtual NS_HIDDEN_(already_AddRefed<nsILayoutHistoryState>) GetLayoutHistoryState() const;
 
   virtual NS_HIDDEN_(void) BlockOnload();
   virtual NS_HIDDEN_(void) UnblockOnload(PRBool aFireSync);
 
   virtual NS_HIDDEN_(void) AddStyleRelevantLink(nsIContent* aContent, nsIURI* aURI);
   virtual NS_HIDDEN_(void) ForgetLink(nsIContent* aContent);
   virtual NS_HIDDEN_(void) NotifyURIVisitednessChanged(nsIURI* aURI);
@@ -770,18 +770,20 @@ protected:
   nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
   nsRefPtr<nsScriptLoader> mScriptLoader;
   nsDocHeaderData* mHeaderData;
 
   nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
 
   // True if the document has been detached from its content viewer.
   PRPackedBool mIsGoingAway:1;
-  // True if we've already saved form control state
-  PRPackedBool mSavedState:1;
+  // True if our content viewer has been removed from the docshell
+  // (it may still be displayed, but in zombie state). Form control data
+  // has been saved.
+  PRPackedBool mRemovedFromDocShell:1;
   // True if the document is being destroyed.
   PRPackedBool mInDestructor:1;
   // True if the document "page" is not hidden
   PRPackedBool mVisible:1;
   // True if document has ever had script handling object.
   PRPackedBool mHasHadScriptHandlingObject:1;
 
   PRPackedBool mHasWarnedAboutBoxObjects:1;
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -1314,17 +1314,17 @@ DocumentViewerImpl::Close(nsISHEntry *aS
     NS_ADDREF_THIS();
   } else
 #endif
     {
       // out of band cleanup of webshell
       mDocument->SetScriptGlobalObject(nsnull);
 
       if (!mSHEntry)
-        mDocument->SaveState();
+        mDocument->RemovedFromDocShell();
     }
 
   if (mFocusListener && mDocument) {
     mDocument->RemoveEventListenerByIID(mFocusListener,
                                         NS_GET_IID(nsIDOMFocusListener));
   }
 
   return NS_OK;