Fix for bug # 108041. Session history misbehaves when _top is replaced after a series of subframe navigations. r=adamlock sr=rpotts.

git-svn-id: svn://10.0.0.236/trunk@107512 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
radha%netscape.com
2001-11-06 23:56:45 +00:00
parent 73de839dd7
commit 9c70ff699d
3 changed files with 65 additions and 22 deletions

View File

@@ -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<nsIDocShellTreeItem> 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<nsISHContainer> 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<nsISHEntry> child;
shContainer->GetChildAt(i, getter_AddRefs(child));
shContainer->RemoveChild(child);
}
}
}
nsCOMPtr<nsISHContainer> 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<nsISHEntry> 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<nsIHistoryEntry> hEntry;
mSessionHistory->GetIndex(&index);
nsCOMPtr<nsISHistoryInternal> 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) {

View File

@@ -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);
};

View File

@@ -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<nsISHTransaction> 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
//*****************************************************************************