diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index eeed6e2f815..0fbfae811a2 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -5070,29 +5070,28 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, shouldPersist = ShouldAddToSessionHistory(aURI); - // - // If the entry is being replaced in SH, then just use the - // current entry... - // - if (LOAD_NORMAL_REPLACE == mLoadType) { - // There is no need to go to mSessionHistory and get the entry at - // current index. mOSHE works for subframes and top level docshells. + // Get a handle to the root docshell + nsCOMPtr root; + GetSameTypeRootTreeItem(getter_AddRefs(root)); + /* + * If this is a LOAD_NORMAL_REPLACE in a subframe, we use + * the existing SH entry in the page and replace the url and + * other vitalities. + */ + if (LOAD_NORMAL_REPLACE == mLoadType && (root.get() != NS_STATIC_CAST(nsIDocShellTreeItem *, this))) { + // This is a subframe entry = mOSHE; - // If there are children for this entry destroy them, as they are - // going out of scope. - if (entry) { - nsCOMPtr shContainer(do_QueryInterface(entry)); - if (shContainer) { - PRInt32 childCount = 0; - shContainer->GetChildCount(&childCount); - // Remove all children of this entry - for (PRInt32 i = childCount - 1; i >= 0; i--) { - nsCOMPtr child; - shContainer->GetChildAt(i, getter_AddRefs(child)); - shContainer->RemoveChild(child); - } - } - } + nsCOMPtr shContainer(do_QueryInterface(entry)); + if (shContainer) { + PRInt32 childCount = 0; + shContainer->GetChildCount(&childCount); + // Remove all children of this entry + for (PRInt32 i = childCount - 1; i >= 0; i--) { + nsCOMPtr child; + shContainer->GetChildAt(i, getter_AddRefs(child)); + shContainer->RemoveChild(child); + } // for + } // shContainer } // Create a new entry if necessary. @@ -5175,6 +5174,18 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, else rv = AddChildSHEntry(nsnull, entry, mChildOffset); } + else { + if (root.get() == NS_STATIC_CAST(nsIDocShellTreeItem *, this) && mSessionHistory) { + // It is a LOAD_NORMAL_REPLACE on the root docshell + PRInt32 index = 0; + nsCOMPtr hEntry; + mSessionHistory->GetIndex(&index); + nsCOMPtr shPrivate(do_QueryInterface(mSessionHistory)); + // Replace the current entry with the new entry + if (shPrivate) + rv = shPrivate->ReplaceEntry(index, entry); + } + } // Return the new SH entry... if (aNewEntry) { diff --git a/xpfe/components/shistory/public/nsISHistoryInternal.idl b/xpfe/components/shistory/public/nsISHistoryInternal.idl index a62b3d16e5c..74f0bb02630 100644 --- a/xpfe/components/shistory/public/nsISHistoryInternal.idl +++ b/xpfe/components/shistory/public/nsISHistoryInternal.idl @@ -77,4 +77,11 @@ interface nsISHistoryInternal: nsISupports */ void updateIndex(); + /** + * Replace the nsISHEntry at a particular index + * @param aIndex - The index at which the entry shoud be replaced + * @param aReplaceEntry - The replacement entry for the index. + */ + void replaceEntry(in long aIndex, in nsISHEntry aReplaceEntry); + }; diff --git a/xpfe/components/shistory/src/nsSHistory.cpp b/xpfe/components/shistory/src/nsSHistory.cpp index 48d69c98ace..900e512271d 100644 --- a/xpfe/components/shistory/src/nsSHistory.cpp +++ b/xpfe/components/shistory/src/nsSHistory.cpp @@ -420,6 +420,31 @@ nsSHistory::RemoveSHistoryListener(nsISHistoryListener * aListener) return NS_ERROR_FAILURE; } + +/* Replace an entry in the History list at a particular index. + * Do not update index or count. + */ +NS_IMETHODIMP +nsSHistory::ReplaceEntry(PRInt32 aIndex, nsISHEntry * aReplaceEntry) +{ + NS_ENSURE_ARG(aReplaceEntry); + nsresult rv; + nsCOMPtr currentTxn; + + if (!mListRoot) // Session History is not initialised. + return NS_ERROR_FAILURE; + + rv = GetTransactionAtIndex(aIndex, getter_AddRefs(currentTxn)); + + if(currentTxn) + { + // Set the replacement entry in the transaction + rv = currentTxn->SetSHEntry(aReplaceEntry); + rv = currentTxn->SetPersist(PR_TRUE); + } + return rv; +} + //***************************************************************************** // nsSHistory: nsIWebNavigation //*****************************************************************************