Fixes related to bug # 71756 r=rpotts, valeski

This commit is contained in:
radha%netscape.com 2001-03-28 03:35:38 +00:00
parent 6fd1cd591a
commit 0ee149dabb
9 changed files with 318 additions and 334 deletions

View File

@ -67,7 +67,7 @@
#include "nsILocaleService.h"
#include "nsITimer.h"
#include "nsIFileStream.h"
#include "nsISHistoryInternal.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
@ -1316,23 +1316,29 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
* hierarchy ie.,you just visited a frameset page
*/
nsCOMPtr<nsISHContainer> container(do_QueryInterface(LSHE, &rv));
if(container)
if(container) {
rv = container->AddChild(aNewEntry, aChildOffset);
}
}
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
* way to the top to clone the current SHEntry hierarchy
* and replace the subframe where a new url was loaded with
* a new entry.
*/
PRInt32 index=-1;
nsCOMPtr<nsISHEntry> currentEntry;
nsCOMPtr<nsIHistoryEntry> currentHE;
mSessionHistory->GetIndex(&index);
if (index < 0)
return NS_ERROR_FAILURE;
rv = mSessionHistory->GetEntryAtIndex(index, PR_FALSE,
getter_AddRefs(currentEntry));
getter_AddRefs(currentHE));
NS_ENSURE_TRUE(currentHE, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> currentEntry(do_QueryInterface(currentHE));
if (currentEntry) {
PRUint32 cloneID=0;
nsCOMPtr<nsISHEntry> nextEntry; //(do_CreateInstance(NS_SHENTRY_CONTRACTID));
@ -1343,7 +1349,9 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
getter_AddRefs(nextEntry));
if (NS_SUCCEEDED(rv)) {
rv = mSessionHistory->AddEntry(nextEntry, PR_TRUE);
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
rv = shPrivate->AddEntry(nextEntry, PR_TRUE);
}
}
}
@ -1639,9 +1647,11 @@ NS_IMETHODIMP nsDocShell::SetSessionHistory(nsISHistory* aSessionHistory)
GetSameTypeRootTreeItem(getter_AddRefs(root));
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
if (root.get() == NS_STATIC_CAST(nsIDocShellTreeItem *, this)) {
mSessionHistory = aSessionHistory;
mSessionHistory->SetRootDocShell(this);
return NS_OK;
mSessionHistory = aSessionHistory;
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
NS_ENSURE_TRUE(shPrivate,NS_ERROR_FAILURE);
shPrivate->SetRootDocShell(this);
return NS_OK;
}
return NS_ERROR_FAILURE;
@ -2105,8 +2115,10 @@ NS_IMETHODIMP nsDocShell::SetTitle(const PRUnichar* aTitle)
{
PRInt32 index = -1;
mSessionHistory->GetIndex(&index);
nsCOMPtr<nsISHEntry> shEntry;
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(shEntry));
nsCOMPtr<nsIHistoryEntry> hEntry;
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(hEntry));
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry));
if(shEntry)
shEntry->SetTitle(mTitle.GetUnicode());
}
@ -3088,8 +3100,10 @@ NS_IMETHODIMP nsDocShell::InternalLoad(nsIURI* aURI, nsIURI* aReferrer,
{
PRInt32 index = -1;
mSessionHistory->GetIndex(&index);
nsCOMPtr<nsISHEntry> shEntry;
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(shEntry));
nsCOMPtr<nsIHistoryEntry> hEntry;
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(hEntry));
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(hEntry));
if(shEntry)
shEntry->SetTitle(mTitle.GetUnicode());
}
@ -3107,10 +3121,7 @@ NS_IMETHODIMP nsDocShell::InternalLoad(nsIURI* aURI, nsIURI* aReferrer,
}
mLoadType = aLoadType;
// XXX: I think that LSHE should *always* be set to the new Entry.
// Even if it is null...
// if (aSHEntry)
LSHE = aSHEntry;
LSHE = aSHEntry;
nsDocShellInfoLoadType loadCmd = ConvertLoadTypeToDocShellLoadInfo(mLoadType);
NS_ENSURE_SUCCESS(DoURILoad(aURI, aReferrer, aOwner, aInheritOwner,
@ -3973,8 +3984,11 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
//
if(mSessionHistory && LOAD_NORMAL_REPLACE == mLoadType) {
PRInt32 index = 0;
nsCOMPtr<nsIHistoryEntry> hEntry;
mSessionHistory->GetIndex(&index);
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(entry));
mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(hEntry));
if(hEntry)
entry = do_QueryInterface(hEntry);
// see if the entry has any children and remove if any.
if (entry) {
nsCOMPtr<nsISHContainer> shContainer(do_QueryInterface(entry));
@ -4023,8 +4037,11 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
// will be deleted when it loses scope...
//
if (mLoadType != LOAD_NORMAL_REPLACE) {
if (mSessionHistory)
rv = mSessionHistory->AddEntry(entry, shouldPersist);
if (mSessionHistory) {
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
rv = shPrivate->AddEntry(entry, shouldPersist);
}
else
rv = AddChildSHEntry(nsnull, entry, mChildOffset);
}
@ -4041,39 +4058,6 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI *aURI,
return rv;
}
/*
* Save the HistoryLayoutState for this page before we leave it.
*/
NS_IMETHODIMP nsDocShell::UpdateCurrentSessionHistory()
{
nsresult rv = NS_OK;
if(!mInitialPageLoad && mSessionHistory) {
PRInt32 index = 0;
mSessionHistory->GetIndex(&index);
if (-1 < index) {
nsCOMPtr<nsISHEntry> entry;
rv = mSessionHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(entry));
if (NS_SUCCEEDED(rv) && entry) {
nsCOMPtr<nsIPresShell> shell;
rv = GetPresShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
nsCOMPtr<nsILayoutHistoryState> layoutState;
rv = shell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE);
if (NS_SUCCEEDED(rv) && layoutState) {
rv = entry->SetLayoutHistoryState(layoutState);
}
}
}
}
}
return rv;
}
NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadType)
{
@ -4082,8 +4066,10 @@ NS_IMETHODIMP nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadTyp
PRBool repost = PR_TRUE;
NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aEntry));
NS_ENSURE_TRUE(hEntry, NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(hEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
NS_ERROR_FAILURE);
@ -4157,20 +4143,22 @@ nsDocShell::CloneAndReplace(nsISHEntry * src, PRUint32 aCloneID,
{
nsresult result = NS_OK;
NS_ENSURE_ARG_POINTER(resultEntry);
if (!src || !replaceEntry)
return NS_ERROR_FAILURE;
nsISHEntry * dest = (nsISHEntry *) nsnull;
PRUint32 srcID;
src->GetID(&srcID);
nsISHEntry * dest = (nsISHEntry *) nsnull;
PRUint32 srcID;
src->GetID(&srcID);
nsCOMPtr<nsIHistoryEntry> srcHE(do_QueryInterface(src));
if (srcID == aCloneID) {
dest = replaceEntry;
*resultEntry = dest;
NS_IF_ADDREF(*resultEntry);
if (!src || !replaceEntry || !srcHE)
return NS_ERROR_FAILURE;
if (srcID == aCloneID) {
dest = replaceEntry;
dest->SetIsSubFrame(PR_TRUE);
*resultEntry = dest;
NS_IF_ADDREF(*resultEntry);
}
else {
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIInputStream> postdata;
nsCOMPtr<nsILayoutHistoryState> LHS;
PRUnichar * title=nsnull;
@ -4181,9 +4169,9 @@ nsDocShell::CloneAndReplace(nsISHEntry * src, PRUint32 aCloneID,
if (!NS_SUCCEEDED(result))
return result;
src->GetURI(getter_AddRefs(uri));
srcHE->GetURI(getter_AddRefs(uri));
src->GetPostData(getter_AddRefs(postdata));
src->GetTitle(&title);
srcHE->GetTitle(&title);
src->GetLayoutHistoryState(getter_AddRefs(LHS));
//XXX Is this correct? parent is a weak ref in nsISHEntry
src->GetParent(getter_AddRefs(parent));
@ -4196,6 +4184,7 @@ nsDocShell::CloneAndReplace(nsISHEntry * src, PRUint32 aCloneID,
dest->SetTitle(title);
dest->SetParent(parent);
dest->SetID(id);
dest->SetIsSubFrame(PR_TRUE);
*resultEntry = dest;
PRInt32 childCount= 0;
@ -4221,9 +4210,8 @@ nsDocShell::CloneAndReplace(nsISHEntry * src, PRUint32 aCloneID,
result = destContainer->AddChild(destChild, i);
if (!NS_SUCCEEDED(result))
return result;
}
}
} // for
}
return result;

View File

@ -226,12 +226,10 @@ protected:
virtual nsresult AddToSessionHistory(nsIURI* aURI, nsIChannel *aChannel,
nsISHEntry **aNewEntry);
NS_IMETHOD UpdateCurrentSessionHistory();
NS_IMETHOD LoadHistoryEntry(nsISHEntry* aEntry, PRUint32 aLoadType);
// NS_IMETHOD GetCurrentSHE(PRInt32 aChildOffset, nsISHEntry ** aResult);
NS_IMETHOD PersistLayoutHistoryState();
NS_IMETHOD CloneAndReplace(nsISHEntry * srcEntry, PRUint32 aCloneID,
NS_IMETHOD CloneAndReplace(nsISHEntry* srcEntry, PRUint32 aCloneID,
nsISHEntry * areplaceEntry, nsISHEntry **destEntry);
// Global History
NS_IMETHOD ShouldAddToGlobalHistory(nsIURI* aURI, PRBool* aShouldAdd);

View File

@ -508,16 +508,14 @@ NS_IMETHODIMP nsWebShell::GoTo(PRInt32 aIndex)
{
NS_ENSURE_STATE(mSessionHistory);
NS_ENSURE_TRUE(!IsFrame(), NS_ERROR_FAILURE);
nsCOMPtr<nsIHistoryEntry> entry;
nsCOMPtr<nsISHEntry> entry;
NS_ENSURE_SUCCESS(mSessionHistory->GetEntryAtIndex(aIndex, PR_TRUE,
getter_AddRefs(entry)), NS_ERROR_FAILURE);
mSessionHistory->GetEntryAtIndex(aIndex, PR_TRUE, getter_AddRefs(entry));
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
NS_ENSURE_TRUE(shEntry, NS_ERROR_FAILURE);
UpdateCurrentSessionHistory();
NS_ENSURE_SUCCESS(LoadHistoryEntry(entry, LOAD_HISTORY), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(LoadHistoryEntry(shEntry, LOAD_HISTORY), NS_ERROR_FAILURE);
return NS_OK;
}
@ -548,7 +546,7 @@ nsWebShell::GetURL(PRInt32 aIndex, const PRUnichar** aURLResult)
NS_ENSURE_STATE(mSessionHistory);
NS_ENSURE_TRUE(!IsFrame(), NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> entry;
nsCOMPtr<nsIHistoryEntry> entry;
NS_ENSURE_SUCCESS(mSessionHistory->GetEntryAtIndex(aIndex, PR_TRUE,
getter_AddRefs(entry)), NS_ERROR_FAILURE);

View File

@ -30,7 +30,7 @@
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIWebNavigation.h"
#include "nsISHEntry.h"
#include "nsIHistoryEntry.h"
#include "nsIURI.h"
#include "nsXPIDLString.h"
@ -109,7 +109,7 @@ HistoryImpl::GetCurrent(nsAWritableString& aCurrent)
// Get the current index at session History
sHistory->GetIndex(&curIndex);
nsCOMPtr<nsISHEntry> curEntry;
nsCOMPtr<nsIHistoryEntry> curEntry;
nsCOMPtr<nsIURI> uri;
// Get the SH entry for the current index
@ -139,7 +139,7 @@ HistoryImpl::GetPrevious(nsAWritableString& aPrevious)
// Get the current index at session History
sHistory->GetIndex(&curIndex);
nsCOMPtr<nsISHEntry> prevEntry;
nsCOMPtr<nsIHistoryEntry> prevEntry;
nsCOMPtr<nsIURI> uri;
// Get the previous SH entry
@ -169,7 +169,7 @@ HistoryImpl::GetNext(nsAWritableString& aNext)
// Get the current index at session History
sHistory->GetIndex(&curIndex);
nsCOMPtr<nsISHEntry> nextEntry;
nsCOMPtr<nsIHistoryEntry> nextEntry;
nsCOMPtr<nsIURI> uri;
// Get the next SH entry
@ -245,7 +245,7 @@ HistoryImpl::Go(JSContext* cx, jsval* argv, PRUint32 argc)
nsAutoString substr; substr.AssignWithConversion(JS_GetStringBytes(jsstr));
result = sHistory->GetCount(&count);
for (i = 0; (i < count) && NS_SUCCEEDED(result); i++) {
nsCOMPtr<nsISHEntry> shEntry;
nsCOMPtr<nsIHistoryEntry> shEntry;
nsCOMPtr<nsIURI> uri;
result = sHistory->GetEntryAtIndex(i, PR_FALSE, getter_AddRefs(shEntry));
@ -282,7 +282,7 @@ HistoryImpl::Item(PRUint32 aIndex, nsAWritableString& aReturn)
GetSessionHistoryFromDocShell(mDocShell, getter_AddRefs(sHistory));
NS_ENSURE_TRUE(sHistory, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> shEntry;
nsCOMPtr<nsIHistoryEntry> shEntry;
nsCOMPtr<nsIURI> uri;
result = sHistory->GetEntryAtIndex(aIndex, PR_FALSE, getter_AddRefs(shEntry));

View File

@ -59,9 +59,10 @@ NS_IMPL_ADDREF(nsSHEntry)
NS_IMPL_RELEASE(nsSHEntry)
NS_INTERFACE_MAP_BEGIN(nsSHEntry)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHEntry)
NS_INTERFACE_MAP_ENTRY(nsISHContainer)
NS_INTERFACE_MAP_ENTRY(nsISHEntry)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHEntry)
NS_INTERFACE_MAP_ENTRY(nsISHContainer)
NS_INTERFACE_MAP_ENTRY(nsISHEntry)
NS_INTERFACE_MAP_ENTRY(nsIHistoryEntry)
NS_INTERFACE_MAP_END
//*****************************************************************************
@ -179,17 +180,37 @@ NS_IMETHODIMP nsSHEntry::SetID(PRUint32 aID)
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetIsSubFrame(PRBool * aFlag)
{
NS_ENSURE_ARG_POINTER(aFlag);
*aFlag = mIsFrameNavigation;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetIsSubFrame(PRBool aFlag)
{
mIsFrameNavigation = aFlag;
return NS_OK;
}
nsresult
nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOMDocument,
nsIInputStream * aInputStream, nsILayoutHistoryState * aHistoryLayoutState)
{
SetURI(aURI);
SetURI(aURI);
SetTitle(aTitle);
SetDocument(aDOMDocument);
SetPostData(aInputStream);
SetLayoutHistoryState(aHistoryLayoutState);
// Set the LoadType by default to loadHistory during creation
// Set the LoadType by default to loadHistory during creation
SetLoadType((PRInt32)nsIDocShellLoadInfo::loadHistory);
// By default all entries are set false for subframe flag.
// nsDocShell::CloneAndReplace() which creates entries for
// all subframe navigations, sets the flag to true.
SetIsSubFrame(PR_FALSE);
return NS_OK;
}
@ -279,93 +300,3 @@ nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetChildEnumerator(nsIEnumerator** aChildEnumerator)
{
nsresult status = NS_OK;
NS_ENSURE_ARG_POINTER(aChildEnumerator);
nsSHEnumerator * iterator = new nsSHEnumerator(this);
if (iterator && !!NS_SUCCEEDED(status = CallQueryInterface(iterator, aChildEnumerator)))
delete iterator;
return status;
}
//*****************************************************************************
//*** nsSHEnumerator: Object Management
//*****************************************************************************
nsSHEnumerator::nsSHEnumerator(nsSHEntry * aEntry):mIndex(0)
{
NS_INIT_REFCNT();
mSHEntry = aEntry;
}
nsSHEnumerator::~nsSHEnumerator()
{
mSHEntry = nsnull;
}
NS_IMPL_ISUPPORTS1(nsSHEnumerator, nsIEnumerator)
NS_IMETHODIMP
nsSHEnumerator::Next()
{
PRUint32 cnt=0;
cnt = mSHEntry->mChildren.Count();
if (mIndex < (PRInt32)(cnt-1)) {
mIndex++;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSHEnumerator::First()
{
mIndex = 0;
return NS_OK;
}
NS_IMETHODIMP
nsSHEnumerator::IsDone()
{
PRUint32 cnt;
cnt = mSHEntry->mChildren.Count();
if (mIndex >= 0 && mIndex < (PRInt32)cnt ) {
return NS_ENUMERATOR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsSHEnumerator::CurrentItem(nsISupports **aItem)
{
NS_ENSURE_ARG_POINTER(aItem);
PRUint32 cnt= mSHEntry->mChildren.Count();
if (mIndex >=0 && mIndex < (PRInt32)cnt){
*aItem = (nsISupports *)mSHEntry->mChildren.ElementAt(mIndex);
NS_IF_ADDREF(*aItem);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSHEnumerator::CurrentItem(nsISHEntry **aItem)
{
NS_ENSURE_ARG_POINTER(aItem);
PRUint32 cnt = mSHEntry->mChildren.Count();
if (mIndex >=0 && mIndex < (PRInt32)cnt){
nsCOMPtr<nsISupports> indexIsupports = (nsISHEntry *) mSHEntry->mChildren.ElementAt(mIndex);
return indexIsupports->QueryInterface(NS_GET_IID(nsISHEntry),(void **)aItem);
}
return NS_ERROR_FAILURE;
}

View File

@ -36,27 +36,26 @@
#include "nsISHContainer.h"
#include "nsIURI.h"
#include "nsIEnumerator.h"
#include "nsIHistoryEntry.h"
// I can probably get rid of the enumerator thing.
class nsSHEnumerator;
class nsSHEntry : public nsISHEntry,
class nsSHEntry : public nsIHistoryEntry,
public nsISHEntry,
public nsISHContainer
{
public:
nsSHEntry();
NS_DECL_ISUPPORTS
NS_DECL_NSISHENTRY
NS_DECL_NSISHCONTAINER
NS_DECL_ISUPPORTS
NS_DECL_NSIHISTORYENTRY
NS_DECL_NSISHENTRY
NS_DECL_NSISHCONTAINER
protected:
virtual ~nsSHEntry();
friend class nsSHEnumerator;
private:
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIDOMDocument> mDocument;
nsString mTitle;
nsCOMPtr<nsIInputStream> mPostData;
@ -64,29 +63,9 @@ private:
nsVoidArray mChildren;
PRUint32 mLoadType;
PRUint32 mID;
PRBool mIsFrameNavigation;
nsISHEntry * mParent; // weak reference
};
//*****************************************************************************
//*** nsSHEnumerator: Object Management
//*****************************************************************************
class nsSHEnumerator : public nsIEnumerator
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIENUMERATOR
nsSHEnumerator(nsSHEntry * aEntry);
NS_IMETHOD CurrentItem(nsISHEntry ** aItem);
protected:
friend class nsSHEntry;
virtual ~nsSHEnumerator();
private:
PRInt32 mIndex;
nsSHEntry * mSHEntry; // what about reference?
};
#endif /* nsSHEntry_h */

View File

@ -65,6 +65,7 @@ NS_INTERFACE_MAP_BEGIN(nsSHistory)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHistory)
NS_INTERFACE_MAP_ENTRY(nsISHistory)
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
NS_INTERFACE_MAP_ENTRY(nsISHistoryInternal)
NS_INTERFACE_MAP_END
//*****************************************************************************
@ -118,8 +119,11 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, PRBool aPersist)
nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(mListener));
if (listener) {
nsCOMPtr<nsIURI> uri;
aSHEntry->GetURI(getter_AddRefs(uri));
listener->OnHistoryNewEntry(uri);
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aSHEntry));
if (hEntry) {
hEntry->GetURI(getter_AddRefs(uri));
listener->OnHistoryNewEntry(uri);
}
}
}
@ -162,49 +166,39 @@ nsSHistory::GetIndex(PRInt32 * aResult)
return NS_OK;
}
/* Get the entry prior to the current index */
NS_IMETHODIMP
nsSHistory::GetPreviousEntry(PRBool aModifyIndex, nsISHEntry ** aResult)
nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aResult)
{
nsresult rv;
nsresult rv;
nsCOMPtr<nsISHTransaction> txn;
/* GetEntryAtIndex ensures aResult is valid */
rv = GetEntryAtIndex((mIndex-1), aModifyIndex, aResult);
return rv;
}
/* Get the entry next to the current index */
NS_IMETHODIMP
nsSHistory::GetNextEntry(PRBool aModifyIndex, nsISHEntry ** aResult)
{
nsresult rv;
/* GetEntryAtIndex ensures aResult is valid */
rv = GetEntryAtIndex((mIndex+1), aModifyIndex, aResult);
return rv;
/* GetTransactionAtIndex ensures aResult is valid and validates aIndex */
rv = GetTransactionAtIndex(aIndex, getter_AddRefs(txn));
if (NS_SUCCEEDED(rv) && txn) {
//Get the Entry from the transaction
rv = txn->GetSHEntry(getter_AddRefs(aResult));
if (NS_SUCCEEDED(rv) && (*aResult)) {
// Set mIndex to the requested index, if asked to do so..
if (aModifyIndex) {
mIndex = aIndex;
}
} //entry
} //Transaction
return rv;
}
/* Get the entry at a given index */
NS_IMETHODIMP
nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aResult)
nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsIHistoryEntry** aResult)
{
nsresult rv;
nsCOMPtr<nsISHTransaction> txn;
/* GetTransactionAtIndex ensures aResult is valid and validates aIndex */
rv = GetTransactionAtIndex(aIndex, getter_AddRefs(txn));
if (NS_SUCCEEDED(rv) && txn) {
//Get the Entry from the transaction
rv = txn->GetSHEntry(aResult);
if (NS_SUCCEEDED(rv) && (*aResult)) {
// Set mIndex to the requested index, if asked to do so..
if (aModifyIndex) {
mIndex = aIndex;
}
} //entry
} //Transaction
return rv;
nsresult rv;
nsCOMPtr<nsISHEntry> shEntry;
rv = GetEntryAtIndex(aIndex, aModifyIndex, getter_AddRefs(shEntry));
if (NS_SUCCEEDED(rv) && shEntry)
rv = CallQueryInterface(shEntry, aResult);
return rv;
}
/* Get the transaction at a given index */
@ -283,8 +277,11 @@ nsSHistory::PrintHistory()
nsXPIDLCString url;
entry->GetLayoutHistoryState(getter_AddRefs(layoutHistoryState));
entry->GetURI(getter_AddRefs(uri));
entry->GetTitle(&title);
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(entry));
if (hEntry) {
hEntry->GetURI(getter_AddRefs(uri));
hEntry->GetTitle(&title);
}
if (uri)
uri->GetSpec(getter_Copies(url));
@ -532,11 +529,13 @@ NS_IMETHODIMP
nsSHistory::GetCurrentURI(nsIURI** aResultURI)
{
NS_ENSURE_ARG_POINTER(aResultURI);
nsresult rv;
nsCOMPtr<nsISHEntry> currentEntry;
nsresult rv = GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(currentEntry));
nsCOMPtr<nsIHistoryEntry> currentEntry;
rv = GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(currentEntry));
if (NS_FAILED(rv) && !currentEntry) return rv;
return currentEntry->GetURI(aResultURI);
rv = currentEntry->GetURI(aResultURI);
return rv;
}
@ -571,35 +570,39 @@ nsSHistory::GotoIndex(PRInt32 aIndex)
NS_IMETHODIMP
nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType)
{
nsCOMPtr<nsIDocShell> docShell;
nsCOMPtr<nsISHEntry> shEntry;
PRInt32 oldIndex = mIndex;
nsCOMPtr<nsIDocShell> docShell;
nsCOMPtr<nsISHEntry> shEntry;
PRInt32 oldIndex = mIndex;
nsCOMPtr<nsISHEntry> prevEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(prevEntry));
mIndex = aIndex;
nsCOMPtr<nsISHEntry> prevEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(prevEntry));
mIndex = aIndex;
nsCOMPtr<nsISHEntry> nextEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(nextEntry));
nsCOMPtr<nsISHEntry> nextEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(nextEntry));
nsCOMPtr<nsIHistoryEntry> nHEntry(do_QueryInterface(nextEntry));
if (!nextEntry || !prevEntry || !nHEntry)
return NS_ERROR_FAILURE;
// Send appropriate listener notifications
PRBool canNavigate = PR_TRUE;
if(mListener) {
nsCOMPtr<nsIURI> uri;
nextEntry->GetURI(getter_AddRefs(uri));
// Get the uri for the entry we are about to visit
nsCOMPtr<nsIURI> nextURI;
nHEntry->GetURI(getter_AddRefs(nextURI));
if(mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(mListener));
if (listener) {
if (mIndex+1 == oldIndex) {
// We are going back one entry. Send GoBack notifications
listener->OnHistoryGoBack(uri, &canNavigate);
listener->OnHistoryGoBack(nextURI, &canNavigate);
}
else if (mIndex-1 == oldIndex) {
// We are going forward. Send GoForward notification
listener->OnHistoryGoForward(uri, &canNavigate);
listener->OnHistoryGoForward(nextURI, &canNavigate);
}
else if (mIndex != oldIndex) {
// We are going somewhere else. This is not reload either
listener->OnHistoryGotoIndex(mIndex, uri, &canNavigate);
listener->OnHistoryGotoIndex(mIndex, nextURI, &canNavigate);
}
}
}
@ -611,70 +614,68 @@ nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType)
return NS_OK; // XXX Maybe I can return some other error code?
}
nsCOMPtr<nsIURI> nexturi;
PRInt32 pCount=0, nCount=0;
nsCOMPtr<nsISHContainer> prevAsContainer(do_QueryInterface(prevEntry));
nsCOMPtr<nsISHContainer> nextAsContainer(do_QueryInterface(nextEntry));
if (prevAsContainer && nextAsContainer) {
prevAsContainer->GetChildCount(&pCount);
nextAsContainer->GetChildCount(&nCount);
}
nsCOMPtr<nsIURI> nexturi;
PRInt32 pCount=0, nCount=0;
nsCOMPtr<nsISHContainer> prevAsContainer(do_QueryInterface(prevEntry));
nsCOMPtr<nsISHContainer> nextAsContainer(do_QueryInterface(nextEntry));
if (prevAsContainer && nextAsContainer) {
prevAsContainer->GetChildCount(&pCount);
nextAsContainer->GetChildCount(&nCount);
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
if (oldIndex == aIndex) {
// Possibly a reload case
docShell = mRootDocShell;
}
else {
// Going back or forward.
if ((pCount > 0) && (nCount > 0)) {
/* THis is a subframe navigation. Go find
* the docshell in which load should happen
*/
PRBool result = CompareSHEntry(prevEntry, nextEntry, mRootDocShell,
getter_AddRefs(docShell),
getter_AddRefs(shEntry));
if (!result) {
/* There was an error in finding the entry and docshell
* where the load should happen. Reset the index back
* to what it was. Return failure.
*/
mIndex = oldIndex;
return NS_ERROR_FAILURE;
}
else {
nextEntry = shEntry;
}
}
else
docShell = mRootDocShell;
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
if (oldIndex == aIndex) {
// Possibly a reload case
docShell = mRootDocShell;
}
else {
// Going back or forward.
if ((pCount > 0) && (nCount > 0)) {
/* THis is a subframe navigation. Go find
* the docshell in which load should happen
*/
PRBool result = CompareSHEntry(prevEntry, nextEntry, mRootDocShell,
getter_AddRefs(docShell),
getter_AddRefs(shEntry));
if (!result) {
/* There was an error in finding the entry and docshell
* where the load should happen. Reset the index back
* to what it was. Return failure.
*/
mIndex = oldIndex;
return NS_ERROR_FAILURE;
}
else {
nextEntry = shEntry;
}
} // (pCount >0)
else
docShell = mRootDocShell;
}
if (!docShell || !nextEntry || !mRootDocShell)
return NS_ERROR_FAILURE;
if (!docShell || !nextEntry || !mRootDocShell)
return NS_ERROR_FAILURE;
nextEntry->GetURI(getter_AddRefs(nexturi));
/* Set the loadType in the SHEntry too to what was passed on.
* This will be passed on to child subframes later in nsDocShell,
* so that proper loadType is maintained through out a frameset
*/
nextEntry->SetLoadType(aLoadType);
/* Set the loadType in the SHEntry too to what was passed on.
* This will be passed on to child subframes later in nsDocShell,
* so that proper loadType is maintained through out a frameset
*/
nextEntry->SetLoadType(aLoadType);
mRootDocShell->CreateLoadInfo (getter_AddRefs(loadInfo));
// This is not available yet
loadInfo->SetLoadType(aLoadType);
loadInfo->SetSHEntry(nextEntry);
// Time to initiate a document load
nsresult rv = docShell->LoadURI(nexturi, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE);
/* If the loadURI call failed for some reason,
* reset mIndex to what it was. so that back/forward
* won't misbehave
*/
if (!NS_SUCCEEDED(rv))
mRootDocShell->CreateLoadInfo (getter_AddRefs(loadInfo));
loadInfo->SetLoadType(aLoadType);
loadInfo->SetSHEntry(nextEntry);
// Time to initiate a document load
nsresult rv = docShell->LoadURI(nextURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE);
/* If the loadURI call failed for some reason,
* reset mIndex to what it was. so that back/forward
* won't misbehave
*/
if (!NS_SUCCEEDED(rv))
mIndex = oldIndex;
return rv;
return rv;
}
@ -689,7 +690,6 @@ nsSHistory::CompareSHEntry(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsI
return PR_FALSE;
PRBool result = PR_FALSE;
nsCOMPtr<nsIURI> prevURI, nextURI;
PRUint32 prevID, nextID;
aPrevEntry->GetID(&prevID);
@ -763,3 +763,64 @@ nsSHistory::GetRootDocShell(nsIDocShell ** aDocShell)
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator)
{
nsresult status = NS_OK;
NS_ENSURE_ARG_POINTER(aEnumerator);
nsSHEnumerator * iterator = new nsSHEnumerator(this);
if (iterator && !NS_SUCCEEDED(status = CallQueryInterface(iterator, aEnumerator)))
delete iterator;
return status;
}
//*****************************************************************************
//*** nsSHEnumerator: Object Management
//*****************************************************************************
nsSHEnumerator::nsSHEnumerator(nsSHistory * aSHistory):mIndex(-1)
{
NS_INIT_REFCNT();
mSHistory = aSHistory;
}
nsSHEnumerator::~nsSHEnumerator()
{
mSHistory = nsnull;
}
NS_IMPL_ISUPPORTS1(nsSHEnumerator, nsISimpleEnumerator)
NS_IMETHODIMP
nsSHEnumerator::HasMoreElements(PRBool * aReturn)
{
PRInt32 cnt;
*aReturn = PR_FALSE;
mSHistory->GetCount(&cnt);
if (mIndex >= 0 && mIndex < cnt ) {
*aReturn = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
nsSHEnumerator::GetNext(nsISupports **aItem)
{
NS_ENSURE_ARG_POINTER(aItem);
PRInt32 cnt= 0;
nsresult result = NS_ERROR_FAILURE;
mSHistory->GetCount(&cnt);
if (mIndex < (cnt-1)) {
mIndex++;
nsCOMPtr<nsIHistoryEntry> hEntry;
result = mSHistory->GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(hEntry));
if (hEntry)
result = CallQueryInterface(hEntry, aItem);
}
return result;
}

View File

@ -28,30 +28,35 @@
//Interfaces Needed
#include "nsISHistory.h"
#include "nsISHistoryInternal.h"
#include "nsISHTransaction.h"
#include "nsIWebNavigation.h"
#include "nsIWeakReference.h"
#include "nsISimpleEnumerator.h"
class nsIDocShell;
class nsSHEnumerator;
class nsSHistory: public nsISHistory,
public nsISHistoryInternal,
public nsIWebNavigation
{
public:
nsSHistory();
NS_DECL_ISUPPORTS
NS_DECL_NSISHISTORY
NS_DECL_NSIWEBNAVIGATION
NS_DECL_ISUPPORTS
NS_DECL_NSISHISTORY
NS_DECL_NSISHISTORYINTERNAL
NS_DECL_NSIWEBNAVIGATION
NS_IMETHOD Init();
protected:
virtual ~nsSHistory();
virtual ~nsSHistory();
friend class nsSHEnumerator;
// Could become part of nsIWebNavigation
NS_IMETHOD PrintHistory();
NS_IMETHOD GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aResult);
NS_IMETHOD GetTransactionAtIndex(PRInt32 aIndex, nsISHTransaction ** aResult);
PRBool CompareSHEntry(nsISHEntry * prevEntry, nsISHEntry * nextEntry, nsIDocShell * rootDocShell,
nsIDocShell ** aResultDocShell, nsISHEntry ** aResultSHEntry);
@ -66,6 +71,26 @@ protected:
// Weak reference. Do not refcount this.
nsIDocShell * mRootDocShell;
};
//*****************************************************************************
//*** nsSHEnumerator: Object Management
//*****************************************************************************
class nsSHEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
nsSHEnumerator(nsSHistory * aHistory);
protected:
friend class nsSHistory;
virtual ~nsSHEnumerator();
private:
PRInt32 mIndex;
nsSHistory * mSHistory;
};
#endif /* nsSHistory */

View File

@ -46,10 +46,14 @@ static nsModuleComponentInfo gSHistoryModuleInfo[] =
{
{ "nsSHEntry", NS_SHENTRY_CID,
NS_SHENTRY_CONTRACTID, nsSHEntryConstructor },
{ "nsSHEntry", NS_HISTORYENTRY_CID,
NS_HISTORYENTRY_CONTRACTID, nsSHEntryConstructor },
{ "nsSHTransaction", NS_SHTRANSACTION_CID,
NS_SHTRANSACTION_CONTRACTID, nsSHTransactionConstructor },
{ "nsSHistory", NS_SHISTORY_CID,
NS_SHISTORY_CONTRACTID, nsSHistoryConstructor }
NS_SHISTORY_CONTRACTID, nsSHistoryConstructor },
{ "nsSHistory", NS_SHISTORY_INTERNAL_CID,
NS_SHISTORY_INTERNAL_CONTRACTID, nsSHistoryConstructor }
};
NS_IMPL_NSGETMODULE("Session History Module", gSHistoryModuleInfo)