Initial checin for feature bug 36547. r=self(module owner) No code in this checkin is currently used by

any parts of the build.
This commit is contained in:
radha%netscape.com 2005-08-18 11:15:34 +00:00
Родитель 6c253d950a
Коммит dd100d5434
7 изменённых файлов: 493 добавлений и 8 удалений

Просмотреть файл

@ -50,6 +50,11 @@ interface nsISHContainer : nsISupports
*/
void RemoveChild(in nsISHEntry child);
/**
* Get child at an index
*/
nsISHEntry GetChildAt(in long index);
/**
* Enumerator to walk child list.
*/

Просмотреть файл

@ -53,6 +53,9 @@ attribute nsIInputStream postData;
/** LayoutHistoryState for scroll position and form values */
attribute nsILayoutHistoryState layoutHistoryState;
/** parent of this entry */
attribute nsISHEntry parent;
/** Additional ways to create an entry */
void create(in nsIURI aURI, in wstring aTitle, in nsIDOMDocument aDocument,
in nsIInputStream aInputStream, in nsILayoutHistoryState aHistoryLayoutState);

Просмотреть файл

@ -24,7 +24,9 @@
#include "nsIFactory.idl"
#include "nsISHEntry.idl"
#include "nsISHTransaction.idl"
#include "nsIDocShell.idl"
//interface nsIDocShell;
%{C++
#define NS_SHISTORY_CID \
@ -75,4 +77,9 @@ interface nsISHistory: nsISupports
*/
readonly attribute nsISHTransaction rootTransaction;
/**
* The toplevel docshell object to which this SHistory object belongs to.
*/
attribute nsIDocShell rootDocShell;
};

Просмотреть файл

@ -18,7 +18,6 @@
*
* Contributor(s):
* Radha Kulkarni <radha@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
// Local Includes
@ -31,6 +30,7 @@
nsSHEntry::nsSHEntry()
{
NS_INIT_REFCNT();
mParent = nsnull;
}
nsSHEntry::~nsSHEntry()
@ -46,6 +46,7 @@ NS_IMPL_RELEASE(nsSHEntry)
NS_INTERFACE_MAP_BEGIN(nsSHEntry)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHEntry)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHContainer)
NS_INTERFACE_MAP_ENTRY(nsISHEntry)
NS_INTERFACE_MAP_END
@ -127,7 +128,8 @@ NS_IMETHODIMP nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState)
return NS_OK;
}
NS_IMETHODIMP
nsresult
nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOMDocument,
nsIInputStream * aInputStream, nsILayoutHistoryState * aHistoryLayoutState)
{
@ -139,3 +141,161 @@ nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle, nsIDOMDocument * aDOM
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetParent(nsISHEntry ** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mParent;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::SetParent(nsISHEntry * aParent)
{
/* parent not Addrefed on purpose to avoid cyclic reference
* Null parent is OK
*/
mParent = aParent;
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetChildCount(PRInt32 * aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = mChildren.Count();
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::AddChild(nsISHEntry * aChild)
{
NS_ENSURE_ARG_POINTER(aChild);
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
mChildren.AppendElement((void *)aChild);
NS_ADDREF(aChild);
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::RemoveChild(nsISHEntry * aChild)
{
NS_ENSURE_ARG_POINTER(aChild);
PRBool childRemoved = mChildren.RemoveElement((void *)aChild);
if (childRemoved) {
aChild->SetParent(nsnull);
NS_RELEASE(aChild);
}
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
if (PRUint32(aIndex) >= PRUint32(mChildren.Count())) {
*aResult = nsnull;
}
else {
*aResult = (nsISHEntry*) mChildren.ElementAt(aIndex);
NS_IF_ADDREF(*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;
}

Просмотреть файл

@ -26,30 +26,65 @@
// Helper Classes
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsVoidArray.h"
// Interfaces needed
#include "nsIDOMDocument.h"
#include "nsIInputStream.h"
#include "nsILayoutHistoryState.h"
#include "nsISHEntry.h"
#include "nsISHContainer.h"
#include "nsIURI.h"
#include "nsIEnumerator.h"
class nsSHEntry : public nsISHEntry
// I can probably get rid of the enumerator thing.
class nsSHEnumerator;
class nsSHEntry : public nsISHEntry,
public nsISHContainer
{
public:
nsSHEntry();
NS_DECL_ISUPPORTS
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;
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
nsVoidArray mChildren;
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 */

Просмотреть файл

@ -18,7 +18,6 @@
*
* Contributor(s):
* Radha Kulkarni <radha@netscape.com>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
// Local Includes
@ -30,6 +29,11 @@
// Interfaces Needed
#include "nsIGenericFactory.h"
#include "nsILayoutHistoryState.h"
#include "nsIDocShellLoadInfo.h"
#include "nsXPIDLString.h"
#include "nsISHContainer.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeNode.h"
//*****************************************************************************
//*** nsSHistory: Object Management
@ -231,7 +235,9 @@ nsSHistory::PrintHistory()
txn = mListRoot;
while (1) {
nsCOMPtr<nsISHEntry> entry;
if (!txn)
break;
nsCOMPtr<nsISHEntry> entry;
rv = txn->GetSHEntry(getter_AddRefs(entry));
if (!NS_SUCCEEDED(rv) && !entry)
return NS_ERROR_FAILURE;
@ -249,7 +255,8 @@ nsSHistory::PrintHistory()
nsString titlestr(title);
titleCStr = titlestr.ToNewCString();
uri->GetSpec(getter_Copies(url));
if (uri)
uri->GetSpec(getter_Copies(url));
#if 0
printf("**** SH Transaction #%d, Entry = %x\n", index, entry.get());
@ -287,3 +294,260 @@ nsSHistory::GetRootTransaction(nsISHTransaction ** aResult)
return NS_OK;
}
//*****************************************************************************
// 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;
}
NS_IMETHODIMP
nsSHistory::GoBack()
{
PRBool canGoBack = PR_FALSE;
GetCanGoBack(&canGoBack);
if (!canGoBack) // Can't go back
return NS_ERROR_UNEXPECTED;
return GotoIndex(mIndex-1);
}
NS_IMETHODIMP
nsSHistory::GoForward()
{
PRBool canGoForward = PR_FALSE;
GetCanGoForward(&canGoForward);
if (!canGoForward) // Can't go forward
return NS_ERROR_UNEXPECTED;
return GotoIndex(mIndex+1);
}
NS_IMETHODIMP
nsSHistory::Reload(PRInt32 reloadType)
{
// NOT implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::Stop()
{
//Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::SetDocument(nsIDOMDocument* aDocument,
const PRUnichar* aContentType)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GetDocument(nsIDOMDocument** aDocument)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GetCurrentURI(PRUnichar** aCurrentURI)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::SetSessionHistory(nsISHistory* aSessionHistory)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GetSessionHistory(nsISHistory** aSessionHistory)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::LoadURI(const PRUnichar* aURI)
{
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GotoIndex(PRInt32 aIndex)
{
nsCOMPtr<nsIDocShell> docShell;
nsCOMPtr<nsISHEntry> shEntry;
PRInt32 oldIndex = mIndex;
nsCOMPtr<nsISHEntry> prevEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(prevEntry));
mIndex = aIndex;
nsCOMPtr<nsISHEntry> nextEntry;
GetEntryAtIndex(mIndex, PR_FALSE, getter_AddRefs(nextEntry));
PRBool result = CompareSHEntry(prevEntry, nextEntry, mRootDocShell, getter_AddRefs(docShell), getter_AddRefs(shEntry));
if (!result)
mIndex = oldIndex;
if (!docShell || !shEntry || !mRootDocShell)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> nexturi;
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
shEntry->GetURI(getter_AddRefs(nexturi));
mRootDocShell->CreateLoadInfo (getter_AddRefs(loadInfo));
// This is not available yet
// loadInfo->SetSessionHistoryEntry(nextEntry);
// Time to initiate a document load
return docShell->LoadURI(nexturi, loadInfo);
}
PRBool
nsSHistory::CompareSHEntry(nsISHEntry * aPrevEntry, nsISHEntry * aNextEntry, nsIDocShell * aParent,
nsIDocShell ** aDSResult, nsISHEntry ** aSHEResult)
{
NS_ENSURE_ARG_POINTER(aDSResult);
NS_ENSURE_ARG_POINTER(aSHEResult);
if (!aPrevEntry || !aNextEntry || !aParent)
return PR_FALSE;
nsresult rv;
PRBool result = PR_FALSE;
nsCOMPtr<nsIURI> prevURI, nextURI;
nsXPIDLCString prevUriSpec, nextUriSpec;
// Not reference counted on purpose
nsIDocShell * docshell = aParent;
nsCOMPtr<nsISHEntry> prevEntry = aPrevEntry;
nsCOMPtr<nsISHEntry> nextEntry = aNextEntry;
prevEntry->GetURI(getter_AddRefs(prevURI));
nextEntry->GetURI(getter_AddRefs(nextURI));
if (!prevURI || !nextURI)
return PR_FALSE;
prevURI->GetSpec(getter_Copies(prevUriSpec));
nextURI->GetSpec(getter_Copies(nextUriSpec));
if (!prevUriSpec || !nextUriSpec)
return PR_FALSE;
if (prevUriSpec != nextUriSpec) {
*aDSResult = docshell;
*aSHEResult = nextEntry;
return PR_TRUE;
}
/* compare the child frames */
PRInt32 cnt=0, pcnt=0, ncnt=0, dsCount=0;
nsCOMPtr<nsISHContainer> prevContainer(do_QueryInterface(prevEntry));
nsCOMPtr<nsISHContainer> nextContainer(do_QueryInterface(nextEntry));
//XXX Not ref counted on purpose. Is this correct.?
// How about AddRef in the QueryInterface?
nsIDocShellTreeNode * dsTreeNode = nsnull;
rv = docshell->QueryInterface(NS_GET_IID(nsIDocShellTreeNode), (void **) &dsTreeNode);
if (!NS_SUCCEEDED(rv) || !dsTreeNode)
return PR_FALSE;
prevContainer->GetChildCount(&pcnt);
nextContainer->GetChildCount(&ncnt);
dsTreeNode->GetChildCount(&dsCount);
//XXX What to do if the children count don't match
for (PRInt32 i=0; i<ncnt; i++){
nsCOMPtr<nsISHEntry> pChild, nChild;
nsIDocShellTreeItem * dsTreeItemChild=nsnull;
prevContainer->GetChildAt(i, getter_AddRefs(pChild));
nextContainer->GetChildAt(i, getter_AddRefs(nChild));
dsTreeNode->GetChildAt(i, &dsTreeItemChild);
// XXX How about AddRef in QueryInterface? Is this OK?
nsIDocShell * dsChild = nsnull;
rv = dsTreeItemChild->QueryInterface(NS_GET_IID(nsIDocShell), (void **) dsChild);
result = CompareSHEntry(pChild, nChild, dsChild, aDSResult, aSHEResult);
if (result) // We have found the docshell in which loadUri is to be called.
break;
}
return result;
}
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;
}

Просмотреть файл

@ -29,25 +29,36 @@
//Interfaces Needed
#include "nsISHistory.h"
#include "nsISHTransaction.h"
#include "nsIWebNavigation.h"
class nsSHistory: public nsISHistory
class nsIDocShell;
class nsSHistory: public nsISHistory,
public nsIWebNavigation
{
public:
nsSHistory();
NS_DECL_ISUPPORTS
NS_DECL_NSISHISTORY
NS_DECL_NSIWEBNAVIGATION
protected:
virtual ~nsSHistory();
// Could become part of nsIWebNavigation
NS_IMETHOD GotoIndex(PRInt32 aIndex);
NS_IMETHOD PrintHistory();
NS_IMETHOD GetTransactionAtIndex(PRInt32 aIndex, nsISHTransaction ** aResult);
PRBool CompareSHEntry(nsISHEntry * prevEntry, nsISHEntry * nextEntry, nsIDocShell * rootDocShell,
nsIDocShell ** aResultDocShell, nsISHEntry ** aResultSHEntry);
protected:
nsCOMPtr<nsISHTransaction> mListRoot;
PRInt32 mIndex;
PRInt32 mLength;
// Weak reference. Do not refcount this.
nsIDocShell * mRootDocShell;
};