Bug 629559. Clone child session history entries on anchor navigation. r=dtownsend,smaug

This commit is contained in:
Boris Zbarsky
2011-03-30 13:40:48 -04:00
parent 0801e6b3bd
commit 8c51a4c6ef
7 changed files with 264 additions and 22 deletions

View File

@@ -3323,7 +3323,8 @@ nsDocShell::GetChildSHEntry(PRInt32 aChildOffset, nsISHEntry ** aResult)
NS_IMETHODIMP
nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
PRInt32 aChildOffset, PRUint32 loadType)
PRInt32 aChildOffset, PRUint32 loadType,
PRBool aCloneChildren)
{
nsresult rv;
@@ -3367,8 +3368,7 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
nsCOMPtr<nsISHEntry> nextEntry;
aCloneRef->GetID(&cloneID);
rv = CloneAndReplace(currentEntry, this, cloneID, aNewEntry,
loadType == LOAD_PUSHSTATE,
getter_AddRefs(nextEntry));
aCloneChildren, getter_AddRefs(nextEntry));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISHistoryInternal>
@@ -3384,14 +3384,15 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
do_QueryInterface(GetAsSupports(mParent), &rv);
if (parent) {
rv = parent->AddChildSHEntry(aCloneRef, aNewEntry, aChildOffset,
loadType);
loadType, aCloneChildren);
}
}
return rv;
}
nsresult
nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset)
nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset,
PRBool aCloneChildren)
{
/* You will get here when you are in a subframe and
* a new url has been loaded on you.
@@ -3412,7 +3413,8 @@ nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, PRInt32 aChildOffset)
nsCOMPtr<nsIDocShellHistory> parent =
do_QueryInterface(GetAsSupports(mParent), &rv);
if (parent) {
rv = parent->AddChildSHEntry(mOSHE, aNewEntry, aChildOffset, mLoadType);
rv = parent->AddChildSHEntry(mOSHE, aNewEntry, aChildOffset, mLoadType,
aCloneChildren);
}
@@ -5885,7 +5887,9 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest,
// This is a document.write(). Get the made-up url
// from the channel and store it in session history.
rv = AddToSessionHistory(uri, wcwgChannel, nsnull,
// Pass false for aCloneChildren, since we're creating
// a new DOM here.
rv = AddToSessionHistory(uri, wcwgChannel, nsnull, PR_FALSE,
getter_AddRefs(mLSHE));
SetCurrentURI(uri, aRequest, PR_TRUE);
// Save history state of the previous page
@@ -7432,7 +7436,8 @@ nsDocShell::CreateContentViewer(const char *aContentType,
OnLoadingSite(failedChannel, PR_TRUE, PR_FALSE);
} else if (failedURI) {
mURIResultedInDocument = PR_TRUE;
OnNewURI(failedURI, nsnull, nsnull, mLoadType, PR_TRUE, PR_FALSE);
OnNewURI(failedURI, nsnull, nsnull, mLoadType, PR_TRUE, PR_FALSE,
PR_FALSE);
}
// Be sure to have a correct mLSHE, it may have been cleared by
@@ -8325,7 +8330,10 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (mOSHE) {
mOSHE->GetOwner(getter_AddRefs(owner));
}
OnNewURI(aURI, nsnull, owner, mLoadType, PR_TRUE, PR_TRUE);
// Pass true for aCloneSHChildren, since we're not
// changing documents here, so all of our subframes are
// still relevant to the new session history entry.
OnNewURI(aURI, nsnull, owner, mLoadType, PR_TRUE, PR_TRUE, PR_TRUE);
nsCOMPtr<nsIInputStream> postData;
PRUint32 pageIdent = PR_UINT32_MAX;
@@ -9295,7 +9303,7 @@ nsDocShell::SetupReferrerFromChannel(nsIChannel * aChannel)
PRBool
nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
PRUint32 aLoadType, PRBool aFireOnLocationChange,
PRBool aAddToGlobalHistory)
PRBool aAddToGlobalHistory, PRBool aCloneSHChildren)
{
NS_PRECONDITION(aURI, "uri is null");
NS_PRECONDITION(!aChannel || !aOwner, "Shouldn't have both set");
@@ -9466,7 +9474,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
*.Create a Entry for it and add it to SH, if this is the
* rootDocShell
*/
(void) AddToSessionHistory(aURI, aChannel, aOwner,
(void) AddToSessionHistory(aURI, aChannel, aOwner, aCloneSHChildren,
getter_AddRefs(mLSHE));
}
@@ -9522,8 +9530,9 @@ nsDocShell::OnLoadingSite(nsIChannel * aChannel, PRBool aFireOnLocationChange,
NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, PR_FALSE);
// Pass false for aCloneSHChildren, since we're loading a new page here.
return OnNewURI(uri, aChannel, nsnull, mLoadType, aFireOnLocationChange,
aAddToGlobalHistory);
aAddToGlobalHistory, PR_FALSE);
}
@@ -9781,7 +9790,9 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
GetCurScrollPos(ScrollOrientation_Y, &cy);
mOSHE->SetScrollPosition(cx, cy);
rv = AddToSessionHistory(newURI, nsnull, nsnull,
// Since we're not changing which page we have loaded, pass
// true for aCloneChildren.
rv = AddToSessionHistory(newURI, nsnull, nsnull, PR_TRUE,
getter_AddRefs(newSHEntry));
NS_ENSURE_SUCCESS(rv, rv);
@@ -9876,7 +9887,8 @@ nsDocShell::ShouldAddToSessionHistory(nsIURI * aURI)
nsresult
nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
nsISupports* aOwner, nsISHEntry ** aNewEntry)
nsISupports* aOwner, PRBool aCloneChildren,
nsISHEntry ** aNewEntry)
{
NS_PRECONDITION(aURI, "uri is null");
NS_PRECONDITION(!aChannel || !aOwner, "Shouldn't have both set");
@@ -10004,9 +10016,9 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
if (root == static_cast<nsIDocShellTreeItem *>(this) && mSessionHistory) {
// Bug 629559: Detect if this is an anchor navigation and clone the
// session history in that case too
if (mLoadType == LOAD_PUSHSTATE && mOSHE) {
// If we need to clone our children onto the new session
// history entry, do so now.
if (aCloneChildren && mOSHE) {
PRUint32 cloneID;
mOSHE->GetID(&cloneID);
nsCOMPtr<nsISHEntry> newEntry;
@@ -10042,7 +10054,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
// This is a subframe.
if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType,
LOAD_FLAGS_REPLACE_HISTORY))
rv = DoAddChildSHEntry(entry, mChildOffset);
rv = DoAddChildSHEntry(entry, mChildOffset, aCloneChildren);
}
// Return the new SH entry...