From e833d177d8bb92a364f217859f88527125527f02 Mon Sep 17 00:00:00 2001 From: "radha%netscape.com" Date: Fri, 26 Oct 2001 19:04:11 +0000 Subject: [PATCH] Fix for bug # 103978. Problems with back/forward at cnn.com, mainly due to expired subframes and clicking back/forward fast. r=adamlock sr=rpotts --- docshell/base/nsDocShell.cpp | 83 +++++++++++++-------- docshell/base/nsDocShell.h | 3 - docshell/base/nsIDocShell.idl | 5 ++ xpfe/components/shistory/src/nsSHistory.cpp | 4 +- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 89a592a4c70..9ebbff94f23 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -497,34 +497,40 @@ nsDocShell::LoadURI(nsIURI * aURI, #endif if (!shEntry && loadType != LOAD_NORMAL_REPLACE && mCurrentURI == nsnull) { - /* Check if we are in the middle of loading a subframe whose parent - * was originally loaded thro' Session History. ie., you were in a frameset - * page, went somewhere else and clicked 'back'. The loading of the root page - * is done and we are currently loading one of its children or sub-children. + /* OK. We are in the process of loading a subframe. Checkout the + * parent's loadtype. If the parent was loaded thro' a history + * mechanism, then get the SH entry for the child from the parent. + * This is done to restore frameset navigation while going back/forward. + * If the parent was not loaded thro' any history mechanism, we don't + * have to do this, since we have nothing to restore. */ + + // get the parent nsCOMPtr parentAsItem; GetSameTypeParent(getter_AddRefs(parentAsItem)); - // Try to get your SHEntry from your parent - if (parentAsItem) { - nsCOMPtr - parent(do_QueryInterface(parentAsItem)); + nsCOMPtr parentDS(do_QueryInterface(parentAsItem)); + PRUint32 parentLoadType; - // XXX: Should we care if this QI fails? - if (parent) { - parent->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry)); - if (shEntry) { - //Get the proper loadType from the SHEntry. - PRUint32 lt; - shEntry->GetLoadType(<); - // Convert the DocShellInfoLoadType returned by the - // previous function to loadType - loadType = - ConvertDocShellLoadInfoToLoadType((nsDocShellInfoLoadType) lt); - } - } - } - } + if (parentDS) { + // Get the parent's load type + parentDS->GetLoadType(&parentLoadType); + + /* Try to get the SHEntry for this subframe from the parent, + * only if the parent was loaded thro' a history mechanism, + * like back/forward/go/reload + */ + if (parentAsItem && (parentLoadType & LOAD_CMD_HISTORY) || (parentLoadType & LOAD_CMD_RELOAD)) { + nsCOMPtr parent(do_QueryInterface(parentAsItem)); + if (parent) { + // Get the ShEntry for the child from the parent + parent->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry)); + if (shEntry) + loadType = parentLoadType; + } // parent + } + } //parentDS + } // !shEntry if (shEntry) { // Load is from SH. SH does normal load only @@ -1977,32 +1983,37 @@ nsDocShell::GetChildSHEntry(PRInt32 aChildOffset, nsISHEntry ** aResult) // A nsISHEntry for a child is *only* available when the parent is in // the progress of loading a document too... - // + if (mLSHE) { /* Before looking for the subframe's url, check * the expiration status of the parent. If the parent * has expired from cache, then subframes will not be - * loaded from history. The whole page will be loaded - * fresh from the server. + * loaded from history in certain situations. */ PRBool parentExpired=PR_FALSE; mLSHE->GetExpirationStatus(&parentExpired); - if (parentExpired) { - // The parent has expired. Return null. - *aResult = nsnull; - return rv; - } + /* Get the parent's Load Type so that it can be set on the child too. * By default give a loadHistory value */ PRUint32 loadType = nsIDocShellLoadInfo::loadHistory; - mLSHE->GetLoadType(&loadType); + mLSHE->GetLoadType(&loadType); // If the user did a shift-reload on this frameset page, // we don't want to load the subframes from history. if (loadType == nsIDocShellLoadInfo::loadReloadBypassCache || loadType == nsIDocShellLoadInfo::loadReloadBypassProxy || loadType == nsIDocShellLoadInfo::loadReloadBypassProxyAndCache) return rv; + + /* If the user pressed reload and the parent frame has expired + * from cache, we do not want to load the child frame from history. + */ + if (parentExpired && (loadType == nsIDocShellLoadInfo::loadReloadNormal)) { + // The parent has expired. Return null. + *aResult = nsnull; + return rv; + } + nsCOMPtr container(do_QueryInterface(mLSHE)); if (container) { // Get the child subframe from session history. @@ -5504,13 +5515,19 @@ nsDocShell::GetLoadCookie(nsISupports ** aResult) return NS_OK; } -nsresult +NS_IMETHODIMP nsDocShell::SetLoadType(PRUint32 aLoadType) { mLoadType = aLoadType; return NS_OK; } +NS_IMETHODIMP +nsDocShell::GetLoadType(PRUint32 * aLoadType) +{ + *aLoadType = mLoadType; + return NS_OK; +} nsDocShellInitInfo * nsDocShell::InitInfo() diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index c80f69e1456..091c86a683d 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -189,9 +189,6 @@ public: nsresult SetLoadCookie(nsISupports * aCookie); nsresult GetLoadCookie(nsISupports ** aResult); - // used when the docshell gets content that's being redirected (so we don't go through - // our own InternalLoad method) to reset the load type... - nsresult SetLoadType(PRUint32 aLoadType); nsDocShellInfoLoadType ConvertLoadTypeToDocShellLoadInfo(PRUint32 aLoadType); PRUint32 ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType); diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 3871fe4fcc7..73d45cc7a74 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -272,5 +272,10 @@ interface nsIDocShell : nsISupports const unsigned long BUSY_FLAGS_PAGE_LOADING = 4; readonly attribute unsigned long busyFlags; + + /* + * attribute to access the loadtype for the document + */ + attribute unsigned long loadType; }; diff --git a/xpfe/components/shistory/src/nsSHistory.cpp b/xpfe/components/shistory/src/nsSHistory.cpp index bee6f2b9d24..48d69c98ace 100644 --- a/xpfe/components/shistory/src/nsSHistory.cpp +++ b/xpfe/components/shistory/src/nsSHistory.cpp @@ -531,7 +531,8 @@ NS_IMETHODIMP nsSHistory::UpdateIndex() { // Update the actual index with the right value. - mIndex = mRequestedIndex; + if (mIndex != mRequestedIndex && mRequestedIndex != -1) + mIndex = mRequestedIndex; return NS_OK; } @@ -706,6 +707,7 @@ nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType, PRUint32 aHistCmd) } + PRBool nsSHistory::CompareSHEntry(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsIDocShell * aParent, nsIDocShell ** aDSResult, nsISHEntry ** aSHEResult)