Bug 581536 part 0. Change SetDocumentInternal to share the normal prescontext/presshell initialization codepath. r=dbaron
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 21 Jan 2011 14:09:11 -0500
changeset 61100 f12f55c744f4890f9dd89177288ef9cb6349a1d3
parent 61099 49b68a67b57537980d8203dce696392776bbf914
child 61101 f3432e1de08529930142e00a7da7519955ff5e24
push idunknown
push userunknown
push dateunknown
reviewersdbaron
bugs581536
milestone2.0b10pre
Bug 581536 part 0. Change SetDocumentInternal to share the normal prescontext/presshell initialization codepath. r=dbaron
layout/base/nsDocumentViewer.cpp
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -372,22 +372,26 @@ private:
   /**
    * Create our device context
    */
   nsresult CreateDeviceContext(nsIView* aContainerView);
 
   /**
    * If aDoCreation is true, this creates the device context, creates a
    * prescontext if necessary, and calls MakeWindow.
+   *
+   * If aForceSetNewDocument is false, then SetNewDocument won't be
+   * called if the window's current document is already mDocument.
    */
   nsresult InitInternal(nsIWidget* aParentWidget,
                         nsISupports *aState,
                         const nsIntRect& aBounds,
                         PRBool aDoCreation,
-                        PRBool aNeedMakeCX = PR_TRUE);
+                        PRBool aNeedMakeCX = PR_TRUE,
+                        PRBool aForceSetNewDocument = PR_TRUE);
   /**
    * @param aDoInitialReflow set to true if you want to kick off the initial
    * reflow
    */
   nsresult InitPresentationStuff(PRBool aDoInitialReflow);
 
   nsresult GetPopupNode(nsIDOMNode** aNode);
   nsresult GetPopupLinkNode(nsIDOMNode** aNode);
@@ -395,16 +399,17 @@ private:
 
   void PrepareToStartLoad(void);
 
   nsresult SyncParentSubDocMap();
 
   nsresult GetDocumentSelection(nsISelection **aSelection);
 
   void DestroyPresShell();
+  void DestroyPresContext();
 
 #ifdef NS_PRINTING
   // Called when the DocViewer is notified that the state
   // of Printing or PP has changed
   void SetIsPrintingInDocShellTree(nsIDocShellTreeNode* aParentNode, 
                                    PRBool               aIsPrintingOrPP, 
                                    PRBool               aStartAtTop);
 #endif // NS_PRINTING
@@ -827,18 +832,25 @@ CreatePresContext(nsIDocument* aDocument
 // This method can be used to initial the "presentation"
 // The aDoCreation indicates whether it should create
 // all the new objects or just initialize the existing ones
 nsresult
 DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget,
                                  nsISupports *aState,
                                  const nsIntRect& aBounds,
                                  PRBool aDoCreation,
-                                 PRBool aNeedMakeCX /*= PR_TRUE*/)
+                                 PRBool aNeedMakeCX /*= PR_TRUE*/,
+                                 PRBool aForceSetNewDocument /* = PR_TRUE*/)
 {
+  if (mIsPageMode) {
+    // XXXbz should the InitInternal in SetPageMode just pass PR_FALSE
+    // here itself?
+    aForceSetNewDocument = PR_FALSE;
+  }
+
   // We don't want any scripts to run here. That can cause flushing,
   // which can cause reentry into initialization of this document viewer,
   // which would be disastrous.
   nsAutoScriptBlocker blockScripts;
 
   mParentWidget = aParentWidget; // not ref counted
   mBounds = aBounds;
 
@@ -947,17 +959,17 @@ DocumentViewerImpl::InitInternal(nsIWidg
 
     nsCOMPtr<nsPIDOMWindow> window;
     requestor->GetInterface(NS_GET_IID(nsPIDOMWindow),
                             getter_AddRefs(window));
 
     if (window) {
       nsCOMPtr<nsIDocument> curDoc =
         do_QueryInterface(window->GetExtantDocument());
-      if (!mIsPageMode || curDoc != mDocument) {
+      if (aForceSetNewDocument || curDoc != mDocument) {
         window->SetNewDocument(mDocument, aState, PR_FALSE);
         nsJSContext::LoadStart();
       }
     }
   }
 
   if (aDoCreation && mPresContext) {
     // The ViewManager and Root View was created above (in
@@ -1618,19 +1630,17 @@ DocumentViewerImpl::Destroy()
 
   mDeviceContext = nsnull;
 
   if (mPresShell) {
     DestroyPresShell();
   }
 
   if (mPresContext) {
-    mPresContext->SetContainer(nsnull);
-    mPresContext->SetLinkHandler(nsnull);
-    mPresContext = nsnull;
+    DestroyPresContext();
   }
 
   mWindow = nsnull;
   mViewManager = nsnull;
   mContainer = nsnull;
 
   return NS_OK;
 }
@@ -1709,17 +1719,17 @@ DocumentViewerImpl::SetDocumentInternal(
     mDocument = aDocument;
 
     // Set the script global object on the new document
     nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(container);
     if (window) {
       window->SetNewDocument(aDocument, nsnull, aForceReuseInnerWindow);
     }
 
-    // Clear the list of old child docshells. CChild docshells for the new
+    // Clear the list of old child docshells. Child docshells for the new
     // document will be constructed as frames are created.
     if (!aDocument->IsStaticDocument()) {
       nsCOMPtr<nsIDocShellTreeNode> node = do_QueryInterface(container);
       if (node) {
         PRInt32 count;
         node->GetChildCount(&count);
         for (PRInt32 i = 0; i < count; ++i) {
           nsCOMPtr<nsIDocShellTreeItem> child;
@@ -1730,47 +1740,24 @@ DocumentViewerImpl::SetDocumentInternal(
     }
   }
 
   nsresult rv = SyncParentSubDocMap();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Replace the current pres shell with a new shell for the new document
 
-  nsCOMPtr<nsILinkHandler> linkHandler;
   if (mPresShell) {
-    nsSize currentSize(0, 0);
-
-    if (mViewManager) {
-      mViewManager->GetWindowDimensions(&currentSize.width, &currentSize.height);
-    }
-
-    if (mPresContext) {
-      // Save the linkhandler (nsPresShell::Destroy removes it from
-      // mPresContext).
-      linkHandler = mPresContext->GetLinkHandler();
-    }
-
     DestroyPresShell();
-
-    nsIView* containerView = FindContainerView();
-
-    // This destroys the root view because it was associated with the root frame,
-    // which has been torn down. Recreate the viewmanager and root view.
-    MakeWindow(currentSize, containerView);
   }
 
-  // And if we're already given a prescontext...
   if (mPresContext) {
-    // If we had a linkHandler and it got removed, put it back.
-    if (linkHandler) {
-      mPresContext->SetLinkHandler(linkHandler);
-    }
-
-    rv = InitPresentationStuff(PR_FALSE);
+    DestroyPresContext();
+
+    InitInternal(mParentWidget, nsnull, mBounds, PR_TRUE, PR_TRUE, PR_FALSE);
   }
 
   return rv;
 }
 
 nsIPresShell*
 DocumentViewerImpl::GetPresShell()
 {
@@ -2043,21 +2030,18 @@ DocumentViewerImpl::Hide(void)
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
   if (docShell) {
     nsCOMPtr<nsILayoutHistoryState> layoutState;
     mPresShell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE);
   }
 
   DestroyPresShell();
 
-  // Clear weak refs
-  mPresContext->SetContainer(nsnull);
-  mPresContext->SetLinkHandler(nsnull);                             
-
-  mPresContext   = nsnull;
+  DestroyPresContext();
+
   mViewManager   = nsnull;
   mWindow        = nsnull;
   mDeviceContext = nsnull;
   mParentWidget  = nsnull;
 
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
 
   if (base_win && !mAttachedToParent) {
@@ -4225,22 +4209,19 @@ NS_IMETHODIMP DocumentViewerImpl::SetPag
   // reftests that require a paginated context
   mIsPageMode = aPageMode;
 
   if (mPresShell) {
     DestroyPresShell();
   }
 
   if (mPresContext) {
-    mPresContext->SetContainer(nsnull);
-    mPresContext->SetLinkHandler(nsnull);
+    DestroyPresContext();
   }
 
-  mPresShell    = nsnull;
-  mPresContext  = nsnull;
   mViewManager  = nsnull;
   mWindow       = nsnull;
 
   NS_ENSURE_STATE(mDocument);
   if (aPageMode)
   {    
     mPresContext = CreatePresContext(mDocument,
         nsPresContext::eContext_PageLayout, FindContainerView());
@@ -4275,16 +4256,24 @@ DocumentViewerImpl::DestroyPresShell()
   if (selPrivate && mSelectionListener)
     selPrivate->RemoveSelectionListener(mSelectionListener);
 
   nsAutoScriptBlocker scriptBlocker;
   mPresShell->Destroy();
   mPresShell = nsnull;
 }
 
+void
+DocumentViewerImpl::DestroyPresContext()
+{
+  mPresContext->SetContainer(nsnull);
+  mPresContext->SetLinkHandler(nsnull);
+  mPresContext = nsnull;
+}
+
 PRBool
 DocumentViewerImpl::IsInitializedForPrintPreview()
 {
   return mInitializedForPrintPreview;
 }
 
 void
 DocumentViewerImpl::InitializeForPrintPreview()