2005-08-18 11:16:28 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
2005-08-18 11:15:08 +00:00
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is the Mozilla browser.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications, Inc. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Radha Kulkarni <radha@netscape.com>
|
|
|
|
*/
|
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
// Local Includes
|
2005-08-18 11:15:08 +00:00
|
|
|
#include "nsSHistory.h"
|
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
// Helper Classes
|
|
|
|
#include "nsXPIDLString.h"
|
2005-08-18 11:16:18 +00:00
|
|
|
#include "nsReadableUtils.h"
|
2005-08-18 11:15:08 +00:00
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
// Interfaces Needed
|
|
|
|
#include "nsILayoutHistoryState.h"
|
2005-08-18 11:16:44 +00:00
|
|
|
#include "nsIDocShell.h"
|
2005-08-18 11:15:34 +00:00
|
|
|
#include "nsIDocShellLoadInfo.h"
|
|
|
|
#include "nsISHContainer.h"
|
|
|
|
#include "nsIDocShellTreeItem.h"
|
|
|
|
#include "nsIDocShellTreeNode.h"
|
2005-08-18 11:15:37 +00:00
|
|
|
#include "nsIDocShellLoadInfo.h"
|
2005-08-18 11:15:47 +00:00
|
|
|
#include "nsIServiceManager.h"
|
2005-08-18 11:16:41 +00:00
|
|
|
#include "nsIPrefService.h"
|
2005-08-18 11:15:59 +00:00
|
|
|
|
|
|
|
#define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries"
|
2005-08-18 11:16:31 +00:00
|
|
|
static PRInt32 gHistoryMaxSize = 50;
|
2005-08-18 11:15:08 +00:00
|
|
|
|
2005-08-18 11:16:17 +00:00
|
|
|
enum HistCmd{
|
|
|
|
HIST_CMD_BACK,
|
|
|
|
HIST_CMD_FORWARD,
|
|
|
|
HIST_CMD_GOTOINDEX,
|
|
|
|
HIST_CMD_RELOAD
|
|
|
|
} ;
|
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
//*****************************************************************************
|
|
|
|
//*** nsSHistory: Object Management
|
|
|
|
//*****************************************************************************
|
2005-08-18 11:15:08 +00:00
|
|
|
|
2005-08-18 11:16:15 +00:00
|
|
|
nsSHistory::nsSHistory() : mListRoot(nsnull), mIndex(-1), mLength(0), mRequestedIndex(-1)
|
2005-08-18 11:15:08 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsSHistory::~nsSHistory()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
//*****************************************************************************
|
|
|
|
// nsSHistory: nsISupports
|
|
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsSHistory)
|
|
|
|
NS_IMPL_RELEASE(nsSHistory)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsSHistory)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHistory)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISHistory)
|
2005-08-18 11:15:39 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
|
2005-08-18 11:16:01 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISHistoryInternal)
|
2005-08-18 11:15:33 +00:00
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
|
|
// nsSHistory: nsISHistory
|
|
|
|
//*****************************************************************************
|
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
/*
|
|
|
|
* Init method to get pref settings
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::Init()
|
|
|
|
{
|
2005-08-18 11:16:41 +00:00
|
|
|
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
|
|
if (prefs) {
|
|
|
|
nsCOMPtr<nsIPrefBranch> defaultBranch;
|
|
|
|
prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch));
|
|
|
|
if (defaultBranch) {
|
|
|
|
defaultBranch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize);
|
|
|
|
}
|
2005-08-18 11:15:59 +00:00
|
|
|
}
|
2005-08-18 11:16:41 +00:00
|
|
|
return NS_OK;
|
2005-08-18 11:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-18 11:15:08 +00:00
|
|
|
/* Add an entry to the History list at mIndex and
|
|
|
|
* increment the index to point to the new entry
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:15:28 +00:00
|
|
|
nsSHistory::AddEntry(nsISHEntry * aSHEntry, PRBool aPersist)
|
2005-08-18 11:15:08 +00:00
|
|
|
{
|
2005-08-18 11:15:59 +00:00
|
|
|
NS_ENSURE_ARG(aSHEntry);
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
nsCOMPtr<nsISHTransaction> currentTxn;
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
if(mListRoot)
|
|
|
|
GetTransactionAtIndex(mIndex, getter_AddRefs(currentTxn));
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
PRBool currentPersist = PR_TRUE;
|
|
|
|
if(currentTxn)
|
|
|
|
currentTxn->GetPersist(¤tPersist);
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
if(!currentPersist)
|
|
|
|
{
|
|
|
|
NS_ENSURE_SUCCESS(currentTxn->SetSHEntry(aSHEntry),NS_ERROR_FAILURE);
|
|
|
|
currentTxn->SetPersist(aPersist);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
nsCOMPtr<nsISHTransaction> txn(do_CreateInstance(NS_SHTRANSACTION_CONTRACTID));
|
|
|
|
NS_ENSURE_TRUE(txn, NS_ERROR_FAILURE);
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:16:00 +00:00
|
|
|
// Notify any listener about the new addition
|
|
|
|
if (mListener) {
|
2005-08-18 11:16:04 +00:00
|
|
|
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
|
2005-08-18 11:16:00 +00:00
|
|
|
if (listener) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aSHEntry));
|
|
|
|
if (hEntry) {
|
|
|
|
hEntry->GetURI(getter_AddRefs(uri));
|
|
|
|
listener->OnHistoryNewEntry(uri);
|
|
|
|
}
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
// Set the ShEntry and parent for the transaction. setting the
|
|
|
|
// parent will properly set the parent child relationship
|
|
|
|
txn->SetPersist(aPersist);
|
|
|
|
NS_ENSURE_SUCCESS(txn->Create(aSHEntry, currentTxn), NS_ERROR_FAILURE);
|
2005-08-18 11:15:28 +00:00
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
// A little tricky math here... Basically when adding an object regardless of
|
|
|
|
// what the length was before, it should always be set back to the current and
|
|
|
|
// lop off the forward.
|
|
|
|
mLength = (++mIndex + 1);
|
|
|
|
|
|
|
|
// If this is the very first transaction, initialize the list
|
|
|
|
if(!mListRoot)
|
|
|
|
mListRoot = txn;
|
|
|
|
|
|
|
|
//Purge History list if it is too long
|
|
|
|
if ((gHistoryMaxSize >= 0) && (mLength > gHistoryMaxSize))
|
|
|
|
PurgeHistory(mLength-gHistoryMaxSize);
|
|
|
|
|
|
|
|
return NS_OK;
|
2005-08-18 11:15:08 +00:00
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:18 +00:00
|
|
|
/* Get size of the history list */
|
2005-08-18 11:15:08 +00:00
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:15:18 +00:00
|
|
|
nsSHistory::GetCount(PRInt32 * aResult)
|
2005-08-18 11:15:08 +00:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult = mLength;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get index of the history list */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetIndex(PRInt32 * aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult = mIndex;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:01 +00:00
|
|
|
nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aResult)
|
2005-08-18 11:15:14 +00:00
|
|
|
{
|
2005-08-18 11:16:01 +00:00
|
|
|
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
|
2005-08-18 11:16:03 +00:00
|
|
|
rv = txn->GetSHEntry(aResult);
|
2005-08-18 11:16:01 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && (*aResult)) {
|
|
|
|
// Set mIndex to the requested index, if asked to do so..
|
|
|
|
if (aModifyIndex) {
|
|
|
|
mIndex = aIndex;
|
|
|
|
}
|
|
|
|
} //entry
|
|
|
|
} //Transaction
|
|
|
|
return rv;
|
2005-08-18 11:15:14 +00:00
|
|
|
}
|
2005-08-18 11:15:08 +00:00
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
|
|
|
|
/* Get the entry at a given index */
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:01 +00:00
|
|
|
nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsIHistoryEntry** aResult)
|
2005-08-18 11:15:14 +00:00
|
|
|
{
|
2005-08-18 11:16:01 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISHEntry> shEntry;
|
|
|
|
rv = GetEntryAtIndex(aIndex, aModifyIndex, getter_AddRefs(shEntry));
|
|
|
|
if (NS_SUCCEEDED(rv) && shEntry)
|
|
|
|
rv = CallQueryInterface(shEntry, aResult);
|
|
|
|
|
|
|
|
return rv;
|
2005-08-18 11:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the transaction at a given index */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetTransactionAtIndex(PRInt32 aIndex, nsISHTransaction ** aResult)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
|
|
|
if ((mLength <= 0) || (aIndex < 0) || (aIndex >= mLength))
|
2005-08-18 11:15:08 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
if (!mListRoot)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2005-08-18 11:15:08 +00:00
|
|
|
if (aIndex == 0)
|
|
|
|
{
|
|
|
|
*aResult = mListRoot;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
PRInt32 cnt=0;
|
|
|
|
nsCOMPtr<nsISHTransaction> tempPtr;
|
2005-08-18 11:15:14 +00:00
|
|
|
|
|
|
|
rv = GetRootTransaction(getter_AddRefs(tempPtr));
|
2005-08-18 11:16:25 +00:00
|
|
|
if (NS_FAILED(rv) || !tempPtr)
|
2005-08-18 11:15:14 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:15:08 +00:00
|
|
|
|
|
|
|
while(1) {
|
|
|
|
nsCOMPtr<nsISHTransaction> ptr;
|
2005-08-18 11:15:33 +00:00
|
|
|
rv = tempPtr->GetNext(getter_AddRefs(ptr));
|
2005-08-18 11:15:08 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && ptr) {
|
|
|
|
cnt++;
|
|
|
|
if (cnt == aIndex) {
|
|
|
|
*aResult = ptr;
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tempPtr = ptr;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} //NS_SUCCEEDED
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:15:14 +00:00
|
|
|
} // while
|
|
|
|
|
2005-08-18 11:15:08 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::PrintHistory()
|
|
|
|
{
|
|
|
|
|
|
|
|
nsCOMPtr<nsISHTransaction> txn;
|
|
|
|
PRInt32 index = 0;
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!mListRoot)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
txn = mListRoot;
|
|
|
|
|
|
|
|
while (1) {
|
2005-08-18 11:15:34 +00:00
|
|
|
if (!txn)
|
|
|
|
break;
|
|
|
|
nsCOMPtr<nsISHEntry> entry;
|
2005-08-18 11:15:14 +00:00
|
|
|
rv = txn->GetSHEntry(getter_AddRefs(entry));
|
2005-08-18 11:16:25 +00:00
|
|
|
if (NS_FAILED(rv) && !entry)
|
2005-08-18 11:15:14 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2005-08-18 11:15:30 +00:00
|
|
|
nsCOMPtr<nsILayoutHistoryState> layoutHistoryState;
|
2005-08-18 11:15:14 +00:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
PRUnichar * title;
|
2005-08-18 11:15:44 +00:00
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
entry->GetLayoutHistoryState(getter_AddRefs(layoutHistoryState));
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(entry));
|
|
|
|
if (hEntry) {
|
|
|
|
hEntry->GetURI(getter_AddRefs(uri));
|
|
|
|
hEntry->GetTitle(&title);
|
|
|
|
}
|
2005-08-18 11:15:14 +00:00
|
|
|
|
2005-08-18 11:16:35 +00:00
|
|
|
#if 0
|
|
|
|
nsCAutoString url;
|
2005-08-18 11:15:34 +00:00
|
|
|
if (uri)
|
2005-08-18 11:16:35 +00:00
|
|
|
uri->GetSpec(url);
|
2005-08-18 11:15:14 +00:00
|
|
|
|
2005-08-18 11:15:55 +00:00
|
|
|
printf("**** SH Transaction #%d, Entry = %x\n", index, entry.get());
|
|
|
|
printf("\t\t URL = %s\n", url);
|
2005-08-18 11:16:28 +00:00
|
|
|
printf("\t\t Title = %s\n", NS_LossyConvertUCS2toASCII(title).get());
|
2005-08-18 11:15:55 +00:00
|
|
|
printf("\t\t layout History Data = %x\n", layoutHistoryState);
|
2005-08-18 11:16:28 +00:00
|
|
|
#endif
|
2005-08-18 11:15:14 +00:00
|
|
|
|
2005-08-18 11:16:28 +00:00
|
|
|
nsMemory::Free(title);
|
2005-08-18 11:15:44 +00:00
|
|
|
|
2005-08-18 11:15:14 +00:00
|
|
|
|
2005-08-18 11:15:33 +00:00
|
|
|
nsCOMPtr<nsISHTransaction> next;
|
|
|
|
rv = txn->GetNext(getter_AddRefs(next));
|
|
|
|
if (NS_SUCCEEDED(rv) && next) {
|
|
|
|
txn = next;
|
2005-08-18 11:15:14 +00:00
|
|
|
index++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetRootTransaction(nsISHTransaction ** aResult)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsISHEntry> entry;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult=mListRoot;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:59 +00:00
|
|
|
/* Get the max size of the history list */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetMaxLength(PRInt32 * aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
*aResult = gHistoryMaxSize;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the max size of the history list */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::SetMaxLength(PRInt32 aMaxSize)
|
|
|
|
{
|
|
|
|
if (aMaxSize < 0)
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
|
|
|
|
gHistoryMaxSize = aMaxSize;
|
2005-08-18 11:16:17 +00:00
|
|
|
if (mLength > aMaxSize)
|
|
|
|
PurgeHistory(mLength-aMaxSize);
|
2005-08-18 11:15:59 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::PurgeHistory(PRInt32 aEntries)
|
|
|
|
{
|
|
|
|
if (mLength <= 0 || aEntries <= 0)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2005-08-18 11:16:00 +00:00
|
|
|
PRBool purgeHistory = PR_TRUE;
|
|
|
|
// Notify the listener about the history purge
|
|
|
|
if (mListener) {
|
2005-08-18 11:16:04 +00:00
|
|
|
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
|
2005-08-18 11:16:00 +00:00
|
|
|
if (listener) {
|
|
|
|
listener->OnHistoryPurge(aEntries, &purgeHistory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!purgeHistory) {
|
|
|
|
// Listener asked us not to purge
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 cnt = 0;
|
2005-08-18 11:15:59 +00:00
|
|
|
while (cnt < aEntries) {
|
|
|
|
nsCOMPtr<nsISHTransaction> txn = mListRoot;
|
|
|
|
nsCOMPtr<nsISHTransaction> nextTxn;
|
|
|
|
if (mListRoot)
|
|
|
|
mListRoot->GetNext(getter_AddRefs(nextTxn));
|
|
|
|
txn = nsnull;
|
|
|
|
mListRoot = nextTxn;
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
mLength -= cnt;
|
|
|
|
mIndex -= cnt;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:00 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::AddSHistoryListener(nsISHistoryListener * aListener)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aListener);
|
|
|
|
|
|
|
|
// Check if the listener supports Weak Reference. This is a must.
|
|
|
|
// This listener functionality is used by embedders and we want to
|
|
|
|
// have the right ownership with who ever listens to SHistory
|
2005-08-18 11:16:50 +00:00
|
|
|
nsWeakPtr listener = do_GetWeakReference(aListener);
|
2005-08-18 11:16:00 +00:00
|
|
|
if (!listener) return NS_ERROR_FAILURE;
|
|
|
|
mListener = listener;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::RemoveSHistoryListener(nsISHistoryListener * aListener)
|
|
|
|
{
|
2005-08-18 11:16:22 +00:00
|
|
|
// Make sure the listener that wants to be removed is the
|
|
|
|
// one we have in store.
|
2005-08-18 11:16:50 +00:00
|
|
|
nsWeakPtr listener = do_GetWeakReference(aListener);
|
2005-08-18 11:16:22 +00:00
|
|
|
if (listener == mListener) {
|
|
|
|
mListener = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:24 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:30 +00:00
|
|
|
/* Get a handle to the Session history listener */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetListener(nsISHistoryListener ** aListener)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aListener);
|
|
|
|
if (mListener)
|
|
|
|
CallQueryReferent(mListener.get(), aListener);
|
|
|
|
// Don't addref aListener. It is a weak pointer.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
//*****************************************************************************
|
|
|
|
// nsSHistory: nsIWebNavigation
|
|
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetCanGoBack(PRBool * aCanGoBack)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCanGoBack);
|
|
|
|
*aCanGoBack = PR_FALSE;
|
|
|
|
|
|
|
|
PRInt32 index = -1;
|
|
|
|
NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
|
|
|
|
if(index > 0)
|
|
|
|
*aCanGoBack = PR_TRUE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetCanGoForward(PRBool * aCanGoForward)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aCanGoForward);
|
|
|
|
*aCanGoForward = PR_FALSE;
|
|
|
|
|
|
|
|
PRInt32 index = -1;
|
|
|
|
PRInt32 count = -1;
|
|
|
|
|
|
|
|
NS_ENSURE_SUCCESS(GetIndex(&index), NS_ERROR_FAILURE);
|
|
|
|
NS_ENSURE_SUCCESS(GetCount(&count), NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
if((index >= 0) && (index < (count - 1)))
|
|
|
|
*aCanGoForward = PR_TRUE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-18 11:15:37 +00:00
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GoBack()
|
|
|
|
{
|
|
|
|
PRBool canGoBack = PR_FALSE;
|
|
|
|
|
|
|
|
GetCanGoBack(&canGoBack);
|
|
|
|
if (!canGoBack) // Can't go back
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2005-08-18 11:16:17 +00:00
|
|
|
return LoadEntry(mIndex-1, nsIDocShellLoadInfo::loadHistory, HIST_CMD_BACK);
|
2005-08-18 11:15:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GoForward()
|
|
|
|
{
|
|
|
|
PRBool canGoForward = PR_FALSE;
|
|
|
|
|
|
|
|
GetCanGoForward(&canGoForward);
|
|
|
|
if (!canGoForward) // Can't go forward
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
2005-08-18 11:16:17 +00:00
|
|
|
return LoadEntry(mIndex+1, nsIDocShellLoadInfo::loadHistory, HIST_CMD_FORWARD);
|
2005-08-18 11:15:34 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:15:51 +00:00
|
|
|
nsSHistory::Reload(PRUint32 aReloadFlags)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
2005-08-18 11:16:00 +00:00
|
|
|
nsresult rv;
|
2005-08-18 11:15:51 +00:00
|
|
|
nsDocShellInfoLoadType loadType;
|
|
|
|
if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY &&
|
|
|
|
aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
|
|
|
|
{
|
|
|
|
loadType = nsIDocShellLoadInfo::loadReloadBypassProxyAndCache;
|
|
|
|
}
|
|
|
|
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY)
|
|
|
|
{
|
|
|
|
loadType = nsIDocShellLoadInfo::loadReloadBypassProxy;
|
|
|
|
}
|
|
|
|
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
|
|
|
|
{
|
|
|
|
loadType = nsIDocShellLoadInfo::loadReloadBypassCache;
|
|
|
|
}
|
2005-08-18 11:16:06 +00:00
|
|
|
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE)
|
|
|
|
{
|
|
|
|
loadType = nsIDocShellLoadInfo::loadReloadCharsetChange;
|
|
|
|
}
|
|
|
|
else
|
2005-08-18 11:15:51 +00:00
|
|
|
{
|
|
|
|
loadType = nsIDocShellLoadInfo::loadReloadNormal;
|
|
|
|
}
|
2005-08-18 11:16:00 +00:00
|
|
|
|
|
|
|
// Notify listeners
|
|
|
|
PRBool canNavigate = PR_TRUE;
|
|
|
|
if (mListener) {
|
2005-08-18 11:16:04 +00:00
|
|
|
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
|
2005-08-18 11:16:00 +00:00
|
|
|
// We are reloading. Send Reload notifications.
|
|
|
|
// nsDocShellLoadFlagType is not public, where as nsIWebNavigation
|
|
|
|
// is public. So send the reload notifications with the
|
|
|
|
// nsIWebNavigation flags.
|
|
|
|
if (listener) {
|
|
|
|
nsCOMPtr<nsIURI> currentURI;
|
|
|
|
rv = GetCurrentURI(getter_AddRefs(currentURI));
|
|
|
|
listener->OnHistoryReload(currentURI, aReloadFlags, &canNavigate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!canNavigate)
|
|
|
|
return NS_OK;
|
|
|
|
|
2005-08-18 11:16:17 +00:00
|
|
|
return LoadEntry(mIndex, loadType, HIST_CMD_RELOAD);
|
2005-08-18 11:15:34 +00:00
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:15 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::UpdateIndex()
|
|
|
|
{
|
|
|
|
// Update the actual index with the right value.
|
2005-08-18 11:16:23 +00:00
|
|
|
if (mIndex != mRequestedIndex && mRequestedIndex != -1)
|
|
|
|
mIndex = mRequestedIndex;
|
2005-08-18 11:16:15 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:05 +00:00
|
|
|
nsSHistory::Stop(PRUint32 aStopFlags)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
|
|
|
//Not implemented
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetDocument(nsIDOMDocument** aDocument)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Not implemented
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:00 +00:00
|
|
|
nsSHistory::GetCurrentURI(nsIURI** aResultURI)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
2005-08-18 11:16:00 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aResultURI);
|
2005-08-18 11:16:01 +00:00
|
|
|
nsresult rv;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIHistoryEntry> currentEntry;
|
|
|
|
rv = GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(currentEntry));
|
2005-08-18 11:16:00 +00:00
|
|
|
if (NS_FAILED(rv) && !currentEntry) return rv;
|
2005-08-18 11:16:01 +00:00
|
|
|
rv = currentEntry->GetURI(aResultURI);
|
|
|
|
return rv;
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
2005-08-18 11:15:34 +00:00
|
|
|
|
|
|
|
|
2005-08-18 11:16:29 +00:00
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:40 +00:00
|
|
|
nsSHistory::GetReferringURI(nsIURI** aURI)
|
2005-08-18 11:16:29 +00:00
|
|
|
{
|
|
|
|
*aURI = nsnull;
|
|
|
|
// Not implemented
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::SetSessionHistory(nsISHistory* aSessionHistory)
|
|
|
|
{
|
|
|
|
// Not implemented
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetSessionHistory(nsISHistory** aSessionHistory)
|
|
|
|
{
|
|
|
|
// Not implemented
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:29 +00:00
|
|
|
nsSHistory::LoadURI(const PRUnichar* aURI,
|
|
|
|
PRUint32 aLoadFlags,
|
2005-08-18 11:16:40 +00:00
|
|
|
nsIURI* aReferringURI,
|
2005-08-18 11:16:29 +00:00
|
|
|
nsIInputStream* aPostStream,
|
|
|
|
nsIInputStream* aExtraHeaderStream)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GotoIndex(PRInt32 aIndex)
|
2005-08-18 11:15:37 +00:00
|
|
|
{
|
2005-08-18 11:16:17 +00:00
|
|
|
return LoadEntry(aIndex, nsIDocShellLoadInfo::loadHistory, HIST_CMD_GOTOINDEX);
|
2005-08-18 11:15:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-08-18 11:16:17 +00:00
|
|
|
nsSHistory::LoadEntry(PRInt32 aIndex, long aLoadType, PRUint32 aHistCmd)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIDocShell> docShell;
|
|
|
|
nsCOMPtr<nsISHEntry> shEntry;
|
2005-08-18 11:16:15 +00:00
|
|
|
// Keep note of requested history index in mRequestedIndex.
|
|
|
|
mRequestedIndex = aIndex;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsISHEntry> prevEntry;
|
2005-08-18 11:16:15 +00:00
|
|
|
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(prevEntry));
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsISHEntry> nextEntry;
|
2005-08-18 11:16:15 +00:00
|
|
|
GetEntryAtIndex(mRequestedIndex, PR_FALSE, getter_AddRefs(nextEntry));
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIHistoryEntry> nHEntry(do_QueryInterface(nextEntry));
|
2005-08-18 11:16:15 +00:00
|
|
|
if (!nextEntry || !prevEntry || !nHEntry) {
|
|
|
|
mRequestedIndex = -1;
|
2005-08-18 11:16:01 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:16:07 +00:00
|
|
|
}
|
2005-08-18 11:16:01 +00:00
|
|
|
|
2005-08-18 11:16:00 +00:00
|
|
|
// Send appropriate listener notifications
|
|
|
|
PRBool canNavigate = PR_TRUE;
|
2005-08-18 11:16:01 +00:00
|
|
|
// Get the uri for the entry we are about to visit
|
|
|
|
nsCOMPtr<nsIURI> nextURI;
|
|
|
|
nHEntry->GetURI(getter_AddRefs(nextURI));
|
2005-08-18 11:16:15 +00:00
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
if(mListener) {
|
2005-08-18 11:16:04 +00:00
|
|
|
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
|
2005-08-18 11:16:00 +00:00
|
|
|
if (listener) {
|
2005-08-18 11:16:17 +00:00
|
|
|
if (aHistCmd == HIST_CMD_BACK) {
|
2005-08-18 11:16:00 +00:00
|
|
|
// We are going back one entry. Send GoBack notifications
|
2005-08-18 11:16:01 +00:00
|
|
|
listener->OnHistoryGoBack(nextURI, &canNavigate);
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
2005-08-18 11:16:17 +00:00
|
|
|
else if (aHistCmd == HIST_CMD_FORWARD) {
|
2005-08-18 11:16:00 +00:00
|
|
|
// We are going forward. Send GoForward notification
|
2005-08-18 11:16:01 +00:00
|
|
|
listener->OnHistoryGoForward(nextURI, &canNavigate);
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
2005-08-18 11:16:17 +00:00
|
|
|
else if (aHistCmd == HIST_CMD_GOTOINDEX) {
|
2005-08-18 11:16:00 +00:00
|
|
|
// We are going somewhere else. This is not reload either
|
2005-08-18 11:16:26 +00:00
|
|
|
listener->OnHistoryGotoIndex(aIndex, nextURI, &canNavigate);
|
2005-08-18 11:16:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!canNavigate) {
|
2005-08-18 11:16:15 +00:00
|
|
|
// If the listener asked us not to proceed with
|
|
|
|
// the operation, simply return.
|
2005-08-18 11:16:00 +00:00
|
|
|
return NS_OK; // XXX Maybe I can return some other error code?
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
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);
|
|
|
|
}
|
2005-08-18 11:15:43 +00:00
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
2005-08-18 11:16:15 +00:00
|
|
|
if (mRequestedIndex == mIndex) {
|
2005-08-18 11:16:01 +00:00
|
|
|
// 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
|
|
|
|
*/
|
2005-08-18 11:16:33 +00:00
|
|
|
PRBool frameFound = PR_FALSE;
|
|
|
|
nsresult rv = CompareFrames(prevEntry, nextEntry, mRootDocShell, aLoadType, &frameFound);
|
|
|
|
if (!frameFound) {
|
|
|
|
// we did not successfully find the subframe in which
|
|
|
|
// the new url was to be loaded. return error.
|
2005-08-18 11:16:15 +00:00
|
|
|
mRequestedIndex = -1;
|
2005-08-18 11:16:33 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:16:01 +00:00
|
|
|
}
|
2005-08-18 11:16:33 +00:00
|
|
|
return rv;
|
2005-08-18 11:16:01 +00:00
|
|
|
} // (pCount >0)
|
|
|
|
else
|
|
|
|
docShell = mRootDocShell;
|
|
|
|
}
|
2005-08-18 11:15:43 +00:00
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
if (!docShell) {
|
2005-08-18 11:16:07 +00:00
|
|
|
// we did not successfully go to the proper index.
|
2005-08-18 11:16:15 +00:00
|
|
|
// return error.
|
|
|
|
mRequestedIndex = -1;
|
2005-08-18 11:16:01 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:16:07 +00:00
|
|
|
}
|
2005-08-18 11:16:01 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
// Start the load on the appropriate docshell
|
|
|
|
return InitiateLoad(nextEntry, docShell, aLoadType);
|
2005-08-18 11:15:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-18 11:16:23 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
nsresult
|
|
|
|
nsSHistory::CompareFrames(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsIDocShell * aParent, long aLoadType, PRBool * aIsFrameFound)
|
2005-08-18 11:15:34 +00:00
|
|
|
{
|
2005-08-18 11:16:33 +00:00
|
|
|
if (!aPrevEntry || !aNextEntry || !aParent)
|
|
|
|
return PR_FALSE;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
nsresult result = NS_OK;
|
|
|
|
PRUint32 prevID, nextID;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
aPrevEntry->GetID(&prevID);
|
|
|
|
aNextEntry->GetID(&nextID);
|
2005-08-18 11:15:56 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
// Check the IDs to verify if the pages are different.
|
|
|
|
if (prevID != nextID) {
|
|
|
|
if (aIsFrameFound)
|
|
|
|
*aIsFrameFound = PR_TRUE;
|
|
|
|
// Set the Subframe flag of the entry to indicate that
|
|
|
|
// it is subframe navigation
|
|
|
|
aNextEntry->SetIsSubFrame(PR_TRUE);
|
|
|
|
InitiateLoad(aNextEntry, aParent, aLoadType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
/* The root entries are the same, so compare any child frames */
|
2005-08-18 11:16:46 +00:00
|
|
|
PRInt32 pcnt=0, ncnt=0, dsCount=0;
|
2005-08-18 11:16:33 +00:00
|
|
|
nsCOMPtr<nsISHContainer> prevContainer(do_QueryInterface(aPrevEntry));
|
|
|
|
nsCOMPtr<nsISHContainer> nextContainer(do_QueryInterface(aNextEntry));
|
|
|
|
nsCOMPtr<nsIDocShellTreeNode> dsTreeNode(do_QueryInterface(aParent));
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
if (!dsTreeNode)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (!prevContainer || !nextContainer)
|
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:02 +00:00
|
|
|
prevContainer->GetChildCount(&pcnt);
|
|
|
|
nextContainer->GetChildCount(&ncnt);
|
|
|
|
dsTreeNode->GetChildCount(&dsCount);
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:02 +00:00
|
|
|
//XXX What to do if the children count don't match
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:02 +00:00
|
|
|
for (PRInt32 i=0; i<ncnt; i++){
|
2005-08-18 11:15:34 +00:00
|
|
|
nsCOMPtr<nsISHEntry> pChild, nChild;
|
2005-08-18 11:16:02 +00:00
|
|
|
nsCOMPtr<nsIDocShellTreeItem> dsTreeItemChild;
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:02 +00:00
|
|
|
prevContainer->GetChildAt(i, getter_AddRefs(pChild));
|
2005-08-18 11:15:34 +00:00
|
|
|
nextContainer->GetChildAt(i, getter_AddRefs(nChild));
|
2005-08-18 11:16:02 +00:00
|
|
|
if (dsCount > 0)
|
|
|
|
dsTreeNode->GetChildAt(i, getter_AddRefs(dsTreeItemChild));
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:15:39 +00:00
|
|
|
if (!dsTreeItemChild)
|
2005-08-18 11:16:33 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-08-18 11:15:39 +00:00
|
|
|
|
2005-08-18 11:16:02 +00:00
|
|
|
nsCOMPtr<nsIDocShell> dsChild(do_QueryInterface(dsTreeItemChild));
|
2005-08-18 11:15:34 +00:00
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
CompareFrames(pChild, nChild, dsChild, aLoadType, aIsFrameFound);
|
2005-08-18 11:15:34 +00:00
|
|
|
}
|
2005-08-18 11:16:33 +00:00
|
|
|
return result;
|
2005-08-18 11:15:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-18 11:16:33 +00:00
|
|
|
nsresult
|
|
|
|
nsSHistory::InitiateLoad(nsISHEntry * aFrameEntry, nsIDocShell * aFrameDS, long aLoadType)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
*/
|
|
|
|
aFrameEntry->SetLoadType(aLoadType);
|
|
|
|
aFrameDS->CreateLoadInfo (getter_AddRefs(loadInfo));
|
|
|
|
|
|
|
|
loadInfo->SetLoadType(aLoadType);
|
|
|
|
loadInfo->SetSHEntry(aFrameEntry);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> nextURI;
|
|
|
|
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aFrameEntry));
|
|
|
|
hEntry->GetURI(getter_AddRefs(nextURI));
|
|
|
|
// Time to initiate a document load
|
2005-08-18 11:16:34 +00:00
|
|
|
return aFrameDS->LoadURI(nextURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE);
|
2005-08-18 11:16:33 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-08-18 11:15:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::SetRootDocShell(nsIDocShell * aDocShell)
|
|
|
|
{
|
|
|
|
mRootDocShell = aDocShell;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetRootDocShell(nsIDocShell ** aDocShell)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aDocShell);
|
|
|
|
|
|
|
|
*aDocShell = mRootDocShell;
|
|
|
|
//Not refcounted. May this method should not be available for public
|
|
|
|
// NS_IF_ADDREF(*aDocShell);
|
|
|
|
return NS_OK;
|
2005-08-18 11:15:35 +00:00
|
|
|
}
|
|
|
|
|
2005-08-18 11:16:01 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSHistory::GetSHistoryEnumerator(nsISimpleEnumerator** aEnumerator)
|
|
|
|
{
|
|
|
|
nsresult status = NS_OK;
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aEnumerator);
|
|
|
|
nsSHEnumerator * iterator = new nsSHEnumerator(this);
|
2005-08-18 11:16:25 +00:00
|
|
|
if (iterator && NS_FAILED(status = CallQueryInterface(iterator, aEnumerator)))
|
2005-08-18 11:16:01 +00:00
|
|
|
delete iterator;
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
|
|
//*** nsSHEnumerator: Object Management
|
|
|
|
//*****************************************************************************
|
|
|
|
|
|
|
|
nsSHEnumerator::nsSHEnumerator(nsSHistory * aSHistory):mIndex(-1)
|
|
|
|
{
|
|
|
|
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);
|
2005-08-18 11:16:04 +00:00
|
|
|
if (mIndex >= -1 && mIndex < (cnt-1) ) {
|
2005-08-18 11:16:01 +00:00
|
|
|
*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;
|
|
|
|
}
|