зеркало из https://github.com/mozilla/pjs.git
Fix for bug # 108041. Session history misbehaves when _top is replaced after a series of subframe navigations. r=adamlock sr=rpotts.
This commit is contained in:
Родитель
a5b157d438
Коммит
4121680bfe
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
|
|
@ -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
|
||||
//*****************************************************************************
|
||||
|
|
Загрузка…
Ссылка в новой задаче