diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index b5f7a92cff9..f5e78dbf1f5 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -3133,6 +3133,180 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry) return NS_OK; } + +NS_IMETHODIMP +nsDocShell::GetSHEForChild(PRInt32 aChildOffset, nsISHEntry ** aResult) +{ + if (OSHE) { + nsCOMPtr container(do_QueryInterface(OSHE)); + if (container) + return container->GetChildAt(aChildOffset, aResult); + } + return NS_ERROR_FAILURE; + +} + +NS_IMETHODIMP +nsDocShell::GetCurrentSHE(PRInt32 mOffset, nsISHEntry ** aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + + if (LSHE) { + return GetSHEForChild(mOffset, aResult); + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsDocShell::PersistLayoutHistoryState() +{ + nsresult rv; + if (OSHE) { + nsCOMPtr shell; + + rv = GetPresShell(getter_AddRefs(shell)); + if (NS_SUCCEEDED(rv) && shell) { + nsCOMPtr layoutState; + rv = shell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE); + if (NS_SUCCEEDED(rv) && layoutState) { + rv = OSHE->SetLayoutHistoryState(layoutState); + } + } + + } + return rv; +} + +NS_IMETHODIMP +nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry) +{ + nsresult rv; + if (LSHE) { + /* You get here if you are currently building a + * hierarchy ie.,you just visited a frameset page + */ + nsCOMPtr container(do_QueryInterface(LSHE)); + if(container) + rv = container->AddChild(aNewEntry); + + } + else if (mSessionHistory) { + /* You are currently in the rootDocShell. + * You will get here when a subframe has a new url + * to load and you have walked up the tree all the + * way to the top + */ + PRInt32 index=-1; + nsCOMPtr currentEntry; + mSessionHistory->GetIndex(&index); + if (index < 0) + return NS_ERROR_FAILURE; + mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(currentEntry)); + if (currentEntry) { + nsCOMPtr result(do_CreateInstance(NS_SHENTRY_PROGID)); + NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); + rv = CloneAndReplace(currentEntry, aCloneRef, aNewEntry, result); + if (!NS_SUCCEEDED(rv)) + return NS_ERROR_FAILURE; + NS_ENSURE_SUCCESS(mSessionHistory->AddEntry(result, PR_TRUE), + NS_ERROR_FAILURE); + } + } + else { + /* You will get here when you are in a subframe and + * a new url has been loaded on you. + * The OSHE in this subframe will be the previous url's + * OSHE. This OSHE will be used as the identification + * for this subframe in the CloneAndReplace function. + */ + + nsCOMPtr webNav(do_QueryInterface(mParent)); + if (!webNav) + return NS_ERROR_FAILURE; + if (aCloneRef) + webNav->AddChildSHEntry(aCloneRef, aNewEntry); + else + webNav->AddChildSHEntry(OSHE, aNewEntry); + + } + return rv; +} + +NS_IMETHODIMP +nsDocShell::CloneAndReplace(nsISHEntry * src, nsISHEntry * cloneRef, + nsISHEntry * replaceEntry, nsISHEntry * dest) +{ + nsresult result; + if (!src || !replaceEntry || !cloneRef || !dest) + return NS_ERROR_FAILURE; +// NS_ENSURE_ARG_POINTER(dest, NS_ERROR_FAILURE); +// static PRBool firstTime = PR_TRUE; +// static nsISHEntry * rootSHEntry = nsnull; + + if (src == cloneRef) { + // release the original object before assigning a new one. + NS_RELEASE(dest); + dest = replaceEntry; + } + else { + nsCOMPtr uri; + nsCOMPtr postdata; + nsCOMPtr LHS; + PRUnichar * title=nsnull; + nsCOMPtr parent; + + src->GetURI(getter_AddRefs(uri)); + src->GetPostData(getter_AddRefs(postdata)); + src->GetTitle(&title); + src->GetLayoutHistoryState(getter_AddRefs(LHS)); + //XXX Is this correct? parent is a weak ref in nsISHEntry + src->GetParent(getter_AddRefs(parent)); + + // XXX do we care much about valid values for these uri, title etc.... + dest->SetURI(uri); + dest->SetPostData(postdata); + dest->SetLayoutHistoryState(LHS); + dest->SetTitle(title); + dest->SetParent(parent); + } + /* + if (firstTime) { + // Save the root of the hierarchy in the result parameter + rootSHEntry = dest; + firstTime = PR_FALSE; + } + */ + PRInt32 childCount= 0; + + nsCOMPtr srcContainer(do_QueryInterface(src)); + if (!srcContainer) + return NS_ERROR_FAILURE; + nsCOMPtr destContainer(do_QueryInterface(dest)); + if (!destContainer) + return NS_ERROR_FAILURE; + srcContainer->GetChildCount(&childCount); + for(PRInt32 i = 0; i srcChild; + srcContainer->GetChildAt(i, getter_AddRefs(srcChild)); + if (!srcChild) + return NS_ERROR_FAILURE; + nsCOMPtr destChild(do_CreateInstance(NS_SHENTRY_PROGID)); + if (!destChild) + return NS_ERROR_FAILURE; + result = destContainer->AddChild(destChild); + if (!NS_SUCCEEDED(result)) + return result; + result = CloneAndReplace(srcChild, cloneRef, replaceEntry, destChild); + if (!NS_SUCCEEDED(result)) + return result; + } + + + return result; + +} + + //***************************************************************************** // nsDocShell: Global History //***************************************************************************** diff --git a/mozilla/docshell/base/nsDocShell.h b/mozilla/docshell/base/nsDocShell.h index e703dfce01f..d31151ddc11 100644 --- a/mozilla/docshell/base/nsDocShell.h +++ b/mozilla/docshell/base/nsDocShell.h @@ -65,6 +65,7 @@ #include "nsITimerCallback.h" #include "nsIWebNavigation.h" #include "nsIWebProgressListener.h" +#include "nsISHContainer.h" //***************************************************************************** //*** nsRefreshTimer @@ -208,7 +209,10 @@ protected: NS_IMETHOD AddToSessionHistory(nsIURI* aURI, nsIChannel *aChannel); NS_IMETHOD UpdateCurrentSessionHistory(); NS_IMETHOD LoadHistoryEntry(nsISHEntry* aEntry); - + NS_IMETHOD GetCurrentSHE(PRInt32 aChildOffset, nsISHEntry ** aResult); + NS_IMETHOD PersistLayoutHistoryState(); + NS_IMETHOD CloneAndReplace(nsISHEntry * srcEntry, nsISHEntry * aCloneRef, + nsISHEntry * areplaceEntry, nsISHEntry * destEntry); // Global History NS_IMETHOD ShouldAddToGlobalHistory(nsIURI* aURI, PRBool* aShouldAdd); NS_IMETHOD AddToGlobalHistory(nsIURI* aURI); @@ -267,6 +271,14 @@ protected: PRBool mInitialPageLoad; PRBool mAllowPlugins; PRInt32 mViewMode; + + PRInt32 mOffset; // Offset in the parent's child list. + // Reference to the SHEntry for this docshell until the page is destroyed. + // Somebody give me better name + nsCOMPtr OSHE; + // Reference to the SHEntry for this docshell until the page is loaded + // Somebody give me better name + nsCOMPtr LSHE; // this flag is for bug #21358. a docshell may load many urls // which don't result in new documents being created (i.e. a new content viewer) // we want to make sure we don't call a on load event more than once for a given diff --git a/mozilla/docshell/base/nsDocShellLoadInfo.cpp b/mozilla/docshell/base/nsDocShellLoadInfo.cpp index fd4fa1e9da2..514a51acea9 100644 --- a/mozilla/docshell/base/nsDocShellLoadInfo.cpp +++ b/mozilla/docshell/base/nsDocShellLoadInfo.cpp @@ -111,6 +111,20 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetOwner(nsISupports* aOwner) return NS_OK; } +NS_IMETHODIMP nsDocShellLoadInfo::GetSHEntry(nsISHEntry** aSHEntry) +{ + NS_ENSURE_ARG_POINTER(aSHEntry); + + *aSHEntry = mSHEntry; + NS_IF_ADDREF(*aSHEntry); + return NS_OK; +} + +NS_IMETHODIMP nsDocShellLoadInfo::SetSHEntry(nsISHEntry* aSHEntry) +{ + mSHEntry = aSHEntry; + return NS_OK; +} //***************************************************************************** // nsDocShellLoadInfo: Helpers //***************************************************************************** diff --git a/mozilla/docshell/base/nsDocShellLoadInfo.h b/mozilla/docshell/base/nsDocShellLoadInfo.h index 3fc5c8be4bf..6827ca79ca5 100644 --- a/mozilla/docshell/base/nsDocShellLoadInfo.h +++ b/mozilla/docshell/base/nsDocShellLoadInfo.h @@ -31,6 +31,7 @@ // Interfaces Needed #include "nsIDocShellLoadInfo.h" #include "nsIURI.h" +#include "nsISHEntry.h" class nsDocShellLoadInfo : public nsIDocShellLoadInfo { @@ -48,6 +49,7 @@ protected: PRBool mReplaceSessionHistorySlot; PRBool mRefresh; nsCOMPtr mOwner; + nsCOMPtr mSHEntry; }; #endif /* nsDocShellLoadInfo_h__ */ diff --git a/mozilla/docshell/base/nsIDocShellLoadInfo.idl b/mozilla/docshell/base/nsIDocShellLoadInfo.idl index faf1e9e24db..c648525be47 100644 --- a/mozilla/docshell/base/nsIDocShellLoadInfo.idl +++ b/mozilla/docshell/base/nsIDocShellLoadInfo.idl @@ -29,6 +29,8 @@ */ interface nsIURI; +interface nsISHEntry; + [scriptable, uuid(33636F98-0635-11d4-9877-00C04FA0D27A)] interface nsIDocShellLoadInfo : nsISupports @@ -55,4 +57,9 @@ interface nsIDocShellLoadInfo : nsISupports causing the load to occur. This should be a nsIPrincipal typically. */ attribute nsISupports owner; + + /* + SHEntry for this page + */ + attribute nsISHEntry SHEntry; }; diff --git a/mozilla/docshell/base/nsIWebNavigation.idl b/mozilla/docshell/base/nsIWebNavigation.idl index 19b18389805..01b7493320e 100644 --- a/mozilla/docshell/base/nsIWebNavigation.idl +++ b/mozilla/docshell/base/nsIWebNavigation.idl @@ -31,6 +31,7 @@ */ interface nsISHistory; +interface nsISHEntry; [scriptable, uuid(F5D9E7B0-D930-11d3-B057-00A024FFC08C)] interface nsIWebNavigation : nsISupports @@ -118,4 +119,15 @@ interface nsIWebNavigation : nsISupports The session history object used to store the session history for the session. */ attribute nsISHistory sessionHistory; + + /* + Get the SHEntry associated with a child docshell + */ + nsISHEntry GetSHEForChild(in long childOffset); + + /* + Add a Child SHEntry for a frameset page + */ + void AddChildSHEntry(in nsISHEntry cloneReference, in nsISHEntry newEntry); + }; \ No newline at end of file