зеркало из 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
|
||||
{
|
||||
|
||||
/**
|
||||
* A readonly property that returns the URI
|
||||
* of the current entry. The object returned is
|
||||
* of type nsIURI
|
||||
*/
|
||||
readonly attribute nsIURI URI;
|
||||
/**
|
||||
* A readonly property that returns the URI
|
||||
* of the current entry. The object returned is
|
||||
* of type nsIURI
|
||||
*/
|
||||
readonly attribute nsIURI URI;
|
||||
|
||||
/**
|
||||
* A readonly property that returns the title
|
||||
* of the current entry. The object returned
|
||||
* is a encoded string
|
||||
*/
|
||||
readonly attribute wstring title;
|
||||
/**
|
||||
* A readonly property that returns the title
|
||||
* of the current entry. The object returned
|
||||
* is a encoded string
|
||||
*/
|
||||
readonly attribute wstring title;
|
||||
|
||||
/**
|
||||
* A readonly property that returns a boolean
|
||||
* flag which indicates if the entry was created as a
|
||||
* result of a subframe navigation. This flag will be
|
||||
* 'false' when a frameset page is visited for
|
||||
* the first time. This flag will be 'true' for all
|
||||
* history entries created as a result of a subframe
|
||||
* navigation.
|
||||
*/
|
||||
readonly attribute boolean isSubFrame;
|
||||
/**
|
||||
* A readonly property that returns a boolean
|
||||
* flag which indicates if the entry was created as a
|
||||
* result of a subframe navigation. This flag will be
|
||||
* 'false' when a frameset page is visited for
|
||||
* the first time. This flag will be 'true' for all
|
||||
* history entries created as a result of a subframe
|
||||
* navigation.
|
||||
*/
|
||||
readonly attribute boolean isSubFrame;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -42,88 +42,145 @@
|
|||
* hold all information required to recreate the document from history
|
||||
*
|
||||
*/
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIURI.idl"
|
||||
#include "nsIInputStream.idl"
|
||||
#include "nsIHistoryEntry.idl"
|
||||
|
||||
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)]
|
||||
interface nsISHEntry : nsISupports
|
||||
[scriptable, uuid(e47bf412-3bc2-4306-a82f-ea2bdf950432)]
|
||||
interface nsISHEntry : nsIHistoryEntry
|
||||
{
|
||||
/** URI for the document */
|
||||
void setURI(in nsIURI aURI);
|
||||
|
||||
/** URI for the document */
|
||||
void SetURI(in nsIURI aURI);
|
||||
/** Referrer URI */
|
||||
attribute nsIURI referrerURI;
|
||||
|
||||
/** Referrer URI */
|
||||
attribute nsIURI referrerURI;
|
||||
/** Content viewer, for fast restoration of presentation */
|
||||
attribute nsIContentViewer contentViewer;
|
||||
|
||||
/** DOM Document */
|
||||
attribute nsIDOMDocument document;
|
||||
/** Whether the content viewer is marked "sticky" */
|
||||
attribute boolean sticky;
|
||||
|
||||
/** Title for the document */
|
||||
void SetTitle(in wstring aTitle);
|
||||
/** Saved state of the global window object */
|
||||
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 */
|
||||
attribute nsISHEntry parent;
|
||||
/** Append a child shell to the end of our list. */
|
||||
void addChildShell(in nsIDocShellTreeItem shell);
|
||||
|
||||
/**
|
||||
* The loadType for this entry. This is typically loadHistory except
|
||||
* when reload is pressed, it has the appropriate reload flag
|
||||
*/
|
||||
attribute unsigned long loadType;
|
||||
/**
|
||||
* Get the child shell at |index|; returns null if |index| is out of bounds.
|
||||
*/
|
||||
nsIDocShellTreeItem childShellAt(in long index);
|
||||
|
||||
/**
|
||||
* An ID to help identify this entry from others during
|
||||
* subframe navigation
|
||||
*/
|
||||
attribute unsigned long ID;
|
||||
/**
|
||||
* Clear the child shell list.
|
||||
*/
|
||||
void clearChildShells();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
/** Saved security state for the content viewer */
|
||||
attribute nsISupports securityState;
|
||||
|
||||
/** attribute to set and get the cache key for the entry */
|
||||
attribute nsISupports cacheKey;
|
||||
/** Saved refresh URI list for the content viewer */
|
||||
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 */
|
||||
attribute boolean expirationStatus;
|
||||
/** Title for the document */
|
||||
void setTitle(in AString aTitle);
|
||||
|
||||
/** attribute to indicate the content-type of the document that this
|
||||
is a session history entry for */
|
||||
attribute ACString contentType;
|
||||
/** Post Data for the document */
|
||||
attribute nsIInputStream postData;
|
||||
|
||||
/** 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 */
|
||||
void setScrollPosition(in PRInt32 x, in PRInt32 y);
|
||||
void getScrollPosition(out PRInt32 x, out PRInt32 y);
|
||||
/** Set/Get scrollers' positon in anchored pages */
|
||||
void setScrollPosition(in long x, in long y);
|
||||
void getScrollPosition(out long x, out long y);
|
||||
|
||||
/** Additional ways to create an entry */
|
||||
void create(in nsIURI aURI, in wstring aTitle, in nsIDOMDocument aDocument,
|
||||
in nsIInputStream aInputStream, in nsILayoutHistoryState aHistoryLayoutState,
|
||||
in nsISupports aCacheKey, in ACString aContentType);
|
||||
|
||||
nsISHEntry clone();
|
||||
|
||||
/** Attribute that indicates if this entry is for a subframe navigation */
|
||||
void SetIsSubFrame(in boolean aFlag);
|
||||
/** Additional ways to create an entry */
|
||||
void create(in nsIURI URI, in AString title,
|
||||
in nsIInputStream inputStream,
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ interface nsIDocShell;
|
|||
|
||||
%{C++
|
||||
#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"
|
||||
%}
|
||||
|
@ -90,4 +90,11 @@ interface nsISHistoryInternal: nsISupports
|
|||
*/
|
||||
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 \
|
||||
docshell \
|
||||
pref \
|
||||
gfx \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsSHEntry.cpp \
|
||||
|
|
|
@ -37,11 +37,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef DEBUG_bryner
|
||||
#define DEBUG_PAGE_CACHE
|
||||
#endif
|
||||
|
||||
// Local Includes
|
||||
#include "nsSHEntry.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
|
||||
static PRUint32 gEntryID = 0;
|
||||
|
||||
|
@ -58,7 +63,9 @@ nsSHEntry::nsSHEntry()
|
|||
, mIsFrameNavigation(PR_FALSE)
|
||||
, mSaveLayoutState(PR_TRUE)
|
||||
, mExpired(PR_FALSE)
|
||||
, mSticky(PR_TRUE)
|
||||
, mParent(nsnull)
|
||||
, mViewerBounds(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,12 +84,21 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
|||
, mIsFrameNavigation(other.mIsFrameNavigation)
|
||||
, mSaveLayoutState(other.mSaveLayoutState)
|
||||
, mExpired(other.mExpired)
|
||||
, mSticky(PR_TRUE)
|
||||
// XXX why not copy mContentType?
|
||||
, mCacheKey(other.mCacheKey)
|
||||
, mParent(other.mParent)
|
||||
, mViewerBounds(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
nsSHEntry::~nsSHEntry()
|
||||
{
|
||||
mChildren.Clear();
|
||||
if (mContentViewer)
|
||||
mContentViewer->Destroy();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsSHEntry: nsISupports
|
||||
//*****************************************************************************
|
||||
|
@ -133,19 +149,35 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::SetDocument(nsIDOMDocument* aDocument)
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetContentViewer(nsIContentViewer *aViewer)
|
||||
{
|
||||
mDocument = aDocument;
|
||||
mContentViewer = aViewer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::GetDocument(nsIDOMDocument** aResult)
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetContentViewer(nsIContentViewer **aResult)
|
||||
{
|
||||
*aResult = mDocument;
|
||||
*aResult = mContentViewer;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
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)
|
||||
{
|
||||
// Check for empty title...
|
||||
|
@ -160,7 +192,7 @@ NS_IMETHODIMP nsSHEntry::GetTitle(PRUnichar** aTitle)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::SetTitle(const PRUnichar* aTitle)
|
||||
NS_IMETHODIMP nsSHEntry::SetTitle(const nsAString &aTitle)
|
||||
{
|
||||
mTitle = aTitle;
|
||||
return NS_OK;
|
||||
|
@ -297,14 +329,13 @@ NS_IMETHODIMP nsSHEntry::SetContentType(const nsACString& aContentType)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle,
|
||||
nsIDOMDocument * aDOMDocument, nsIInputStream * aInputStream,
|
||||
nsILayoutHistoryState * aHistoryLayoutState,
|
||||
nsSHEntry::Create(nsIURI * aURI, const nsAString &aTitle,
|
||||
nsIInputStream * aInputStream,
|
||||
nsILayoutHistoryState * aLayoutHistoryState,
|
||||
nsISupports * aCacheKey, const nsACString& aContentType)
|
||||
{
|
||||
mURI = aURI;
|
||||
mTitle = aTitle;
|
||||
mDocument = aDOMDocument;
|
||||
mPostData = aInputStream;
|
||||
mCacheKey = aCacheKey;
|
||||
mContentType = aContentType;
|
||||
|
@ -317,9 +348,9 @@ nsSHEntry::Create(nsIURI * aURI, const PRUnichar * aTitle,
|
|||
// all subframe navigations, sets the flag to true.
|
||||
mIsFrameNavigation = PR_FALSE;
|
||||
|
||||
// By default we save HistoryLayoutState
|
||||
// By default we save LayoutHistoryState
|
||||
mSaveLayoutState = PR_TRUE;
|
||||
mLayoutHistoryState = aHistoryLayoutState;
|
||||
mLayoutHistoryState = aLayoutHistoryState;
|
||||
|
||||
//By default the page is not expired
|
||||
mExpired = PR_FALSE;
|
||||
|
@ -358,6 +389,34 @@ nsSHEntry::SetParent(nsISHEntry * aParent)
|
|||
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
|
||||
//*****************************************************************************
|
||||
|
@ -416,3 +475,77 @@ nsSHEntry::GetChildAt(PRInt32 aIndex, nsISHEntry ** aResult)
|
|||
}
|
||||
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 "nsCOMArray.h"
|
||||
#include "nsString.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
// Interfaces needed
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILayoutHistoryState.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
@ -54,9 +55,10 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsSupportsArray.h"
|
||||
|
||||
class nsSHEntry : public nsIHistoryEntry,
|
||||
public nsISHEntry,
|
||||
class nsSHEntry : public nsISHEntry,
|
||||
public nsISHContainer
|
||||
{
|
||||
public:
|
||||
|
@ -69,11 +71,11 @@ public:
|
|||
NS_DECL_NSISHCONTAINER
|
||||
|
||||
private:
|
||||
~nsSHEntry() { mChildren.Clear(); }
|
||||
~nsSHEntry();
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
nsCOMPtr<nsIDOMDocument> mDocument;
|
||||
nsCOMPtr<nsIContentViewer> mContentViewer;
|
||||
nsString mTitle;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
|
||||
|
@ -86,9 +88,15 @@ private:
|
|||
PRPackedBool mIsFrameNavigation;
|
||||
PRPackedBool mSaveLayoutState;
|
||||
PRPackedBool mExpired;
|
||||
PRPackedBool mSticky;
|
||||
nsCString mContentType;
|
||||
nsCOMPtr<nsISupports> mCacheKey;
|
||||
nsISHEntry * mParent; // weak reference
|
||||
nsCOMPtr<nsISupports> mWindowState;
|
||||
nsRect mViewerBounds;
|
||||
nsVoidArray mChildShells;
|
||||
nsCOMPtr<nsISupports> mSecurityState;
|
||||
nsCOMPtr<nsISupportsArray> mRefreshURIList;
|
||||
};
|
||||
|
||||
#endif /* nsSHEntry_h */
|
||||
|
|
|
@ -54,9 +54,14 @@
|
|||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIContentViewer.h"
|
||||
|
||||
#define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries"
|
||||
#define PREF_SHISTORY_VIEWERS "browser.sessionhistory.max_viewers"
|
||||
|
||||
static PRInt32 gHistoryMaxSize = 50;
|
||||
static PRInt32 gHistoryMaxViewers = 0;
|
||||
|
||||
enum HistCmd{
|
||||
HIST_CMD_BACK,
|
||||
|
@ -104,11 +109,21 @@ nsSHistory::Init()
|
|||
{
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
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;
|
||||
prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch));
|
||||
if (defaultBranch) {
|
||||
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;
|
||||
}
|
||||
|
@ -207,6 +222,7 @@ nsSHistory::GetEntryAtIndex(PRInt32 aIndex, PRBool aModifyIndex, nsISHEntry** aR
|
|||
if (NS_SUCCEEDED(rv) && (*aResult)) {
|
||||
// Set mIndex to the requested index, if asked to do so..
|
||||
if (aModifyIndex) {
|
||||
EvictContentViewers(mIndex, aIndex);
|
||||
mIndex = aIndex;
|
||||
}
|
||||
} //entry
|
||||
|
@ -476,6 +492,14 @@ nsSHistory::GetListener(nsISHistoryListener ** aListener)
|
|||
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
|
||||
//*****************************************************************************
|
||||
|
@ -583,12 +607,63 @@ nsSHistory::Reload(PRUint32 aReloadFlags)
|
|||
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
|
||||
nsSHistory::UpdateIndex()
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ protected:
|
|||
nsresult PrintHistory();
|
||||
#endif
|
||||
|
||||
void EvictContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsISHTransaction> mListRoot;
|
||||
PRInt32 mIndex;
|
||||
|
|
Загрузка…
Ссылка в новой задаче