зеркало из https://github.com/mozilla/pjs.git
Add support for caching content viewers in session history to speed up back/forward (bug 274784). This initial landing has the feature disabled by default; set browser.sessionhistory.max_viewers to the maximum number of pages to cache to enable the feature. r=bzbarsky, sr/a=brendan.
This commit is contained in:
Родитель
7e7578bb1f
Коммит
e3bc99eb80
|
@ -53,30 +53,30 @@ interface nsIURI;
|
||||||
interface nsIHistoryEntry : nsISupports
|
interface nsIHistoryEntry : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A readonly property that returns the URI
|
* A readonly property that returns the URI
|
||||||
* of the current entry. The object returned is
|
* of the current entry. The object returned is
|
||||||
* of type nsIURI
|
* of type nsIURI
|
||||||
*/
|
*/
|
||||||
readonly attribute nsIURI URI;
|
readonly attribute nsIURI URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A readonly property that returns the title
|
* A readonly property that returns the title
|
||||||
* of the current entry. The object returned
|
* of the current entry. The object returned
|
||||||
* is a encoded string
|
* is a encoded string
|
||||||
*/
|
*/
|
||||||
readonly attribute wstring title;
|
readonly attribute wstring title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A readonly property that returns a boolean
|
* A readonly property that returns a boolean
|
||||||
* flag which indicates if the entry was created as a
|
* flag which indicates if the entry was created as a
|
||||||
* result of a subframe navigation. This flag will be
|
* result of a subframe navigation. This flag will be
|
||||||
* 'false' when a frameset page is visited for
|
* 'false' when a frameset page is visited for
|
||||||
* the first time. This flag will be 'true' for all
|
* the first time. This flag will be 'true' for all
|
||||||
* history entries created as a result of a subframe
|
* history entries created as a result of a subframe
|
||||||
* navigation.
|
* navigation.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean isSubFrame;
|
readonly attribute boolean isSubFrame;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,88 +42,145 @@
|
||||||
* hold all information required to recreate the document from history
|
* hold all information required to recreate the document from history
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "nsISupports.idl"
|
#include "nsIHistoryEntry.idl"
|
||||||
#include "nsIURI.idl"
|
|
||||||
#include "nsIInputStream.idl"
|
|
||||||
|
|
||||||
interface nsILayoutHistoryState;
|
interface nsILayoutHistoryState;
|
||||||
interface nsIDOMDocument;
|
interface nsIContentViewer;
|
||||||
|
interface nsIURI;
|
||||||
|
interface nsIInputStream;
|
||||||
|
interface nsIDocShellTreeItem;
|
||||||
|
interface nsISecureBrowserUIState;
|
||||||
|
interface nsISupportsArray;
|
||||||
|
%{C++
|
||||||
|
struct nsRect;
|
||||||
|
%}
|
||||||
|
[ref] native nsRect(nsRect);
|
||||||
|
|
||||||
[scriptable, uuid(6b596e1f-a3bd-40f9-a7ee-ab3edc7f9960)]
|
[scriptable, uuid(e47bf412-3bc2-4306-a82f-ea2bdf950432)]
|
||||||
interface nsISHEntry : nsISupports
|
interface nsISHEntry : nsIHistoryEntry
|
||||||
{
|
{
|
||||||
|
/** URI for the document */
|
||||||
|
void setURI(in nsIURI aURI);
|
||||||
|
|
||||||
/** URI for the document */
|
/** Referrer URI */
|
||||||
void SetURI(in nsIURI aURI);
|
attribute nsIURI referrerURI;
|
||||||
|
|
||||||
/** Referrer URI */
|
/** Content viewer, for fast restoration of presentation */
|
||||||
attribute nsIURI referrerURI;
|
attribute nsIContentViewer contentViewer;
|
||||||
|
|
||||||
/** DOM Document */
|
/** Whether the content viewer is marked "sticky" */
|
||||||
attribute nsIDOMDocument document;
|
attribute boolean sticky;
|
||||||
|
|
||||||
/** Title for the document */
|
/** Saved state of the global window object */
|
||||||
void SetTitle(in wstring aTitle);
|
attribute nsISupports windowState;
|
||||||
|
|
||||||
/** Post Data for the document */
|
/**
|
||||||
attribute nsIInputStream postData;
|
* Saved position and dimensions of the content viewer; we must adjust the
|
||||||
|
* root view's widget accordingly if this has changed when the presentation
|
||||||
|
* is restored.
|
||||||
|
*/
|
||||||
|
[noscript] void getViewerBounds(in nsRect bounds);
|
||||||
|
[noscript] void setViewerBounds([const] in nsRect bounds);
|
||||||
|
|
||||||
/** LayoutHistoryState for scroll position and form values */
|
/**
|
||||||
attribute nsILayoutHistoryState layoutHistoryState;
|
* Saved child docshells corresponding to contentViewer. There are weak
|
||||||
|
* references since it's assumed that the content viewer's document has
|
||||||
|
* an owning reference to the subdocument for each shell. The child shells
|
||||||
|
* are restored as children of the parent docshell, in this order, when the
|
||||||
|
* parent docshell restores a saved presentation.
|
||||||
|
*/
|
||||||
|
|
||||||
/** parent of this entry */
|
/** Append a child shell to the end of our list. */
|
||||||
attribute nsISHEntry parent;
|
void addChildShell(in nsIDocShellTreeItem shell);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The loadType for this entry. This is typically loadHistory except
|
* Get the child shell at |index|; returns null if |index| is out of bounds.
|
||||||
* when reload is pressed, it has the appropriate reload flag
|
*/
|
||||||
*/
|
nsIDocShellTreeItem childShellAt(in long index);
|
||||||
attribute unsigned long loadType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ID to help identify this entry from others during
|
* Clear the child shell list.
|
||||||
* subframe navigation
|
*/
|
||||||
*/
|
void clearChildShells();
|
||||||
attribute unsigned long ID;
|
|
||||||
|
|
||||||
/**
|
/** Saved security state for the content viewer */
|
||||||
* pageIdentifier is an integer that should be the same for two entries
|
attribute nsISupports securityState;
|
||||||
* attached to the same docshell only if the two entries are entries for the
|
|
||||||
* same page in the sense that one could go from the state represented by one
|
|
||||||
* to the state represented by the other simply by scrolling (so the entries
|
|
||||||
* are separated by an anchor traversal or a subframe navigation in some other
|
|
||||||
* frame).
|
|
||||||
*/
|
|
||||||
attribute unsigned long pageIdentifier;
|
|
||||||
|
|
||||||
/** attribute to set and get the cache key for the entry */
|
/** Saved refresh URI list for the content viewer */
|
||||||
attribute nsISupports cacheKey;
|
attribute nsISupportsArray refreshURIList;
|
||||||
|
|
||||||
/** attribute to indicate whether layoutHistoryState should be saved */
|
/**
|
||||||
attribute boolean saveLayoutStateFlag;
|
* Ensure that the cached presentation members are self-consistent.
|
||||||
|
* If either |contentViewer| or |windowState| are null, then all of the
|
||||||
|
* following members are cleared/reset:
|
||||||
|
* contentViewer, sticky, windowState, viewerBounds, childShells,
|
||||||
|
* refreshURIList.
|
||||||
|
*/
|
||||||
|
void syncPresentationState();
|
||||||
|
|
||||||
/** attribute to indicate whether the page is already expired in cache */
|
/** Title for the document */
|
||||||
attribute boolean expirationStatus;
|
void setTitle(in AString aTitle);
|
||||||
|
|
||||||
/** attribute to indicate the content-type of the document that this
|
/** Post Data for the document */
|
||||||
is a session history entry for */
|
attribute nsIInputStream postData;
|
||||||
attribute ACString contentType;
|
|
||||||
|
/** LayoutHistoryState for scroll position and form values */
|
||||||
|
attribute nsILayoutHistoryState layoutHistoryState;
|
||||||
|
|
||||||
|
/** parent of this entry */
|
||||||
|
attribute nsISHEntry parent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The loadType for this entry. This is typically loadHistory except
|
||||||
|
* when reload is pressed, it has the appropriate reload flag
|
||||||
|
*/
|
||||||
|
attribute unsigned long loadType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ID to help identify this entry from others during
|
||||||
|
* subframe navigation
|
||||||
|
*/
|
||||||
|
attribute unsigned long ID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pageIdentifier is an integer that should be the same for two entries
|
||||||
|
* attached to the same docshell only if the two entries are entries for
|
||||||
|
* the same page in the sense that one could go from the state represented
|
||||||
|
* by one to the state represented by the other simply by scrolling (so the
|
||||||
|
* entries are separated by an anchor traversal or a subframe navigation in
|
||||||
|
* some other frame).
|
||||||
|
*/
|
||||||
|
attribute unsigned long pageIdentifier;
|
||||||
|
|
||||||
|
/** attribute to set and get the cache key for the entry */
|
||||||
|
attribute nsISupports cacheKey;
|
||||||
|
|
||||||
|
/** attribute to indicate whether layoutHistoryState should be saved */
|
||||||
|
attribute boolean saveLayoutStateFlag;
|
||||||
|
|
||||||
|
/** attribute to indicate whether the page is already expired in cache */
|
||||||
|
attribute boolean expirationStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* attribute to indicate the content-type of the document that this
|
||||||
|
* is a session history entry for
|
||||||
|
*/
|
||||||
|
attribute ACString contentType;
|
||||||
|
|
||||||
/** Set/Get scrollers' positon in anchored pages */
|
/** Set/Get scrollers' positon in anchored pages */
|
||||||
void setScrollPosition(in PRInt32 x, in PRInt32 y);
|
void setScrollPosition(in long x, in long y);
|
||||||
void getScrollPosition(out PRInt32 x, out PRInt32 y);
|
void getScrollPosition(out long x, out long y);
|
||||||
|
|
||||||
/** Additional ways to create an entry */
|
/** Additional ways to create an entry */
|
||||||
void create(in nsIURI aURI, in wstring aTitle, in nsIDOMDocument aDocument,
|
void create(in nsIURI URI, in AString title,
|
||||||
in nsIInputStream aInputStream, in nsILayoutHistoryState aHistoryLayoutState,
|
in nsIInputStream inputStream,
|
||||||
in nsISupports aCacheKey, in ACString aContentType);
|
in nsILayoutHistoryState layoutHistoryState,
|
||||||
|
in nsISupports cacheKey, in ACString contentType);
|
||||||
nsISHEntry clone();
|
|
||||||
|
|
||||||
/** Attribute that indicates if this entry is for a subframe navigation */
|
|
||||||
void SetIsSubFrame(in boolean aFlag);
|
|
||||||
|
|
||||||
|
nsISHEntry clone();
|
||||||
|
|
||||||
|
/** Attribute that indicates if this entry is for a subframe navigation */
|
||||||
|
void setIsSubFrame(in boolean aFlag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ interface nsIDocShell;
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
#define NS_SHISTORY_INTERNAL_CID \
|
#define NS_SHISTORY_INTERNAL_CID \
|
||||||
{0xdd335422, 0xb8b8, 0x11d3, {0xbd, 0xc8, 0x00, 0x50, 0x04, 0x0a, 0x9b, 0x44}}
|
{0x5b4cba4c, 0xbf67, 0x499a, {0xae, 0x2c, 0x3f, 0x76, 0x65, 0x6f, 0x4a, 0x4e}}
|
||||||
|
|
||||||
#define NS_SHISTORY_INTERNAL_CONTRACTID "@mozilla.org/browser/shistory-internal;1"
|
#define NS_SHISTORY_INTERNAL_CONTRACTID "@mozilla.org/browser/shistory-internal;1"
|
||||||
%}
|
%}
|
||||||
|
@ -90,4 +90,11 @@ interface nsISHistoryInternal: nsISupports
|
||||||
*/
|
*/
|
||||||
readonly attribute nsISHistoryListener listener;
|
readonly attribute nsISHistoryListener listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evict content viewers until the number of content viewers is no more than
|
||||||
|
* browser.sessionhistory.max_viewers. This is done automatically by
|
||||||
|
* updateIndex(), but should be called explicitly if a new history entry
|
||||||
|
* is added and later has a content viewer set.
|
||||||
|
*/
|
||||||
|
void evictContentViewers();
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,6 +55,7 @@ REQUIRES = xpcom \
|
||||||
layout \
|
layout \
|
||||||
docshell \
|
docshell \
|
||||||
pref \
|
pref \
|
||||||
|
gfx \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = nsSHEntry.cpp \
|
CPPSRCS = nsSHEntry.cpp \
|
||||||
|
|
|
@ -37,11 +37,16 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifdef DEBUG_bryner
|
||||||
|
#define DEBUG_PAGE_CACHE
|
||||||
|
#endif
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#include "nsSHEntry.h"
|
#include "nsSHEntry.h"
|
||||||
#include "nsXPIDLString.h"
|
#include "nsXPIDLString.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsIDocShellLoadInfo.h"
|
#include "nsIDocShellLoadInfo.h"
|
||||||
|
#include "nsIDocShellTreeItem.h"
|
||||||
|
|
||||||
static PRUint32 gEntryID = 0;
|
static PRUint32 gEntryID = 0;
|
||||||
|
|
||||||
|
@ -58,7 +63,9 @@ nsSHEntry::nsSHEntry()
|
||||||
, mIsFrameNavigation(PR_FALSE)
|
, mIsFrameNavigation(PR_FALSE)
|
||||||
, mSaveLayoutState(PR_TRUE)
|
, mSaveLayoutState(PR_TRUE)
|
||||||
, mExpired(PR_FALSE)
|
, mExpired(PR_FALSE)
|
||||||
|
, mSticky(PR_TRUE)
|
||||||
, mParent(nsnull)
|
, mParent(nsnull)
|
||||||
|
, mViewerBounds(0, 0, 0, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +84,21 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
||||||
, mIsFrameNavigation(other.mIsFrameNavigation)
|
, mIsFrameNavigation(other.mIsFrameNavigation)
|
||||||
, mSaveLayoutState(other.mSaveLayoutState)
|
, mSaveLayoutState(other.mSaveLayoutState)
|
||||||
, mExpired(other.mExpired)
|
, mExpired(other.mExpired)
|
||||||
|
, mSticky(PR_TRUE)
|
||||||
// XXX why not copy mContentType?
|
// XXX why not copy mContentType?
|
||||||
, mCacheKey(other.mCacheKey)
|
, mCacheKey(other.mCacheKey)
|
||||||
, mParent(other.mParent)
|
, mParent(other.mParent)
|
||||||
|
, mViewerBounds(0, 0, 0, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsSHEntry::~nsSHEntry()
|
||||||
|
{
|
||||||
|
mChildren.Clear();
|
||||||
|
if (mContentViewer)
|
||||||
|
mContentViewer->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// nsSHEntry: nsISupports
|
// nsSHEntry: nsISupports
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -133,19 +149,35 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsSHEntry::SetDocument(nsIDOMDocument* aDocument)
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetContentViewer(nsIContentViewer *aViewer)
|
||||||
{
|
{
|
||||||
mDocument = aDocument;
|
mContentViewer = aViewer;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsSHEntry::GetDocument(nsIDOMDocument** aResult)
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetContentViewer(nsIContentViewer **aResult)
|
||||||
{
|
{
|
||||||
*aResult = mDocument;
|
*aResult = mContentViewer;
|
||||||
NS_IF_ADDREF(*aResult);
|
NS_IF_ADDREF(*aResult);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetSticky(PRBool aSticky)
|
||||||
|
{
|
||||||
|
mSticky = aSticky;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetSticky(PRBool *aSticky)
|
||||||
|
{
|
||||||
|
*aSticky = mSticky;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle)
|
NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle)
|
||||||
{
|
{
|
||||||
// Check for empty title...
|
// Check for empty title...
|
||||||
|
@ -160,7 +192,7 @@ NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsSHEntry::SetTitle(const PRUnichar* aTitle)
|
NS_IMETHODIMP nsSHEntry::SetTitle(const nsAString &aTitle)
|
||||||
{
|
{
|
||||||
mTitle = aTitle;
|
mTitle = aTitle;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -297,14 +329,13 @@ NS_IMETHODIMP nsSHEntry::SetContentType(const nsACString& aContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle,
|
nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle,
|
||||||
nsIDOMDocument * aDOMDocument, nsIInputStream * aInputStream,
|
nsIInputStream * aInputStream,
|
||||||
nsILayoutHistoryState * aHistoryLayoutState,
|
nsILayoutHistoryState * aLayoutHistoryState,
|
||||||
nsISupports * aCacheKey, const nsACString& aContentType)
|
nsISupports * aCacheKey, const nsACString& aContentType)
|
||||||
{
|
{
|
||||||
mURI = aURI;
|
mURI = aURI;
|
||||||
mTitle = aTitle;
|
mTitle = aTitle;
|
||||||
mDocument = aDOMDocument;
|
|
||||||
mPostData = aInputStream;
|
mPostData = aInputStream;
|
||||||
mCacheKey = aCacheKey;
|
mCacheKey = aCacheKey;
|
||||||
mContentType = aContentType;
|
mContentType = aContentType;
|
||||||
|
@ -317,9 +348,9 @@ nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle,
|
||||||
// all subframe navigations, sets the flag to true.
|
// all subframe navigations, sets the flag to true.
|
||||||
mIsFrameNavigation = PR_FALSE;
|
mIsFrameNavigation = PR_FALSE;
|
||||||
|
|
||||||
// By default we save HistoryLayoutState
|
// By default we save LayoutHistoryState
|
||||||
mSaveLayoutState = PR_TRUE;
|
mSaveLayoutState = PR_TRUE;
|
||||||
mLayoutHistoryState = aHistoryLayoutState;
|
mLayoutHistoryState = aLayoutHistoryState;
|
||||||
|
|
||||||
//By default the page is not expired
|
//By default the page is not expired
|
||||||
mExpired = PR_FALSE;
|
mExpired = PR_FALSE;
|
||||||
|
@ -358,6 +389,34 @@ nsSHEntry::SetParent(nsISHEntry * aParent)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetWindowState(nsISupports *aState)
|
||||||
|
{
|
||||||
|
mWindowState = aState;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetWindowState(nsISupports **aState)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(*aState = mWindowState);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetViewerBounds(const nsRect &aBounds)
|
||||||
|
{
|
||||||
|
mViewerBounds = aBounds;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetViewerBounds(nsRect &aBounds)
|
||||||
|
{
|
||||||
|
aBounds = mViewerBounds;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// nsSHEntry: nsISHContainer
|
// nsSHEntry: nsISHContainer
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -416,3 +475,77 @@ nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult)
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aShell, "Null child shell added to history entry");
|
||||||
|
mChildShells.AppendElement(aShell);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::ChildShellAt(PRInt32 aIndex, nsIDocShellTreeItem **aShell)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(*aShell =
|
||||||
|
NS_STATIC_CAST(nsIDocShellTreeItem*,
|
||||||
|
mChildShells.SafeElementAt(aIndex)));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::ClearChildShells()
|
||||||
|
{
|
||||||
|
mChildShells.Clear();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetSecurityState(nsISupports **aState)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(*aState = mSecurityState);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetSecurityState(nsISupports *aState)
|
||||||
|
{
|
||||||
|
mSecurityState = aState;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::GetRefreshURIList(nsISupportsArray **aList)
|
||||||
|
{
|
||||||
|
NS_IF_ADDREF(*aList = mRefreshURIList);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SetRefreshURIList(nsISupportsArray *aList)
|
||||||
|
{
|
||||||
|
mRefreshURIList = aList;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHEntry::SyncPresentationState()
|
||||||
|
{
|
||||||
|
if (mContentViewer && mWindowState) {
|
||||||
|
// If we have a content viewer and a window state, we should be ok.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not, then nuke all of the presentation-related members.
|
||||||
|
if (mContentViewer)
|
||||||
|
mContentViewer->SetHistoryEntry(nsnull);
|
||||||
|
|
||||||
|
mContentViewer = nsnull;
|
||||||
|
mSticky = PR_TRUE;
|
||||||
|
mWindowState = nsnull;
|
||||||
|
mViewerBounds.SetRect(0, 0, 0, 0);
|
||||||
|
mChildShells.Clear();
|
||||||
|
mSecurityState = nsnull;
|
||||||
|
mRefreshURIList = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -44,9 +44,10 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
#include "nsVoidArray.h"
|
||||||
|
|
||||||
// Interfaces needed
|
// Interfaces needed
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIContentViewer.h"
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsILayoutHistoryState.h"
|
#include "nsILayoutHistoryState.h"
|
||||||
#include "nsISHEntry.h"
|
#include "nsISHEntry.h"
|
||||||
|
@ -54,9 +55,10 @@
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIEnumerator.h"
|
#include "nsIEnumerator.h"
|
||||||
#include "nsIHistoryEntry.h"
|
#include "nsIHistoryEntry.h"
|
||||||
|
#include "nsRect.h"
|
||||||
|
#include "nsSupportsArray.h"
|
||||||
|
|
||||||
class nsSHEntry : public nsIHistoryEntry,
|
class nsSHEntry : public nsISHEntry,
|
||||||
public nsISHEntry,
|
|
||||||
public nsISHContainer
|
public nsISHContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -69,11 +71,11 @@ public:
|
||||||
NS_DECL_NSISHCONTAINER
|
NS_DECL_NSISHCONTAINER
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~nsSHEntry() { mChildren.Clear(); }
|
~nsSHEntry();
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> mURI;
|
nsCOMPtr<nsIURI> mURI;
|
||||||
nsCOMPtr<nsIURI> mReferrerURI;
|
nsCOMPtr<nsIURI> mReferrerURI;
|
||||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
nsCOMPtr<nsIContentViewer> mContentViewer;
|
||||||
nsString mTitle;
|
nsString mTitle;
|
||||||
nsCOMPtr<nsIInputStream> mPostData;
|
nsCOMPtr<nsIInputStream> mPostData;
|
||||||
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
|
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
|
||||||
|
@ -86,9 +88,15 @@ private:
|
||||||
PRPackedBool mIsFrameNavigation;
|
PRPackedBool mIsFrameNavigation;
|
||||||
PRPackedBool mSaveLayoutState;
|
PRPackedBool mSaveLayoutState;
|
||||||
PRPackedBool mExpired;
|
PRPackedBool mExpired;
|
||||||
|
PRPackedBool mSticky;
|
||||||
nsCString mContentType;
|
nsCString mContentType;
|
||||||
nsCOMPtr<nsISupports> mCacheKey;
|
nsCOMPtr<nsISupports> mCacheKey;
|
||||||
nsISHEntry * mParent; // weak reference
|
nsISHEntry * mParent; // weak reference
|
||||||
|
nsCOMPtr<nsISupports> mWindowState;
|
||||||
|
nsRect mViewerBounds;
|
||||||
|
nsVoidArray mChildShells;
|
||||||
|
nsCOMPtr<nsISupports> mSecurityState;
|
||||||
|
nsCOMPtr<nsISupportsArray> mRefreshURIList;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsSHEntry_h */
|
#endif /* nsSHEntry_h */
|
||||||
|
|
|
@ -54,9 +54,14 @@
|
||||||
#include "nsIDocShellLoadInfo.h"
|
#include "nsIDocShellLoadInfo.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
#include "nsIContentViewer.h"
|
||||||
|
|
||||||
#define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries"
|
#define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries"
|
||||||
|
#define PREF_SHISTORY_VIEWERS "browser.sessionhistory.max_viewers"
|
||||||
|
|
||||||
static PRInt32 gHistoryMaxSize = 50;
|
static PRInt32 gHistoryMaxSize = 50;
|
||||||
|
static PRInt32 gHistoryMaxViewers = 0;
|
||||||
|
|
||||||
enum HistCmd{
|
enum HistCmd{
|
||||||
HIST_CMD_BACK,
|
HIST_CMD_BACK,
|
||||||
|
@ -104,11 +109,21 @@ nsSHistory::Init()
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||||
if (prefs) {
|
if (prefs) {
|
||||||
|
// Session history size is only taken from the default prefs branch.
|
||||||
|
// This means that it's only configurable on a per-application basis.
|
||||||
|
// The goal of this is to unbreak users who have inadvertently set their
|
||||||
|
// session history size to -1.
|
||||||
nsCOMPtr<nsIPrefBranch> defaultBranch;
|
nsCOMPtr<nsIPrefBranch> defaultBranch;
|
||||||
prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch));
|
prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch));
|
||||||
if (defaultBranch) {
|
if (defaultBranch) {
|
||||||
defaultBranch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize);
|
defaultBranch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The size of the content viewer cache does not suffer from this problem,
|
||||||
|
// so we allow it to be overridden by user prefs.
|
||||||
|
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
|
||||||
|
if (branch)
|
||||||
|
branch->GetIntPref(PREF_SHISTORY_VIEWERS, &gHistoryMaxViewers);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +222,7 @@ nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aR
|
||||||
if (NS_SUCCEEDED(rv) && (*aResult)) {
|
if (NS_SUCCEEDED(rv) && (*aResult)) {
|
||||||
// Set mIndex to the requested index, if asked to do so..
|
// Set mIndex to the requested index, if asked to do so..
|
||||||
if (aModifyIndex) {
|
if (aModifyIndex) {
|
||||||
|
EvictContentViewers(mIndex, aIndex);
|
||||||
mIndex = aIndex;
|
mIndex = aIndex;
|
||||||
}
|
}
|
||||||
} //entry
|
} //entry
|
||||||
|
@ -476,6 +492,14 @@ nsSHistory::GetListener(nsISHistoryListener ** aListener)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSHistory::EvictContentViewers()
|
||||||
|
{
|
||||||
|
// This is called after a new entry has been appended to the end of the list.
|
||||||
|
EvictContentViewers(mIndex - 1, mIndex);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// nsSHistory: nsIWebNavigation
|
// nsSHistory: nsIWebNavigation
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -583,12 +607,63 @@ nsSHistory::Reload(PRUint32 aReloadFlags)
|
||||||
return LoadEntry(mIndex, loadType, HIST_CMD_RELOAD);
|
return LoadEntry(mIndex, loadType, HIST_CMD_RELOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsSHistory::EvictContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex)
|
||||||
|
{
|
||||||
|
// To enforce the limit on cached content viewers, we need to release all
|
||||||
|
// of the content viewers that are no longer in the "window" that now
|
||||||
|
// ends/begins at aToIndex.
|
||||||
|
|
||||||
|
PRInt32 startIndex, endIndex;
|
||||||
|
if (aToIndex > aFromIndex) { // going forward
|
||||||
|
startIndex = PR_MAX(0, aFromIndex - gHistoryMaxViewers);
|
||||||
|
endIndex = PR_MAX(0, aToIndex - gHistoryMaxViewers);
|
||||||
|
} else { // going backward
|
||||||
|
startIndex = PR_MIN(mLength - 1, aToIndex + gHistoryMaxViewers);
|
||||||
|
endIndex = PR_MIN(mLength - 1, aFromIndex + gHistoryMaxViewers);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsISHTransaction> trans;
|
||||||
|
GetTransactionAtIndex(startIndex, getter_AddRefs(trans));
|
||||||
|
|
||||||
|
for (PRInt32 i = startIndex; trans && i < endIndex; ++i) {
|
||||||
|
nsCOMPtr<nsISHEntry> entry;
|
||||||
|
trans->GetSHEntry(getter_AddRefs(entry));
|
||||||
|
nsCOMPtr<nsIContentViewer> viewer;
|
||||||
|
entry->GetContentViewer(getter_AddRefs(viewer));
|
||||||
|
if (viewer) {
|
||||||
|
#ifdef DEBUG_PAGE_CACHE
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
entry->GetURI(getter_AddRefs(uri));
|
||||||
|
nsCAutoString spec;
|
||||||
|
if (uri)
|
||||||
|
uri->GetSpec(spec);
|
||||||
|
|
||||||
|
printf("Evicting content viewer: %s\n", spec.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
viewer->Destroy();
|
||||||
|
entry->SetContentViewer(nsnull);
|
||||||
|
entry->SyncPresentationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsISHTransaction *temp = trans;
|
||||||
|
temp->GetNext(getter_AddRefs(trans));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsSHistory::UpdateIndex()
|
nsSHistory::UpdateIndex()
|
||||||
{
|
{
|
||||||
// Update the actual index with the right value.
|
// Update the actual index with the right value.
|
||||||
if (mIndex != mRequestedIndex && mRequestedIndex != -1)
|
if (mIndex != mRequestedIndex && mRequestedIndex != -1) {
|
||||||
|
// We've just finished a history navigation (back or forward), so enforce
|
||||||
|
// the max number of content viewers.
|
||||||
|
|
||||||
|
EvictContentViewers(mIndex, mRequestedIndex);
|
||||||
mIndex = mRequestedIndex;
|
mIndex = mRequestedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,8 @@ protected:
|
||||||
nsresult PrintHistory();
|
nsresult PrintHistory();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void EvictContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsISHTransaction> mListRoot;
|
nsCOMPtr<nsISHTransaction> mListRoot;
|
||||||
PRInt32 mIndex;
|
PRInt32 mIndex;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче