From 331cadb8136b4f045b98f93363f1642b0acff66d Mon Sep 17 00:00:00 2001 From: "bryner%brianryner.com" Date: Fri, 24 Jun 2005 20:53:43 +0000 Subject: [PATCH] Fix pending-loads check for fastback so that we detect loads initiated either before or after Stop() is called. Fix assert on reload. Fix problem where the wrong load type was being checked in CanSavePresentation(). Fix problem where we cached a content viewer on the current history entry when it was equal to the new history entry. Bugs 292954 and 292950. r+sr=darin, a=asa. git-svn-id: svn://10.0.0.236/trunk@175110 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/docshell/base/nsDocShell.cpp | 46 ++++++++++++++++++---------- mozilla/docshell/base/nsDocShell.h | 14 ++++++--- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index b24a1ddd5ee..dbe4331493e 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -4799,7 +4799,7 @@ nsDocShell::CreateAboutBlankContentViewer() } PRBool -nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) +nsDocShell::CanSavePresentation(PRUint32 aLoadType, nsIRequest *aNewRequest) { if (!mOSHE) return PR_FALSE; // no entry to save into @@ -4807,9 +4807,9 @@ nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) // Only save presentation for "normal" loads and link loads. Anything else // probably wants to refetch the page, so caching the old presentation // would be incorrect. - if (mLoadType != LOAD_NORMAL && - mLoadType != LOAD_HISTORY && - mLoadType != LOAD_LINK) + if (aLoadType != LOAD_NORMAL && + aLoadType != LOAD_HISTORY && + aLoadType != LOAD_LINK) return PR_FALSE; // If the session history entry has the saveLayoutState flag set to false, @@ -4842,8 +4842,13 @@ nsDocShell::CanSavePresentation(nsIRequest *aNewRequest) nsresult nsDocShell::CaptureState() { + if (!mOSHE || mOSHE == mLSHE) { + // No entry to save into, or we're replacing the existing entry. + return NS_ERROR_FAILURE; + } + nsCOMPtr privWin = do_QueryInterface(mScriptGlobal); - if (!privWin || !mOSHE) + if (!privWin) return NS_ERROR_FAILURE; nsCOMPtr windowState; @@ -5098,7 +5103,7 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, PRBool aSavePresentation, printf("No valid container, clearing presentation\n"); #endif aSHEntry->SetContentViewer(nsnull); - return NS_OK; + return NS_ERROR_FAILURE; } NS_ASSERTION(mContentViewer != viewer, "Restoring existing presentation"); @@ -5357,8 +5362,15 @@ nsDocShell::CreateContentViewer(const char *aContentType, // wrong information :-( // - PRBool savePresentation = CanSavePresentation(request); - FirePageHideNotification(!savePresentation); + if (mSavingOldViewer) { + // We determined that it was safe to cache the document presentation + // at the time we initiated the new load. We need to check whether + // it's still safe to do so, since there may have been DOM mutations + // or new requests initiated. + mSavingOldViewer = CanSavePresentation(mLoadType, request); + } + + FirePageHideNotification(!mSavingOldViewer); // Set mFiredUnloadEvent = PR_FALSE so that the unload handler for the // *new* document will fire. @@ -5373,8 +5385,6 @@ nsDocShell::CreateContentViewer(const char *aContentType, PRBool onLocationChangeNeeded = OnLoadingSite(aOpenedChannel, PR_FALSE); - mSavingOldViewer = savePresentation; - // let's try resetting the load group if we need to... nsCOMPtr currentLoadGroup; NS_ENSURE_SUCCESS(aOpenedChannel-> @@ -6242,7 +6252,7 @@ nsDocShell::InternalLoad(nsIURI * aURI, // This is necessary so that we can catch any pending requests. // Since the new request has not been created yet, we pass null for the // new request parameter. - PRBool savePresentation = CanSavePresentation(nsnull); + PRBool savePresentation = CanSavePresentation(aLoadType, nsnull); // Don't stop current network activity for javascript: URL's since // they might not result in any data, and thus nothing should be @@ -6278,23 +6288,25 @@ nsDocShell::InternalLoad(nsIURI * aURI, // mLSHE should be assigned to aSHEntry, only after Stop() has // been called. mLSHE = aSHEntry; + mSavingOldViewer = savePresentation; // If we have a saved content viewer in history, restore and show it now. - if (aSHEntry) { + if (aSHEntry && (mLoadType & LOAD_CMD_HISTORY)) { nsCOMPtr oldEntry = mOSHE; PRBool restored; - rv = RestorePresentation(aSHEntry, savePresentation && - NS_SUCCEEDED(rv), &restored); + rv = RestorePresentation(aSHEntry, savePresentation, &restored); if (restored) return rv; // We failed to restore the presentation, so clean up. // Both the old and new history entries could potentially be in // an inconsistent state. - if (oldEntry) - oldEntry->SyncPresentationState(); + if (NS_FAILED(rv)) { + if (oldEntry) + oldEntry->SyncPresentationState(); - aSHEntry->SyncPresentationState(); + aSHEntry->SyncPresentationState(); + } } nsCOMPtr req; diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index 4b1c4699a37..b8373475faa 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -424,9 +424,12 @@ protected: // Determines whether we can safely cache the current mContentViewer in // session history. This checks a number of factors such as cache policy, - // pending requests, and unload handlers. |aNewRequest| should be the - // request for the document to be loaded in place of the current document. - PRBool CanSavePresentation(nsIRequest *aNewRequest); + // pending requests, and unload handlers. + // |aLoadType| should be the load type that will replace the current + // presentation. |aNewRequest| should be the request for the document to + // be loaded in place of the current document, or null if such a request + // has not been created yet. + PRBool CanSavePresentation(PRUint32 aLoadType, nsIRequest *aNewRequest); // Captures the state of the supporting elements of the presentation // (the "window" object, docshell tree, meta-refresh loads, and security @@ -471,8 +474,9 @@ protected: // Indicates that a DocShell in this "docshell tree" is printing PRPackedBool mIsPrintingOrPP; - // Indicates to SetupNewViewer() that we are in the process of saving the - // presentation for mContentViewer. + // Indicates to CreateContentViewer() that it is safe to cache the old + // presentation of the page, and to SetupNewViewer() that the old viewer + // should be passed a SHEntry to save itself into. PRPackedBool mSavingOldViewer; PRUint32 mAppType;