fixes bug 260314 "UMR in nsSHEntry::SetLayoutHistoryState + cleanup" r=biesi sr=bzbarsky

git-svn-id: svn://10.0.0.236/trunk@162636 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
darin%meer.net 2004-09-22 00:38:19 +00:00
parent b9bbc0af83
commit a516cdfb48
2 changed files with 154 additions and 190 deletions

View File

@ -43,39 +43,53 @@
#include "nsReadableUtils.h"
#include "nsIDocShellLoadInfo.h"
PRUint32 gEntryID=0;
static PRUint32 gEntryID = 0;
//*****************************************************************************
//*** nsSHEntry: Object Management
//*****************************************************************************
nsSHEntry::nsSHEntry()
: mLoadType(0)
, mID(gEntryID++)
, mScrollPositionX(0)
, mScrollPositionY(0)
, mIsFrameNavigation(PR_FALSE)
, mSaveLayoutState(PR_TRUE)
, mExpired(PR_FALSE)
, mParent(nsnull)
{
mParent = nsnull;
mID = gEntryID++;
}
nsSHEntry::~nsSHEntry()
nsSHEntry::nsSHEntry(const nsSHEntry &other)
: mURI(other.mURI)
, mReferrerURI(other.mReferrerURI)
// XXX why not copy mDocument?
, mTitle(other.mTitle)
, mPostData(other.mPostData)
, mLayoutHistoryState(other.mLayoutHistoryState)
, mLoadType(0) // XXX why not copy?
, mID(other.mID)
, mScrollPositionX(0) // XXX why not copy?
, mScrollPositionY(0) // XXX why not copy?
, mIsFrameNavigation(other.mIsFrameNavigation)
, mSaveLayoutState(other.mSaveLayoutState)
, mExpired(other.mExpired)
// XXX why not copy mContentType?
, mParent(other.mParent)
{
mChildren.Clear();
}
//*****************************************************************************
// nsSHEntry: nsISupports
//*****************************************************************************
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(nsIHistoryEntry)
NS_INTERFACE_MAP_END
NS_IMPL_ISUPPORTS3(nsSHEntry, nsISHContainer, nsISHEntry, nsIHistoryEntry)
//*****************************************************************************
// nsSHEntry: nsISHEntry
//*****************************************************************************
NS_IMETHODIMP nsSHEntry::SetScrollPosition(PRInt32 x, PRInt32 y)
{
mScrollPositionX = x;
@ -85,201 +99,174 @@ NS_IMETHODIMP nsSHEntry::SetScrollPosition(PRInt32 x, PRInt32 y)
NS_IMETHODIMP nsSHEntry::GetScrollPosition(PRInt32 *x, PRInt32 *y)
{
if (x && y) {
*x = mScrollPositionX;
*y = mScrollPositionY;
}
*x = mScrollPositionX;
*y = mScrollPositionY;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetURI(nsIURI** aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
*aURI = mURI;
NS_IF_ADDREF(*aURI);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetURI(nsIURI* aURI)
{
mURI = aURI;
return NS_OK;
mURI = aURI;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetReferrerURI(nsIURI **aReferrerURI)
{
NS_ENSURE_ARG_POINTER(aReferrerURI);
*aReferrerURI = mReferrerURI;
NS_IF_ADDREF(*aReferrerURI);
return NS_OK;
*aReferrerURI = mReferrerURI;
NS_IF_ADDREF(*aReferrerURI);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
{
mReferrerURI = aReferrerURI;
return NS_OK;
mReferrerURI = aReferrerURI;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetDocument(nsIDOMDocument* aDocument)
{
mDocument = aDocument;
return NS_OK;
mDocument = aDocument;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetDocument(nsIDOMDocument** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mDocument;
NS_IF_ADDREF(*aResult);
return NS_OK;
*aResult = mDocument;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle)
{
NS_ENSURE_ARG_POINTER(aTitle);
// Check for empty title...
if (mTitle.IsEmpty() && mURI) {
// Default title is the URL.
nsCAutoString spec;
if (NS_SUCCEEDED(mURI->GetSpec(spec)))
AppendUTF8toUTF16(spec, mTitle);
}
// Check for empty title...
if ( mTitle.IsEmpty() && mURI ) {
// Default title is the URL.
nsCAutoString spec;
if ( NS_SUCCEEDED( mURI->GetSpec( spec ) ) ) {
AppendUTF8toUTF16(spec, mTitle);
}
}
*aTitle = ToNewUnicode(mTitle);
return NS_OK;
*aTitle = ToNewUnicode(mTitle);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetTitle(const PRUnichar* aTitle)
{
mTitle = aTitle;
return NS_OK;
mTitle = aTitle;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetPostData(nsIInputStream** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mPostData;
NS_IF_ADDREF(*aResult);
return NS_OK;
*aResult = mPostData;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetPostData(nsIInputStream* aPostData)
{
mPostData = aPostData;
return NS_OK;
mPostData = aPostData;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mLayoutHistoryState;
NS_IF_ADDREF(*aResult);
return NS_OK;
*aResult = mLayoutHistoryState;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState)
{
NS_ENSURE_STATE(mSaveLayoutState || !aState);
mLayoutHistoryState = aState;
return NS_OK;
NS_ENSURE_STATE(mSaveLayoutState || !aState);
mLayoutHistoryState = aState;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetLoadType(PRUint32 * aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mLoadType;
return NS_OK;
*aResult = mLoadType;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetLoadType(PRUint32 aLoadType)
{
mLoadType = aLoadType;
return NS_OK;
mLoadType = aLoadType;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetID(PRUint32 * aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mID;
return NS_OK;
*aResult = mID;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetID(PRUint32 aID)
{
mID = aID;
return NS_OK;
mID = aID;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetIsSubFrame(PRBool * aFlag)
{
NS_ENSURE_ARG_POINTER(aFlag);
*aFlag = mIsFrameNavigation;
return NS_OK;
*aFlag = mIsFrameNavigation;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetIsSubFrame(PRBool aFlag)
{
mIsFrameNavigation = aFlag;
return NS_OK;
mIsFrameNavigation = aFlag;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetCacheKey(nsISupports** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mCacheKey;
NS_IF_ADDREF(*aResult);
return NS_OK;
*aResult = mCacheKey;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetCacheKey(nsISupports* aCacheKey)
{
mCacheKey = aCacheKey;
return NS_OK;
mCacheKey = aCacheKey;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetSaveLayoutStateFlag(PRBool * aFlag)
{
NS_ENSURE_ARG_POINTER(aFlag);
*aFlag = mSaveLayoutState;
return NS_OK;
*aFlag = mSaveLayoutState;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetSaveLayoutStateFlag(PRBool aFlag)
{
mSaveLayoutState = aFlag;
mSaveLayoutState = aFlag;
// if we are not allowed to hold layout history state, then make sure
// that we are not holding it!
if (!mSaveLayoutState)
mLayoutHistoryState = nsnull;
// if we are not allowed to hold layout history state, then make sure
// that we are not holding it!
if (!mSaveLayoutState)
mLayoutHistoryState = nsnull;
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetExpirationStatus(PRBool * aFlag)
{
NS_ENSURE_ARG_POINTER(aFlag);
*aFlag = mExpired;
return NS_OK;
*aFlag = mExpired;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::SetExpirationStatus(PRBool aFlag)
{
mExpired = aFlag;
return NS_OK;
mExpired = aFlag;
return NS_OK;
}
NS_IMETHODIMP nsSHEntry::GetContentType(nsACString& aContentType)
@ -300,63 +287,41 @@ nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle,
nsILayoutHistoryState * aHistoryLayoutState,
nsISupports * aCacheKey, const nsACString& aContentType)
{
SetURI(aURI);
SetTitle(aTitle);
SetDocument(aDOMDocument);
SetPostData(aInputStream);
SetLayoutHistoryState(aHistoryLayoutState);
SetCacheKey(aCacheKey);
SetContentType(aContentType);
mURI = aURI;
mTitle = aTitle;
mDocument = aDOMDocument;
mPostData = aInputStream;
mCacheKey = aCacheKey;
mContentType = aContentType;
// Set the LoadType by default to loadHistory during creation
SetLoadType((PRInt32)nsIDocShellLoadInfo::loadHistory);
mLoadType = (PRUint32) 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);
mIsFrameNavigation = PR_FALSE;
// By default we save HistoryLayoutState
SetSaveLayoutStateFlag(PR_TRUE);
mSaveLayoutState = PR_TRUE;
mLayoutHistoryState = aHistoryLayoutState;
//By default the page is not expired
SetExpirationStatus(PR_FALSE);
mExpired = PR_FALSE;
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::Clone(nsISHEntry ** aResult)
{
nsresult rv;
nsSHEntry *dest;
dest = new nsSHEntry();
if (!dest) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(dest);
dest->SetURI(mURI);
dest->SetReferrerURI(mReferrerURI);
dest->SetPostData(mPostData);
dest->SetLayoutHistoryState(mLayoutHistoryState);
dest->SetTitle(mTitle.get());
dest->SetParent(mParent);
dest->SetID(mID);
dest->SetIsSubFrame(mIsFrameNavigation);
dest->SetExpirationStatus(mExpired);
dest->SetSaveLayoutStateFlag(mSaveLayoutState);
dest->SetCacheKey(mCacheKey);
rv = dest->QueryInterface(NS_GET_IID(nsISHEntry), (void**) aResult);
NS_RELEASE(dest);
return rv;
*aResult = new nsSHEntry(*this);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetParent(nsISHEntry ** aResult)
{
@ -366,70 +331,71 @@ nsSHEntry::GetParent(nsISHEntry ** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::SetParent(nsISHEntry * aParent)
{
/* parent not Addrefed on purpose to avoid cyclic reference
* Null parent is OK
*/
/* parent not Addrefed on purpose to avoid cyclic reference
* Null parent is OK
*
* XXX this method should not be scriptable if this is the case!!
*/
mParent = aParent;
return NS_OK;
}
//*****************************************************************************
// nsSHEntry: nsISHContainer
//*****************************************************************************
NS_IMETHODIMP
nsSHEntry::GetChildCount(PRInt32 * aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = mChildren.Count();
return NS_OK;
*aCount = mChildren.Count();
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::AddChild(nsISHEntry * aChild, PRInt32 aOffset)
{
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
//
// Bug 52670: Ensure children are added in order.
//
// Later frames in the child list may load faster and get appended
// before earlier frames, causing session history to be scrambled.
// By growing the list here, they are added to the right position.
//
// Assert that aOffset will not be so high as to grow us a lot.
//
NS_ASSERTION(aOffset < (mChildren.Count()+1023), "Large frames array!\n");
//
// Bug 52670: Ensure children are added in order.
//
// Later frames in the child list may load faster and get appended
// before earlier frames, causing session history to be scrambled.
// By growing the list here, they are added to the right position.
//
// Assert that aOffset will not be so high as to grow us a lot.
//
NS_ASSERTION(aOffset < (mChildren.Count()+1023), "Large frames array!\n");
// This implicitly extends the array to include aOffset
mChildren.ReplaceObjectAt(aChild, aOffset);
// This implicitly extends the array to include aOffset
mChildren.ReplaceObjectAt(aChild, aOffset);
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::RemoveChild(nsISHEntry * aChild)
{
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
PRBool childRemoved = mChildren.RemoveObject(aChild);
if (childRemoved) {
aChild->SetParent(nsnull);
}
return NS_OK;
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
PRBool childRemoved = mChildren.RemoveObject(aChild);
if (childRemoved)
aChild->SetParent(nsnull);
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
if (aIndex >= 0 && aIndex < mChildren.Count()) {
*aResult = mChildren[aIndex];
NS_ADDREF(*aResult);
} else {
*aResult = nsnull;
if (aIndex >= 0 && aIndex < mChildren.Count()) {
*aResult = mChildren[aIndex];
}
NS_IF_ADDREF(*aResult);
return NS_OK;
}
return NS_OK;
}

View File

@ -60,18 +60,17 @@ class nsSHEntry : public nsIHistoryEntry,
public nsISHContainer
{
public:
nsSHEntry();
nsSHEntry();
nsSHEntry(const nsSHEntry &other);
NS_DECL_ISUPPORTS
NS_DECL_NSIHISTORYENTRY
NS_DECL_NSISHENTRY
NS_DECL_NSISHCONTAINER
protected:
virtual ~nsSHEntry();
private:
~nsSHEntry() { mChildren.Clear(); }
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIURI> mReferrerURI;
nsCOMPtr<nsIDOMDocument> mDocument;
@ -91,5 +90,4 @@ private:
nsISHEntry * mParent; // weak reference
};
#endif /* nsSHEntry_h */