nsCOMPtr<nsIDocShellTreeItem> item; PRInt32 itemIndex = 0; while (NS_SUCCEEDED(shEntry->ChildShellAt(itemIndex++, getter_AddRefs(item))) && item) { DetachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item))); }
DocumentViewerImpl::Destroy(){  NS_ASSERTION(mDocument, "No document in Destroy()!");#ifdef NS_PRINTING  // Here is where we check to see if the docment was still being prepared   // for printing when it was asked to be destroy from someone externally  // This usually happens if the document is unloaded while the user is in the Print Dialog  //  // So we flip the bool to remember that the document is going away  // and we can clean up and abort later after returning from the Print Dialog  if (mPrintEngine) {    if (mPrintEngine->CheckBeforeDestroy()) {      return NS_OK;    }  }#endif  // Don't let the document get unloaded while we are printing.  // this could happen if we hit the back button during printing.  // We also keep the viewer from being cached in session history, since  // we require all documents there to be sanitized.  if (mDestroyRefCount != 0) {    --mDestroyRefCount;    return NS_OK;  }  // If we were told to put ourselves into session history instead of destroy  // the presentation, do that now.  if (mSHEntry) {    if (mPresShell)      mPresShell->Freeze();    // Make sure the presentation isn't torn down by Hide().    mSHEntry->SetSticky(mIsSticky);    mIsSticky = PR_TRUE;    PRBool savePresentation = PR_TRUE;    // Remove our root view from the view hierarchy.    if (mPresShell) {      nsIViewManager *vm = mPresShell->GetViewManager();      if (vm) {        nsIView *rootView = nsnull;        vm->GetRootView(rootView);        if (rootView) {          nsIView *rootViewParent = rootView->GetParent();          if (rootViewParent) {            nsIViewManager *parentVM = rootViewParent->GetViewManager();            if (parentVM) {              parentVM->RemoveChild(rootView);            }          }        }      }    }    Hide();    // This is after Hide() so that the user doesn't see the inputs clear.    if (mDocument) {      nsresult rv = mDocument->Sanitize();      if (NS_FAILED(rv)) {        // If we failed to sanitize, don't save presentation.        savePresentation = PR_FALSE;      }    }    // Reverse ownership. Do this *after* calling sanitize so that sanitize    // doesn't cause mutations that make the SHEntry drop the presentation    if (savePresentation) {      mSHEntry->SetContentViewer(this);    }    else {      mSHEntry->SyncPresentationState();    }    mSHEntry = nsnull;    // Break the link from the document/presentation to the docshell, so that    // link traversals cannot affect the currently-loaded document.    // When the presentation is restored, Open() and InitInternal() will reset    // these pointers to their original values.    if (mDocument)      mDocument->SetContainer(nsnull);    if (mPresContext) {      mPresContext->SetLinkHandler(nsnull);      mPresContext->SetContainer(nsnull);    }    if (mPresShell)      mPresShell->SetForwardingContainer(mContainer);    return NS_OK;  }  if (mDocument) {    mDocument->Destroy();    mDocument = nsnull;  }  // All callers are supposed to call destroy to break circular  // references.  If we do this stuff in the destructor, the  // destructor might never be called (especially if we're being  // used from JS.#ifdef NS_PRINTING  if (mPrintEngine) {    mPrintEngine->Destroy();    NS_RELEASE(mPrintEngine);  }#endif  // Avoid leaking the old viewer.  if (mPreviousViewer) {    mPreviousViewer->Destroy();    mPreviousViewer = nsnull;  }  if (mDeviceContext) {    mDeviceContext->FlushFontCache();    mDeviceContext = nsnull;  }  if (mPresShell) {    // Break circular reference (or something)    mPresShell->EndObservingDocument();    nsCOMPtr<nsISelection> selection;    GetDocumentSelection(getter_AddRefs(selection));    nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));    if (selPrivate && mSelectionListener)      selPrivate->RemoveSelectionListener(mSelectionListener);    mPresShell->Destroy();    mPresShell = nsnull;  }  if (mPresContext) {    mPresContext->SetContainer(nsnull);    mPresContext->SetLinkHandler(nsnull);    mPresContext = nsnull;  }  mContainer = nsnull;  return NS_OK;}