mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-14 19:27:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
40
docshell/shistory/moz.build
Normal file
40
docshell/shistory/moz.build
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIBFCacheEntry.idl',
|
||||
'nsIGroupedSHistory.idl',
|
||||
'nsIPartialSHistory.idl',
|
||||
'nsIPartialSHistoryListener.idl',
|
||||
'nsISHContainer.idl',
|
||||
'nsISHEntry.idl',
|
||||
'nsISHistory.idl',
|
||||
'nsISHistoryInternal.idl',
|
||||
'nsISHistoryListener.idl',
|
||||
'nsISHTransaction.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'shistory'
|
||||
|
||||
EXPORTS += [
|
||||
'nsSHEntryShared.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsSHEntry.cpp',
|
||||
'nsSHEntryShared.cpp',
|
||||
'nsSHistory.cpp',
|
||||
'nsSHTransaction.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/docshell/base',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
18
docshell/shistory/nsIBFCacheEntry.idl
Normal file
18
docshell/shistory/nsIBFCacheEntry.idl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* This interface lets you evict a document from the back/forward cache.
|
||||
*/
|
||||
[scriptable, uuid(a576060e-c7df-4d81-aa8c-5b52bd6ad25d)]
|
||||
interface nsIBFCacheEntry : nsISupports
|
||||
{
|
||||
void RemoveFromBFCacheSync();
|
||||
void RemoveFromBFCacheAsync();
|
||||
|
||||
readonly attribute unsigned long long ID;
|
||||
};
|
||||
47
docshell/shistory/nsIGroupedSHistory.idl
Normal file
47
docshell/shistory/nsIGroupedSHistory.idl
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIFrameLoader;
|
||||
interface nsIPartialSHistory;
|
||||
|
||||
/**
|
||||
* nsIGroupedSHistory represent a combined session history across multiple
|
||||
* root docshells (usually browser tabs). The participating nsISHistory can
|
||||
* either be in chrome process or in content process, but nsIGroupedSHistory
|
||||
* itself lives in chrome process. The communication is proxyed through
|
||||
* nsIPartialSHistory.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(813e498d-73a8-449a-be09-6187e62c5352)]
|
||||
interface nsIGroupedSHistory : nsISupports
|
||||
{
|
||||
// The total number of entries of all its partial session histories.
|
||||
[infallible] readonly attribute unsigned long count;
|
||||
|
||||
/**
|
||||
* Remove all partial histories after currently active one (if any) and then
|
||||
* append the given partial session history to the end of the list.
|
||||
*/
|
||||
void appendPartialSessionHistory(in nsIPartialSHistory aPartialHistory);
|
||||
|
||||
/**
|
||||
* Notify the grouped session history that the active partial session history
|
||||
* has been modified. All partial session histories after the active one
|
||||
* will be removed and destroy.
|
||||
*/
|
||||
void onPartialSessionHistoryChange(in nsIPartialSHistory aPartialHistory);
|
||||
|
||||
/**
|
||||
* Find the proper partial session history and navigate to the entry
|
||||
* corresponding to the given global index. Note it doesn't swap frameloaders,
|
||||
* but rather return the target loader for the caller to swap.
|
||||
*
|
||||
* @param aGlobalIndex The global index to navigate to.
|
||||
* @param aTargetLoaderToSwap The owner frameloader of the to-be-navigate
|
||||
* partial session history.
|
||||
*/
|
||||
void gotoIndex(in unsigned long aGlobalIndex, out nsIFrameLoader aTargetLoaderToSwap);
|
||||
};
|
||||
62
docshell/shistory/nsIPartialSHistory.idl
Normal file
62
docshell/shistory/nsIPartialSHistory.idl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIFrameLoader;
|
||||
|
||||
/**
|
||||
* nsIPartialSHistory represents a part of nsIGroupedSHistory. It associates to
|
||||
* a "partial" nsISHistory in either local or remote process.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(5cd75e28-838c-4a0a-972e-6005f736ef7a)]
|
||||
interface nsIPartialSHistory : nsISupports
|
||||
{
|
||||
// The number of entries of its corresponding nsISHistory.
|
||||
[infallible] readonly attribute unsigned long count;
|
||||
|
||||
// If it's part of a grouped session history, globalIndexOffset denotes the
|
||||
// number of entries ahead.
|
||||
[infallible] readonly attribute unsigned long globalIndexOffset;
|
||||
|
||||
// The frameloader which owns this partial session history.
|
||||
readonly attribute nsIFrameLoader ownerFrameLoader;
|
||||
|
||||
/**
|
||||
* Notify that it's been added to a grouped session history. It also implies
|
||||
* it's becoming the active partial history of the group.
|
||||
*
|
||||
* @param aOffset The number of entries in preceding partial
|
||||
* session histories.
|
||||
*/
|
||||
void onAttachGroupedSessionHistory(in unsigned long aOffset);
|
||||
|
||||
/**
|
||||
* Notify that one or more entries in its associated nsISHistory object
|
||||
* have been changed (i.e. add / remove / replace). It's mainly used for
|
||||
* cross-process case, since in the in-process case we can just register an
|
||||
* nsISHistoryListener instead.
|
||||
*
|
||||
* @param aCount The number of entries in the associated session history.
|
||||
* It can be the same as the old value if entries were replaced.
|
||||
*/
|
||||
void onSessionHistoryChange(in unsigned long aCount);
|
||||
|
||||
/**
|
||||
* Notify that the partial session history has been swapped in as the active
|
||||
* session history. Only an active session history can possibly add / remove /
|
||||
* replace its history entries.
|
||||
*
|
||||
* @param aGlobalLength The up-to-date global length.
|
||||
* @param aTargetLocalIndex The local index to navigate to.
|
||||
*/
|
||||
void onActive(in unsigned long aGlobalLength, in unsigned long aTargetLocalIndex);
|
||||
|
||||
/**
|
||||
* Notify that the partial session history has been swapped out and is no
|
||||
* longer active.
|
||||
*/
|
||||
void onDeactive();
|
||||
};
|
||||
24
docshell/shistory/nsIPartialSHistoryListener.idl
Normal file
24
docshell/shistory/nsIPartialSHistoryListener.idl
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* Listener to handle cross partial nsISHistory navigation requests.
|
||||
*/
|
||||
[scriptable, uuid(be0cd2b6-6f03-4366-9fe2-184c914ff3df)]
|
||||
interface nsIPartialSHistoryListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when the navigation target belongs to another nsISHistory within
|
||||
* the same nsIGroupedSHistory, and it needs to initiate cross nsISHistory
|
||||
* navigation.
|
||||
*
|
||||
* @param aIndex The index of complete history to navigate to.
|
||||
*/
|
||||
void onRequestCrossBrowserNavigation(in unsigned long aIndex);
|
||||
};
|
||||
49
docshell/shistory/nsISHContainer.idl
Normal file
49
docshell/shistory/nsISHContainer.idl
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsISHEntry;
|
||||
|
||||
/**
|
||||
* The nsISHEntryContainer. The interface to access child entries
|
||||
* of an nsISHEntry.
|
||||
*
|
||||
*/
|
||||
|
||||
[scriptable, uuid(67dd0357-8372-4122-bff6-217435e8b7e4)]
|
||||
interface nsISHContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
* The current number of nsISHEntries which are immediate children of the
|
||||
* current SHEntry
|
||||
*/
|
||||
readonly attribute long childCount;
|
||||
|
||||
/**
|
||||
* Add a new child SHEntry. If offset is -1 adds to the end of the list.
|
||||
*/
|
||||
void AddChild(in nsISHEntry child, in long offset);
|
||||
|
||||
/**
|
||||
* Removes a child SHEntry
|
||||
*/
|
||||
void RemoveChild(in nsISHEntry child);
|
||||
|
||||
/**
|
||||
* Get child at an index
|
||||
*/
|
||||
nsISHEntry GetChildAt(in long index);
|
||||
|
||||
/**
|
||||
* Replaces a child which is for the same docshell as aNewChild
|
||||
* with aNewChild.
|
||||
* @throw if nothing was replaced.
|
||||
*/
|
||||
void ReplaceChild(in nsISHEntry aNewChild);
|
||||
|
||||
};
|
||||
|
||||
352
docshell/shistory/nsISHEntry.idl
Normal file
352
docshell/shistory/nsISHEntry.idl
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* The interface to nsISHentry. Each document or subframe in
|
||||
* Session History will have a nsISHEntry associated with it which will
|
||||
* hold all information required to recreate the document from history
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIMutableArray;
|
||||
interface nsILayoutHistoryState;
|
||||
interface nsIContentViewer;
|
||||
interface nsIURI;
|
||||
interface nsIInputStream;
|
||||
interface nsIDocShellTreeItem;
|
||||
interface nsIStructuredCloneContainer;
|
||||
interface nsIBFCacheEntry;
|
||||
interface nsIPrincipal;
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
class nsDocShellEditorData;
|
||||
class nsSHEntryShared;
|
||||
%}
|
||||
[ref] native nsIntRect(nsIntRect);
|
||||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
[ptr] native nsSHEntryShared(nsSHEntryShared);
|
||||
|
||||
[scriptable, uuid(0dad26b8-a259-42c7-93f1-2fa7fc076e45)]
|
||||
interface nsISHEntry : 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 original URI of the current entry.
|
||||
* If an entry is the result of a redirect this attribute holds original
|
||||
* URI. The object returned is of type nsIURI
|
||||
*/
|
||||
attribute nsIURI originalURI;
|
||||
|
||||
/**
|
||||
* This flag remembers whether channel has LOAD_REPLACE set.
|
||||
*/
|
||||
attribute boolean loadReplace;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** URI for the document */
|
||||
void setURI(in nsIURI aURI);
|
||||
|
||||
/** Referrer URI */
|
||||
attribute nsIURI referrerURI;
|
||||
|
||||
/** Referrer policy, holding one of the values (REFERRER_POLICY_*)
|
||||
* defined in nsIHttpChannel.
|
||||
*/
|
||||
attribute unsigned long referrerPolicy;
|
||||
|
||||
/** Content viewer, for fast restoration of presentation */
|
||||
attribute nsIContentViewer contentViewer;
|
||||
|
||||
/** Whether the content viewer is marked "sticky" */
|
||||
attribute boolean sticky;
|
||||
|
||||
/** Saved state of the global window object */
|
||||
attribute nsISupports windowState;
|
||||
|
||||
/**
|
||||
* 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 nsIntRect bounds);
|
||||
[noscript] void setViewerBounds([const] in nsIntRect bounds);
|
||||
|
||||
/**
|
||||
* Saved child docshells corresponding to contentViewer. The child shells
|
||||
* are restored as children of the parent docshell, in this order, when the
|
||||
* parent docshell restores a saved presentation.
|
||||
*/
|
||||
|
||||
/** Append a child shell to the end of our list. */
|
||||
void addChildShell(in nsIDocShellTreeItem shell);
|
||||
|
||||
/**
|
||||
* Get the child shell at |index|; returns null if |index| is out of bounds.
|
||||
*/
|
||||
nsIDocShellTreeItem childShellAt(in long index);
|
||||
|
||||
/**
|
||||
* Clear the child shell list.
|
||||
*/
|
||||
void clearChildShells();
|
||||
|
||||
/** Saved refresh URI list for the content viewer */
|
||||
attribute nsIMutableArray refreshURIList;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/** Title for the document */
|
||||
void setTitle(in AString aTitle);
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/**
|
||||
* If we created this SHEntry via history.pushState or modified it via
|
||||
* history.replaceState, and if we changed the SHEntry's URI via the
|
||||
* push/replaceState call, and if the SHEntry's new URI differs from its
|
||||
* old URI by more than just the hash, then we set this field to true.
|
||||
*
|
||||
* Additionally, if this SHEntry was created by calling pushState from a
|
||||
* SHEntry whose URI was modified, this SHEntry's URIWasModified field is
|
||||
* true.
|
||||
*
|
||||
*/
|
||||
attribute boolean URIWasModified;
|
||||
|
||||
/** 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 */
|
||||
[noscript] void create(in nsIURI URI, in AString title,
|
||||
in nsIInputStream inputStream,
|
||||
in nsILayoutHistoryState layoutHistoryState,
|
||||
in nsISupports cacheKey, in ACString contentType,
|
||||
in nsIPrincipal triggeringPrincipal,
|
||||
in nsIPrincipal principalToInherit,
|
||||
in unsigned long long docshellID,
|
||||
in boolean dynamicCreation);
|
||||
|
||||
nsISHEntry clone();
|
||||
|
||||
/** Attribute that indicates if this entry is for a subframe navigation */
|
||||
void setIsSubFrame(in boolean aFlag);
|
||||
|
||||
/** Return any content viewer present in or below this node in the
|
||||
nsSHEntry tree. This will differ from contentViewer in the case
|
||||
where a child nsSHEntry has the content viewer for this tree. */
|
||||
nsIContentViewer getAnyContentViewer(out nsISHEntry ownerEntry);
|
||||
|
||||
/**
|
||||
* Get the principal, if any, that was associated with the channel
|
||||
* that the document that was loaded to create this history entry
|
||||
* came from.
|
||||
*/
|
||||
attribute nsIPrincipal triggeringPrincipal;
|
||||
|
||||
/**
|
||||
* Get the principal, if any, that is used when the inherit flag
|
||||
* is set.
|
||||
*/
|
||||
attribute nsIPrincipal principalToInherit;
|
||||
|
||||
/**
|
||||
* Get/set data associated with this history state via a pushState() call,
|
||||
* serialized using structured clone.
|
||||
**/
|
||||
attribute nsIStructuredCloneContainer stateData;
|
||||
|
||||
/**
|
||||
* Gets the owning pointer to the editor data assosicated with
|
||||
* this shistory entry. This forgets its pointer, so free it when
|
||||
* you're done.
|
||||
*/
|
||||
[noscript, notxpcom] nsDocShellEditorDataPtr forgetEditorData();
|
||||
|
||||
/**
|
||||
* Sets the owning pointer to the editor data assosicated with
|
||||
* this shistory entry. Unless forgetEditorData() is called, this
|
||||
* shentry will destroy the editor data when it's destroyed.
|
||||
*/
|
||||
[noscript, notxpcom] void setEditorData(in nsDocShellEditorDataPtr aData);
|
||||
|
||||
/** Returns true if this shistory entry is storing a detached editor. */
|
||||
[noscript, notxpcom] boolean hasDetachedEditor();
|
||||
|
||||
/**
|
||||
* Returns true if the related docshell was added because of
|
||||
* dynamic addition of an iframe/frame.
|
||||
*/
|
||||
boolean isDynamicallyAdded();
|
||||
|
||||
/**
|
||||
* Returns true if any of the child entries returns true
|
||||
* when isDynamicallyAdded is called on it.
|
||||
*/
|
||||
boolean hasDynamicallyAddedChild();
|
||||
|
||||
/**
|
||||
* The history ID of the docshell.
|
||||
*/
|
||||
attribute unsigned long long docshellID;
|
||||
|
||||
readonly attribute nsIBFCacheEntry BFCacheEntry;
|
||||
|
||||
/**
|
||||
* Does this SHEntry point to the given BFCache entry? If so, evicting
|
||||
* the BFCache entry will evict the SHEntry, since the two entries
|
||||
* correspond to the same document.
|
||||
*/
|
||||
[notxpcom, noscript]
|
||||
boolean hasBFCacheEntry(in nsIBFCacheEntry aEntry);
|
||||
|
||||
/**
|
||||
* Adopt aEntry's BFCacheEntry, so now both this and aEntry point to
|
||||
* aEntry's BFCacheEntry.
|
||||
*/
|
||||
void adoptBFCacheEntry(in nsISHEntry aEntry);
|
||||
|
||||
/**
|
||||
* Create a new BFCache entry and drop our reference to our old one. This
|
||||
* call unlinks this SHEntry from any other SHEntries for its document.
|
||||
*/
|
||||
void abandonBFCacheEntry();
|
||||
|
||||
/**
|
||||
* Does this SHEntry correspond to the same document as aEntry? This is
|
||||
* true iff the two SHEntries have the same BFCacheEntry. So in
|
||||
* particular, sharesDocumentWith(aEntry) is guaranteed to return true if
|
||||
* it's preceeded by a call to adoptBFCacheEntry(aEntry).
|
||||
*/
|
||||
boolean sharesDocumentWith(in nsISHEntry aEntry);
|
||||
|
||||
/**
|
||||
* True if this SHEntry corresponds to a document created by a srcdoc iframe.
|
||||
* Set when a value is assigned to srcdocData.
|
||||
*/
|
||||
readonly attribute boolean isSrcdocEntry;
|
||||
|
||||
/**
|
||||
* Contents of the srcdoc attribute in a srcdoc iframe to be loaded instead
|
||||
* of the URI. Similar to a Data URI, this information is needed to
|
||||
* recreate the document at a later stage.
|
||||
* Setting this sets isSrcdocEntry to true
|
||||
*/
|
||||
attribute AString srcdocData;
|
||||
|
||||
/**
|
||||
* When isSrcdocEntry is true, this contains the baseURI of the srcdoc
|
||||
* document for use in situations where it cannot otherwise be determined,
|
||||
* for example with view-source.
|
||||
*/
|
||||
attribute nsIURI baseURI;
|
||||
|
||||
/**
|
||||
* Sets/gets the current scroll restoration state,
|
||||
* if true == "manual", false == "auto".
|
||||
*/
|
||||
attribute boolean scrollRestorationIsManual;
|
||||
};
|
||||
|
||||
[scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)]
|
||||
interface nsISHEntryInternal : nsISupports
|
||||
{
|
||||
[notxpcom] void RemoveFromBFCacheAsync();
|
||||
[notxpcom] void RemoveFromBFCacheSync();
|
||||
|
||||
/**
|
||||
* A number that is assigned by the sHistory when the entry is activated
|
||||
*/
|
||||
attribute unsigned long lastTouched;
|
||||
|
||||
/**
|
||||
* Some state, particularly that related to the back/forward cache, is
|
||||
* shared between SHEntries which correspond to the same document. This
|
||||
* method gets a pointer to that shared state.
|
||||
*
|
||||
* This shared state is the SHEntry's BFCacheEntry. So
|
||||
* hasBFCacheEntry(getSharedState()) is guaranteed to return true.
|
||||
*/
|
||||
[noscript, notxpcom]
|
||||
nsSHEntryShared getSharedState();
|
||||
};
|
||||
|
||||
%{ C++
|
||||
// {BFD1A791-AD9F-11d3-BDC7-0050040A9B44}
|
||||
#define NS_SHENTRY_CID \
|
||||
{0xbfd1a791, 0xad9f, 0x11d3, {0xbd, 0xc7, 0x0, 0x50, 0x4, 0xa, 0x9b, 0x44}}
|
||||
|
||||
#define NS_SHENTRY_CONTRACTID \
|
||||
"@mozilla.org/browser/session-history-entry;1"
|
||||
|
||||
%}
|
||||
|
||||
56
docshell/shistory/nsISHTransaction.idl
Normal file
56
docshell/shistory/nsISHTransaction.idl
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsISHEntry;
|
||||
|
||||
/**
|
||||
* The nsISHTransaction.
|
||||
*/
|
||||
|
||||
|
||||
[scriptable, uuid(2EDF705F-D252-4971-9F09-71DD0F760DC6)]
|
||||
interface nsISHTransaction : nsISupports
|
||||
{
|
||||
/**
|
||||
* The nsISHEntry for the current transaction
|
||||
*/
|
||||
attribute nsISHEntry sHEntry;
|
||||
|
||||
/**
|
||||
* The parent of this transaction
|
||||
*/
|
||||
attribute nsISHTransaction prev;
|
||||
|
||||
/**
|
||||
* The legitimate child of this transaction
|
||||
*/
|
||||
attribute nsISHTransaction next;
|
||||
|
||||
/**
|
||||
* Specifies if this transaction should persist. If not it will be replaced
|
||||
* by new additions to the list.
|
||||
*/
|
||||
attribute boolean persist;
|
||||
|
||||
/**
|
||||
* Create a transaction with parent and History Entry
|
||||
*/
|
||||
void create(in nsISHEntry aSHEntry, in nsISHTransaction aPrev);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
// {BFD1A792-AD9F-11d3-BDC7-0050040A9B44}
|
||||
|
||||
|
||||
#define NS_SHTRANSACTION_CID \
|
||||
{0xbfd1a792, 0xad9f, 0x11d3, {0xbd, 0xc7, 0x0, 0x50, 0x4, 0xa, 0x9b, 0x44}}
|
||||
|
||||
#define NS_SHTRANSACTION_CONTRACTID \
|
||||
"@mozilla.org/browser/session-history-transaction;1"
|
||||
|
||||
%}
|
||||
221
docshell/shistory/nsISHistory.idl
Normal file
221
docshell/shistory/nsISHistory.idl
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsISHEntry;
|
||||
interface nsISHistoryListener;
|
||||
interface nsISimpleEnumerator;
|
||||
interface nsIPartialSHistoryListener;
|
||||
|
||||
/**
|
||||
* An interface to the primary properties of the Session History
|
||||
* component. In an embedded browser environment, the nsIWebBrowser
|
||||
* object creates an instance of session history for each open window.
|
||||
* A handle to the session history object can be obtained from
|
||||
* nsIWebNavigation. In a non-embedded situation, the owner of the
|
||||
* session history component must create a instance of it and set
|
||||
* it in the nsIWebNavigation object.
|
||||
* This interface is accessible from javascript.
|
||||
*/
|
||||
|
||||
|
||||
%{C++
|
||||
#define NS_SHISTORY_CID \
|
||||
{0x7b807041, 0xe60a, 0x4384, {0x93, 0x5f, 0xaf, 0x30, 0x61, 0xd8, 0xb8, 0x15}}
|
||||
|
||||
#define NS_SHISTORY_CONTRACTID "@mozilla.org/browser/shistory;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(7b807041-e60a-4384-935f-af3061d8b815)]
|
||||
interface nsISHistory: nsISupports
|
||||
{
|
||||
/**
|
||||
* An attribute denoting whether the nsISHistory is associated to a grouped
|
||||
* session history.
|
||||
*
|
||||
* The abstraction of grouped session history is implemented at
|
||||
* nsIWebNavigation level, so those canGoBack / canGoForward / gotoIndex
|
||||
* functions work transparently;
|
||||
*
|
||||
* On the other hand, nsISHistory works on partial session history directly.
|
||||
* Unless otherwise specified, count / index attributes and parameters all
|
||||
* indicate local count / index, so we won't mess up docshell.
|
||||
*/
|
||||
readonly attribute bool isPartial;
|
||||
|
||||
/**
|
||||
* A readonly property of the interface that returns
|
||||
* the number of toplevel documents currently available
|
||||
* in session history.
|
||||
*/
|
||||
readonly attribute long count;
|
||||
|
||||
/**
|
||||
* If isPartial, globalCount denotes the total number of entries in the
|
||||
* grouped session history; Otherwise it has the same value as count.
|
||||
*/
|
||||
readonly attribute long globalCount;
|
||||
|
||||
/**
|
||||
* A readonly property which represents the difference between global indices
|
||||
* of grouped session history and local indices of this particular session
|
||||
* history object.
|
||||
*/
|
||||
readonly attribute long globalIndexOffset;
|
||||
|
||||
/**
|
||||
* A readonly property of the interface that returns
|
||||
* the index of the current document in session history.
|
||||
*/
|
||||
readonly attribute long index;
|
||||
|
||||
/**
|
||||
* A readonly property of the interface that returns
|
||||
* the index of the last document that started to load and
|
||||
* didn't finished yet. When document finishes the loading
|
||||
* value -1 is returned.
|
||||
*/
|
||||
readonly attribute long requestedIndex;
|
||||
|
||||
/**
|
||||
* A read/write property of the interface, used to Get/Set
|
||||
* the maximum number of toplevel documents, session history
|
||||
* can hold for each instance.
|
||||
*/
|
||||
attribute long maxLength;
|
||||
|
||||
/**
|
||||
* Called to obtain handle to the history entry at a
|
||||
* given index.
|
||||
*
|
||||
* @param index The index value whose entry is requested.
|
||||
* The oldest entry is located at index == 0.
|
||||
* @param modifyIndex A boolean flag that indicates if the current
|
||||
* index of session history should be modified
|
||||
* to the parameter index.
|
||||
*
|
||||
* @return <code>NS_OK</code> history entry for
|
||||
* the index is obtained successfully.
|
||||
* <code>NS_ERROR_FAILURE</code> Error in obtaining
|
||||
* history entry for the given index.
|
||||
*/
|
||||
nsISHEntry getEntryAtIndex(in long index, in boolean modifyIndex);
|
||||
|
||||
|
||||
/**
|
||||
* Called to purge older documents from history.
|
||||
* Documents can be removed from session history for various
|
||||
* reasons. For example to control memory usage of the browser, to
|
||||
* prevent users from loading documents from history, to erase evidence of
|
||||
* prior page loads etc...
|
||||
*
|
||||
* @param numEntries The number of toplevel documents to be
|
||||
* purged from history. During purge operation,
|
||||
* the latest documents are maintained and older
|
||||
* 'numEntries' documents are removed from history.
|
||||
* @throws <code>NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA</code> Purge was vetod.
|
||||
* @throws <code>NS_ERROR_FAILURE</code> numEntries is
|
||||
* invalid or out of bounds with the size of history.
|
||||
*
|
||||
*/
|
||||
void PurgeHistory(in long numEntries);
|
||||
|
||||
/**
|
||||
* Called to register a listener for the session history component.
|
||||
* Listeners are notified when pages are loaded or purged from history.
|
||||
*
|
||||
* @param aListener Listener object to be notified for all
|
||||
* page loads that initiate in session history.
|
||||
*
|
||||
* @note A listener object must implement
|
||||
* nsISHistoryListener and nsSupportsWeakReference
|
||||
*
|
||||
* @see nsISHistoryListener
|
||||
* @see nsSupportsWeakReference
|
||||
*/
|
||||
void addSHistoryListener(in nsISHistoryListener aListener);
|
||||
|
||||
/**
|
||||
* Called to remove a listener for the session history component.
|
||||
* Listeners are notified when pages are loaded from history.
|
||||
*
|
||||
* @param aListener Listener object to be removed from
|
||||
* session history.
|
||||
*
|
||||
* @note A listener object must implement
|
||||
* nsISHistoryListener and nsSupportsWeakReference
|
||||
* @see nsISHistoryListener
|
||||
* @see nsSupportsWeakReference
|
||||
*/
|
||||
void removeSHistoryListener(in nsISHistoryListener aListener);
|
||||
|
||||
/**
|
||||
* Set the listener to handle cross nsISHistory navigation when it works
|
||||
* in "partial" mode.
|
||||
*/
|
||||
void setPartialSHistoryListener(in nsIPartialSHistoryListener aListener);
|
||||
|
||||
/**
|
||||
* Called to obtain a enumerator for all the documents stored in
|
||||
* session history. The enumerator object thus returned by this method
|
||||
* can be traversed using nsISimpleEnumerator.
|
||||
*
|
||||
* @note To access individual history entries of the enumerator, perform the
|
||||
* following steps:
|
||||
* 1) Call nsISHistory->GetSHistoryEnumerator() to obtain handle
|
||||
* the nsISimpleEnumerator object.
|
||||
* 2) Use nsISimpleEnumerator->GetNext() on the object returned
|
||||
* by step #1 to obtain handle to the next object in the list.
|
||||
* The object returned by this step is of type nsISupports.
|
||||
* 3) Perform a QueryInterface on the object returned by step #2
|
||||
* to nsISHEntry.
|
||||
* 4) Use nsISHEntry to access properties of each history entry.
|
||||
*
|
||||
* @see nsISimpleEnumerator
|
||||
* @see nsISHEntry
|
||||
* @see QueryInterface()
|
||||
* @see do_QueryInterface()
|
||||
*/
|
||||
readonly attribute nsISimpleEnumerator SHistoryEnumerator;
|
||||
|
||||
void reloadCurrentEntry();
|
||||
|
||||
/**
|
||||
* Called to obtain the index to a given history entry.
|
||||
*
|
||||
* @param aEntry The entry to obtain the index of.
|
||||
*
|
||||
* @return <code>NS_OK</code> index for the history entry
|
||||
* is obtained successfully.
|
||||
* <code>NS_ERROR_FAILURE</code> Error in obtaining
|
||||
* index for the given history entry.
|
||||
*/
|
||||
long getIndexOfEntry(in nsISHEntry aEntry);
|
||||
|
||||
/**
|
||||
* Called when this nsISHistory has became the active history of a grouped
|
||||
* session history.
|
||||
*
|
||||
* @param globalLength The up to date number of entries in the grouped
|
||||
* session history.
|
||||
* @param targetIndex The local index to navigate to.
|
||||
*/
|
||||
void onPartialSessionHistoryActive(in long globalLength, in long targetIndex);
|
||||
|
||||
/**
|
||||
* Called when this nsISHistory has became inactive history of a grouped
|
||||
* session history.
|
||||
*/
|
||||
void onPartialSessionHistoryDeactive();
|
||||
|
||||
/**
|
||||
* Called when it's attached to a nsIGroupedSHistory instance.
|
||||
*
|
||||
* @param offset The number of entries in the grouped session
|
||||
* history before this session history object.
|
||||
*/
|
||||
void onAttachGroupedSessionHistory(in long offset);
|
||||
};
|
||||
104
docshell/shistory/nsISHistoryInternal.idl
Normal file
104
docshell/shistory/nsISHistoryInternal.idl
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIBFCacheEntry;
|
||||
interface nsISHEntry;
|
||||
interface nsISHistoryListener;
|
||||
interface nsISHTransaction;
|
||||
interface nsIDocShell;
|
||||
interface nsIURI;
|
||||
|
||||
%{C++
|
||||
#define NS_SHISTORY_INTERNAL_CID \
|
||||
{ 0x3dfb2f54, 0x378d, 0x4d3c, \
|
||||
{ 0xa9, 0xf9, 0x95, 0xdd, 0x26, 0x73, 0x24, 0x8c } }
|
||||
|
||||
#define NS_SHISTORY_INTERNAL_CONTRACTID "@mozilla.org/browser/shistory-internal;1"
|
||||
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
%}
|
||||
|
||||
[ref] native nsDocshellIDArray(nsTArray<uint64_t>);
|
||||
|
||||
[scriptable, uuid(3dfb2f54-378d-4d3c-a9f9-95dd2673248c)]
|
||||
interface nsISHistoryInternal: nsISupports
|
||||
{
|
||||
/**
|
||||
* Add a new Entry to the History List
|
||||
* @param aEntry - The entry to add
|
||||
* @param aPersist - If true this specifies that the entry should persist
|
||||
* in the list. If false, this means that when new entries are added
|
||||
* this element will not appear in the session history list.
|
||||
*/
|
||||
void addEntry(in nsISHEntry aEntry, in boolean aPersist);
|
||||
|
||||
/**
|
||||
* Get the root transaction
|
||||
*/
|
||||
readonly attribute nsISHTransaction rootTransaction;
|
||||
|
||||
/**
|
||||
* Sets the toplevel docshell object to which this SHistory object belongs to.
|
||||
*/
|
||||
void setRootDocShell(in nsIDocShell rootDocShell);
|
||||
|
||||
/**
|
||||
* Update the index maintained by sessionHistory
|
||||
*/
|
||||
void updateIndex();
|
||||
|
||||
/**
|
||||
* Replace the nsISHEntry at a particular index
|
||||
* @param aIndex - The index at which the entry should be replaced
|
||||
* @param aReplaceEntry - The replacement entry for the index.
|
||||
*/
|
||||
void replaceEntry(in long aIndex, in nsISHEntry aReplaceEntry);
|
||||
|
||||
/**
|
||||
* Notifies all registered session history listeners about an impending
|
||||
* reload.
|
||||
*
|
||||
* @param aReloadURI The URI of the document to be reloaded.
|
||||
* @param aReloadFlags Flags that indicate how the document is to be
|
||||
* refreshed. See constants on the nsIWebNavigation
|
||||
* interface.
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean notifyOnHistoryReload(in nsIURI aReloadURI, in unsigned long aReloadFlags);
|
||||
|
||||
/**
|
||||
* Evict content viewers which don't lie in the "safe" range around aIndex.
|
||||
* In practice, this should leave us with no more than gHistoryMaxViewers
|
||||
* viewers associated with this SHistory object.
|
||||
*
|
||||
* Also make sure that the total number of content viewers in all windows is
|
||||
* not greater than our global max; if it is, evict viewers as appropriate.
|
||||
*
|
||||
* @param aIndex - The index around which the "safe" range is centered. In
|
||||
* general, if you just navigated the history, aIndex should be the index
|
||||
* history was navigated to.
|
||||
*/
|
||||
void evictOutOfRangeContentViewers(in long aIndex);
|
||||
|
||||
/**
|
||||
* Evict the content viewer associated with a bfcache entry
|
||||
* that has timed out.
|
||||
*/
|
||||
void evictExpiredContentViewerForEntry(in nsIBFCacheEntry aEntry);
|
||||
|
||||
/**
|
||||
* Evict all the content viewers in this session history
|
||||
*/
|
||||
void evictAllContentViewers();
|
||||
|
||||
/**
|
||||
* Removes entries from the history if their docshellID is in
|
||||
* aIDs array.
|
||||
*/
|
||||
[noscript, notxpcom] void RemoveEntries(in nsDocshellIDArray aIDs,
|
||||
in long aStartIndex);
|
||||
};
|
||||
108
docshell/shistory/nsISHistoryListener.idl
Normal file
108
docshell/shistory/nsISHistoryListener.idl
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* nsISHistoryListener defines the interface one can implement to receive
|
||||
* notifications about activities in session history and to be able to
|
||||
* cancel them.
|
||||
*
|
||||
* A session history listener will be notified when pages are added, removed
|
||||
* and loaded from session history. It can prevent any action (except adding
|
||||
* a new session history entry) from happening by returning false from the
|
||||
* corresponding callback method.
|
||||
*
|
||||
* A session history listener can be registered on a particular nsISHistory
|
||||
* instance via the nsISHistory::addSHistoryListener() method.
|
||||
*/
|
||||
[scriptable, uuid(125c0833-746a-400e-9b89-d2d18545c08a)]
|
||||
interface nsISHistoryListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when a new document is added to session history. New documents are
|
||||
* added to session history by docshell when new pages are loaded in a frame
|
||||
* or content area, for example via nsIWebNavigation::loadURI()
|
||||
*
|
||||
* @param aNewURI The URI of the document to be added to session history.
|
||||
* @param aOldIndex The index of the current history item before the operation.
|
||||
*/
|
||||
void OnHistoryNewEntry(in nsIURI aNewURI, in long aOldIndex);
|
||||
|
||||
/**
|
||||
* Called when navigating to a previous session history entry, for example
|
||||
* due to a nsIWebNavigation::goBack() call.
|
||||
*
|
||||
* @param aBackURI The URI of the session history entry being navigated to.
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryGoBack(in nsIURI aBackURI);
|
||||
|
||||
/**
|
||||
* Called when navigating to a next session history entry, for example
|
||||
* due to a nsIWebNavigation::goForward() call.
|
||||
*
|
||||
* @param aForwardURI The URI of the session history entry being navigated to.
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryGoForward(in nsIURI aForwardURI);
|
||||
|
||||
/**
|
||||
* Called when the current document is reloaded, for example due to a
|
||||
* nsIWebNavigation::reload() call.
|
||||
*
|
||||
* @param aReloadURI The URI of the document to be reloaded.
|
||||
* @param aReloadFlags Flags that indicate how the document is to be
|
||||
* refreshed. See constants on the nsIWebNavigation
|
||||
* interface.
|
||||
* @return Whether the operation can proceed.
|
||||
*
|
||||
* @see nsIWebNavigation
|
||||
*/
|
||||
boolean OnHistoryReload(in nsIURI aReloadURI, in unsigned long aReloadFlags);
|
||||
|
||||
/**
|
||||
* Called when navigating to a session history entry by index, for example,
|
||||
* when nsIWebNavigation::gotoIndex() is called.
|
||||
*
|
||||
* @param aIndex The index in session history of the entry to be loaded.
|
||||
* @param aGotoURI The URI of the session history entry to be loaded.
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryGotoIndex(in long aIndex, in nsIURI aGotoURI);
|
||||
|
||||
/**
|
||||
* Called when entries are removed from session history. Entries can be
|
||||
* removed from session history for various reasons, for example to control
|
||||
* the memory usage of the browser, to prevent users from loading documents
|
||||
* from history, to erase evidence of prior page loads, etc.
|
||||
*
|
||||
* To purge documents from session history call nsISHistory::PurgeHistory()
|
||||
*
|
||||
* @param aNumEntries The number of entries to be removed from session history.
|
||||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryPurge(in long aNumEntries);
|
||||
|
||||
/**
|
||||
* Called when an entry is replaced in the session history. Entries are
|
||||
* replaced when navigating away from non-persistent history entries (such as
|
||||
* about pages) and when history.replaceState is called.
|
||||
*
|
||||
* @param aIndex The index in session history of the entry being
|
||||
* replaced
|
||||
*/
|
||||
void OnHistoryReplaceEntry(in long aIndex);
|
||||
|
||||
/**
|
||||
* Called when nsISHistory::count has been updated. Unlike OnHistoryNewEntry
|
||||
* and OnHistoryPurge which happen before the modifications are actually done
|
||||
* and maybe cancellable, this function is called after these modifications.
|
||||
*/
|
||||
void OnLengthChange(in long aCount);
|
||||
};
|
||||
944
docshell/shistory/nsSHEntry.cpp
Normal file
944
docshell/shistory/nsSHEntry.cpp
Normal file
|
|
@ -0,0 +1,944 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSHEntry.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsDocShellEditorData.h"
|
||||
#include "nsSHEntryShared.h"
|
||||
#include "nsILayoutHistoryState.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
||||
static uint32_t gEntryID = 0;
|
||||
|
||||
nsSHEntry::nsSHEntry()
|
||||
: mShared(new nsSHEntryShared())
|
||||
, mLoadReplace(false)
|
||||
, mReferrerPolicy(mozilla::net::RP_Default)
|
||||
, mLoadType(0)
|
||||
, mID(gEntryID++)
|
||||
, mScrollPositionX(0)
|
||||
, mScrollPositionY(0)
|
||||
, mParent(nullptr)
|
||||
, mURIWasModified(false)
|
||||
, mIsSrcdocEntry(false)
|
||||
, mScrollRestorationIsManual(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsSHEntry::nsSHEntry(const nsSHEntry& aOther)
|
||||
: mShared(aOther.mShared)
|
||||
, mURI(aOther.mURI)
|
||||
, mOriginalURI(aOther.mOriginalURI)
|
||||
, mLoadReplace(aOther.mLoadReplace)
|
||||
, mReferrerURI(aOther.mReferrerURI)
|
||||
, mReferrerPolicy(aOther.mReferrerPolicy)
|
||||
, mTitle(aOther.mTitle)
|
||||
, mPostData(aOther.mPostData)
|
||||
, mLoadType(0) // XXX why not copy?
|
||||
, mID(aOther.mID)
|
||||
, mScrollPositionX(0) // XXX why not copy?
|
||||
, mScrollPositionY(0) // XXX why not copy?
|
||||
, mParent(aOther.mParent)
|
||||
, mURIWasModified(aOther.mURIWasModified)
|
||||
, mStateData(aOther.mStateData)
|
||||
, mIsSrcdocEntry(aOther.mIsSrcdocEntry)
|
||||
, mScrollRestorationIsManual(false)
|
||||
, mSrcdocData(aOther.mSrcdocData)
|
||||
, mBaseURI(aOther.mBaseURI)
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
ClearParentPtr(nsISHEntry* aEntry, void* /* aData */)
|
||||
{
|
||||
if (aEntry) {
|
||||
aEntry->SetParent(nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsSHEntry::~nsSHEntry()
|
||||
{
|
||||
// Null out the mParent pointers on all our kids.
|
||||
mChildren.EnumerateForwards(ClearParentPtr, nullptr);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry, nsISHEntryInternal)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetScrollPosition(int32_t aX, int32_t aY)
|
||||
{
|
||||
mScrollPositionX = aX;
|
||||
mScrollPositionY = aY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetScrollPosition(int32_t* aX, int32_t* aY)
|
||||
{
|
||||
*aX = mScrollPositionX;
|
||||
*aY = mScrollPositionY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetURIWasModified(bool* aOut)
|
||||
{
|
||||
*aOut = mURIWasModified;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetURIWasModified(bool aIn)
|
||||
{
|
||||
mURIWasModified = aIn;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = mURI;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetURI(nsIURI* aURI)
|
||||
{
|
||||
mURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetOriginalURI(nsIURI** aOriginalURI)
|
||||
{
|
||||
*aOriginalURI = mOriginalURI;
|
||||
NS_IF_ADDREF(*aOriginalURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
|
||||
{
|
||||
mOriginalURI = aOriginalURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetLoadReplace(bool* aLoadReplace)
|
||||
{
|
||||
*aLoadReplace = mLoadReplace;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetLoadReplace(bool aLoadReplace)
|
||||
{
|
||||
mLoadReplace = aLoadReplace;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetReferrerURI(nsIURI** aReferrerURI)
|
||||
{
|
||||
*aReferrerURI = mReferrerURI;
|
||||
NS_IF_ADDREF(*aReferrerURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetReferrerURI(nsIURI* aReferrerURI)
|
||||
{
|
||||
mReferrerURI = aReferrerURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetReferrerPolicy(uint32_t* aReferrerPolicy)
|
||||
{
|
||||
*aReferrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = aReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetContentViewer(nsIContentViewer* aViewer)
|
||||
{
|
||||
return mShared->SetContentViewer(aViewer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetContentViewer(nsIContentViewer** aResult)
|
||||
{
|
||||
*aResult = mShared->mContentViewer;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetAnyContentViewer(nsISHEntry** aOwnerEntry,
|
||||
nsIContentViewer** aResult)
|
||||
{
|
||||
// Find a content viewer in the root node or any of its children,
|
||||
// assuming that there is only one content viewer total in any one
|
||||
// nsSHEntry tree
|
||||
GetContentViewer(aResult);
|
||||
if (*aResult) {
|
||||
#ifdef DEBUG_PAGE_CACHE
|
||||
printf("Found content viewer\n");
|
||||
#endif
|
||||
*aOwnerEntry = this;
|
||||
NS_ADDREF(*aOwnerEntry);
|
||||
return NS_OK;
|
||||
}
|
||||
// The root SHEntry doesn't have a ContentViewer, so check child nodes
|
||||
for (int32_t i = 0; i < mChildren.Count(); i++) {
|
||||
nsISHEntry* child = mChildren[i];
|
||||
if (child) {
|
||||
#ifdef DEBUG_PAGE_CACHE
|
||||
printf("Evaluating SHEntry child %d\n", i);
|
||||
#endif
|
||||
child->GetAnyContentViewer(aOwnerEntry, aResult);
|
||||
if (*aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetSticky(bool aSticky)
|
||||
{
|
||||
mShared->mSticky = aSticky;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetSticky(bool* aSticky)
|
||||
{
|
||||
*aSticky = mShared->mSticky;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetTitle(char16_t** aTitle)
|
||||
{
|
||||
// Check for empty title...
|
||||
if (mTitle.IsEmpty() && mURI) {
|
||||
// Default title is the URL.
|
||||
nsAutoCString spec;
|
||||
if (NS_SUCCEEDED(mURI->GetSpec(spec))) {
|
||||
AppendUTF8toUTF16(spec, mTitle);
|
||||
}
|
||||
}
|
||||
|
||||
*aTitle = ToNewUnicode(mTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetTitle(const nsAString& aTitle)
|
||||
{
|
||||
mTitle = aTitle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetPostData(nsIInputStream** aResult)
|
||||
{
|
||||
*aResult = mPostData;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetPostData(nsIInputStream* aPostData)
|
||||
{
|
||||
mPostData = aPostData;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult)
|
||||
{
|
||||
*aResult = mShared->mLayoutHistoryState;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState)
|
||||
{
|
||||
mShared->mLayoutHistoryState = aState;
|
||||
if (mShared->mLayoutHistoryState) {
|
||||
mShared->mLayoutHistoryState->SetScrollPositionOnly(
|
||||
!mShared->mSaveLayoutState);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetLoadType(uint32_t* aResult)
|
||||
{
|
||||
*aResult = mLoadType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetLoadType(uint32_t aLoadType)
|
||||
{
|
||||
mLoadType = aLoadType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetID(uint32_t* aResult)
|
||||
{
|
||||
*aResult = mID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetID(uint32_t aID)
|
||||
{
|
||||
mID = aID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSHEntryShared*
|
||||
nsSHEntry::GetSharedState()
|
||||
{
|
||||
return mShared;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetIsSubFrame(bool* aFlag)
|
||||
{
|
||||
*aFlag = mShared->mIsFrameNavigation;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetIsSubFrame(bool aFlag)
|
||||
{
|
||||
mShared->mIsFrameNavigation = aFlag;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetCacheKey(nsISupports** aResult)
|
||||
{
|
||||
*aResult = mShared->mCacheKey;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetCacheKey(nsISupports* aCacheKey)
|
||||
{
|
||||
mShared->mCacheKey = aCacheKey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetSaveLayoutStateFlag(bool* aFlag)
|
||||
{
|
||||
*aFlag = mShared->mSaveLayoutState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetSaveLayoutStateFlag(bool aFlag)
|
||||
{
|
||||
mShared->mSaveLayoutState = aFlag;
|
||||
if (mShared->mLayoutHistoryState) {
|
||||
mShared->mLayoutHistoryState->SetScrollPositionOnly(!aFlag);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetExpirationStatus(bool* aFlag)
|
||||
{
|
||||
*aFlag = mShared->mExpired;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetExpirationStatus(bool aFlag)
|
||||
{
|
||||
mShared->mExpired = aFlag;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
aContentType = mShared->mContentType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetContentType(const nsACString& aContentType)
|
||||
{
|
||||
mShared->mContentType = aContentType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::Create(nsIURI* aURI, const nsAString& aTitle,
|
||||
nsIInputStream* aInputStream,
|
||||
nsILayoutHistoryState* aLayoutHistoryState,
|
||||
nsISupports* aCacheKey, const nsACString& aContentType,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
nsIPrincipal* aPrincipalToInherit,
|
||||
uint64_t aDocShellID,
|
||||
bool aDynamicCreation)
|
||||
{
|
||||
mURI = aURI;
|
||||
mTitle = aTitle;
|
||||
mPostData = aInputStream;
|
||||
|
||||
// Set the LoadType by default to loadHistory during creation
|
||||
mLoadType = (uint32_t)nsIDocShellLoadInfo::loadHistory;
|
||||
|
||||
mShared->mCacheKey = aCacheKey;
|
||||
mShared->mContentType = aContentType;
|
||||
mShared->mTriggeringPrincipal = aTriggeringPrincipal;
|
||||
mShared->mPrincipalToInherit = aPrincipalToInherit;
|
||||
mShared->mDocShellID = aDocShellID;
|
||||
mShared->mDynamicallyCreated = aDynamicCreation;
|
||||
|
||||
// By default all entries are set false for subframe flag.
|
||||
// nsDocShell::CloneAndReplace() which creates entries for
|
||||
// all subframe navigations, sets the flag to true.
|
||||
mShared->mIsFrameNavigation = false;
|
||||
|
||||
// By default we save LayoutHistoryState
|
||||
mShared->mSaveLayoutState = true;
|
||||
mShared->mLayoutHistoryState = aLayoutHistoryState;
|
||||
|
||||
// By default the page is not expired
|
||||
mShared->mExpired = false;
|
||||
|
||||
mIsSrcdocEntry = false;
|
||||
mSrcdocData = NullString();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::Clone(nsISHEntry** aResult)
|
||||
{
|
||||
*aResult = new nsSHEntry(*this);
|
||||
NS_ADDREF(*aResult);
|
||||
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
|
||||
*
|
||||
* XXX this method should not be scriptable if this is the case!!
|
||||
*/
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetWindowState(nsISupports* aState)
|
||||
{
|
||||
mShared->mWindowState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetWindowState(nsISupports** aState)
|
||||
{
|
||||
NS_IF_ADDREF(*aState = mShared->mWindowState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetViewerBounds(const nsIntRect& aBounds)
|
||||
{
|
||||
mShared->mViewerBounds = aBounds;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetViewerBounds(nsIntRect& aBounds)
|
||||
{
|
||||
aBounds = mShared->mViewerBounds;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal)
|
||||
{
|
||||
NS_IF_ADDREF(*aTriggeringPrincipal = mShared->mTriggeringPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal)
|
||||
{
|
||||
mShared->mTriggeringPrincipal = aTriggeringPrincipal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit)
|
||||
{
|
||||
NS_IF_ADDREF(*aPrincipalToInherit = mShared->mPrincipalToInherit);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit)
|
||||
{
|
||||
mShared->mPrincipalToInherit = aPrincipalToInherit;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry** aEntry)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEntry);
|
||||
NS_IF_ADDREF(*aEntry = mShared);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsSHEntry::HasBFCacheEntry(nsIBFCacheEntry* aEntry)
|
||||
{
|
||||
return static_cast<nsIBFCacheEntry*>(mShared) == aEntry;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::AdoptBFCacheEntry(nsISHEntry* aEntry)
|
||||
{
|
||||
nsCOMPtr<nsISHEntryInternal> shEntry = do_QueryInterface(aEntry);
|
||||
NS_ENSURE_STATE(shEntry);
|
||||
|
||||
nsSHEntryShared* shared = shEntry->GetSharedState();
|
||||
NS_ENSURE_STATE(shared);
|
||||
|
||||
mShared = shared;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SharesDocumentWith(nsISHEntry* aEntry, bool* aOut)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOut);
|
||||
|
||||
nsCOMPtr<nsISHEntryInternal> internal = do_QueryInterface(aEntry);
|
||||
NS_ENSURE_STATE(internal);
|
||||
|
||||
*aOut = mShared == internal->GetSharedState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::AbandonBFCacheEntry()
|
||||
{
|
||||
mShared = nsSHEntryShared::Duplicate(mShared);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetIsSrcdocEntry(bool* aIsSrcdocEntry)
|
||||
{
|
||||
*aIsSrcdocEntry = mIsSrcdocEntry;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetSrcdocData(nsAString& aSrcdocData)
|
||||
{
|
||||
aSrcdocData = mSrcdocData;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetSrcdocData(const nsAString& aSrcdocData)
|
||||
{
|
||||
mSrcdocData = aSrcdocData;
|
||||
mIsSrcdocEntry = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetBaseURI(nsIURI** aBaseURI)
|
||||
{
|
||||
*aBaseURI = mBaseURI;
|
||||
NS_IF_ADDREF(*aBaseURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetBaseURI(nsIURI* aBaseURI)
|
||||
{
|
||||
mBaseURI = aBaseURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetScrollRestorationIsManual(bool* aIsManual)
|
||||
{
|
||||
*aIsManual = mScrollRestorationIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetScrollRestorationIsManual(bool aIsManual)
|
||||
{
|
||||
mScrollRestorationIsManual = aIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetChildCount(int32_t* aCount)
|
||||
{
|
||||
*aCount = mChildren.Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::AddChild(nsISHEntry* aChild, int32_t aOffset)
|
||||
{
|
||||
if (aChild) {
|
||||
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (aOffset < 0) {
|
||||
mChildren.AppendObject(aChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// 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");
|
||||
|
||||
bool newChildIsDyn = false;
|
||||
if (aChild) {
|
||||
aChild->IsDynamicallyAdded(&newChildIsDyn);
|
||||
}
|
||||
|
||||
// If the new child is dynamically added, try to add it to aOffset, but if
|
||||
// there are non-dynamically added children, the child must be after those.
|
||||
if (newChildIsDyn) {
|
||||
int32_t lastNonDyn = aOffset - 1;
|
||||
for (int32_t i = aOffset; i < mChildren.Count(); ++i) {
|
||||
nsISHEntry* entry = mChildren[i];
|
||||
if (entry) {
|
||||
bool dyn = false;
|
||||
entry->IsDynamicallyAdded(&dyn);
|
||||
if (dyn) {
|
||||
break;
|
||||
} else {
|
||||
lastNonDyn = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// InsertObjectAt allows only appending one object.
|
||||
// If aOffset is larger than Count(), we must first manually
|
||||
// set the capacity.
|
||||
if (aOffset > mChildren.Count()) {
|
||||
mChildren.SetCount(aOffset);
|
||||
}
|
||||
if (!mChildren.InsertObjectAt(aChild, lastNonDyn + 1)) {
|
||||
NS_WARNING("Adding a child failed!");
|
||||
aChild->SetParent(nullptr);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// If the new child isn't dynamically added, it should be set to aOffset.
|
||||
// If there are dynamically added children before that, those must be
|
||||
// moved to be after aOffset.
|
||||
if (mChildren.Count() > 0) {
|
||||
int32_t start = std::min(mChildren.Count() - 1, aOffset);
|
||||
int32_t dynEntryIndex = -1;
|
||||
nsISHEntry* dynEntry = nullptr;
|
||||
for (int32_t i = start; i >= 0; --i) {
|
||||
nsISHEntry* entry = mChildren[i];
|
||||
if (entry) {
|
||||
bool dyn = false;
|
||||
entry->IsDynamicallyAdded(&dyn);
|
||||
if (dyn) {
|
||||
dynEntryIndex = i;
|
||||
dynEntry = entry;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dynEntry) {
|
||||
nsCOMArray<nsISHEntry> tmp;
|
||||
tmp.SetCount(aOffset - dynEntryIndex + 1);
|
||||
mChildren.InsertObjectsAt(tmp, dynEntryIndex);
|
||||
NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there isn't anything at aOffset.
|
||||
if (aOffset < mChildren.Count()) {
|
||||
nsISHEntry* oldChild = mChildren[aOffset];
|
||||
if (oldChild && oldChild != aChild) {
|
||||
NS_ERROR("Adding a child where we already have a child? This may misbehave");
|
||||
oldChild->SetParent(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
mChildren.ReplaceObjectAt(aChild, aOffset);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::RemoveChild(nsISHEntry* aChild)
|
||||
{
|
||||
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
|
||||
bool childRemoved = false;
|
||||
bool dynamic = false;
|
||||
aChild->IsDynamicallyAdded(&dynamic);
|
||||
if (dynamic) {
|
||||
childRemoved = mChildren.RemoveObject(aChild);
|
||||
} else {
|
||||
int32_t index = mChildren.IndexOfObject(aChild);
|
||||
if (index >= 0) {
|
||||
mChildren.ReplaceObjectAt(nullptr, index);
|
||||
childRemoved = true;
|
||||
}
|
||||
}
|
||||
if (childRemoved) {
|
||||
aChild->SetParent(nullptr);
|
||||
|
||||
// reduce the child count, i.e. remove empty children at the end
|
||||
for (int32_t i = mChildren.Count() - 1; i >= 0 && !mChildren[i]; --i) {
|
||||
if (!mChildren.RemoveObjectAt(i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry** aResult)
|
||||
{
|
||||
if (aIndex >= 0 && aIndex < mChildren.Count()) {
|
||||
*aResult = mChildren[aIndex];
|
||||
// yes, mChildren can have holes in it. AddChild's offset parameter makes
|
||||
// that possible.
|
||||
NS_IF_ADDREF(*aResult);
|
||||
} else {
|
||||
*aResult = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry)
|
||||
{
|
||||
NS_ENSURE_STATE(aNewEntry);
|
||||
|
||||
uint64_t docshellID;
|
||||
aNewEntry->GetDocshellID(&docshellID);
|
||||
|
||||
uint64_t otherID;
|
||||
for (int32_t i = 0; i < mChildren.Count(); ++i) {
|
||||
if (mChildren[i] && NS_SUCCEEDED(mChildren[i]->GetDocshellID(&otherID)) &&
|
||||
docshellID == otherID) {
|
||||
mChildren[i]->SetParent(nullptr);
|
||||
mChildren.ReplaceObjectAt(aNewEntry, i);
|
||||
return aNewEntry->SetParent(this);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::AddChildShell(nsIDocShellTreeItem* aShell)
|
||||
{
|
||||
NS_ASSERTION(aShell, "Null child shell added to history entry");
|
||||
mShared->mChildShells.AppendObject(aShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::ChildShellAt(int32_t aIndex, nsIDocShellTreeItem** aShell)
|
||||
{
|
||||
NS_IF_ADDREF(*aShell = mShared->mChildShells.SafeObjectAt(aIndex));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::ClearChildShells()
|
||||
{
|
||||
mShared->mChildShells.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetRefreshURIList(nsIMutableArray** aList)
|
||||
{
|
||||
NS_IF_ADDREF(*aList = mShared->mRefreshURIList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetRefreshURIList(nsIMutableArray* aList)
|
||||
{
|
||||
mShared->mRefreshURIList = aList;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SyncPresentationState()
|
||||
{
|
||||
return mShared->SyncPresentationState();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntry::RemoveFromBFCacheSync()
|
||||
{
|
||||
mShared->RemoveFromBFCacheSync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntry::RemoveFromBFCacheAsync()
|
||||
{
|
||||
mShared->RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
nsDocShellEditorData*
|
||||
nsSHEntry::ForgetEditorData()
|
||||
{
|
||||
// XXX jlebar Check how this is used.
|
||||
return mShared->mEditorData.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntry::SetEditorData(nsDocShellEditorData* aData)
|
||||
{
|
||||
NS_ASSERTION(!(aData && mShared->mEditorData),
|
||||
"We're going to overwrite an owning ref!");
|
||||
if (mShared->mEditorData != aData) {
|
||||
mShared->mEditorData = aData;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsSHEntry::HasDetachedEditor()
|
||||
{
|
||||
return mShared->mEditorData != nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetStateData(nsIStructuredCloneContainer** aContainer)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContainer);
|
||||
NS_IF_ADDREF(*aContainer = mStateData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetStateData(nsIStructuredCloneContainer* aContainer)
|
||||
{
|
||||
mStateData = aContainer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::IsDynamicallyAdded(bool* aAdded)
|
||||
{
|
||||
*aAdded = mShared->mDynamicallyCreated;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::HasDynamicallyAddedChild(bool* aAdded)
|
||||
{
|
||||
*aAdded = false;
|
||||
for (int32_t i = 0; i < mChildren.Count(); ++i) {
|
||||
nsISHEntry* entry = mChildren[i];
|
||||
if (entry) {
|
||||
entry->IsDynamicallyAdded(aAdded);
|
||||
if (*aAdded) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetDocshellID(uint64_t* aID)
|
||||
{
|
||||
*aID = mShared->mDocShellID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetDocshellID(uint64_t aID)
|
||||
{
|
||||
mShared->mDocShellID = aID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetLastTouched(uint32_t* aLastTouched)
|
||||
{
|
||||
*aLastTouched = mShared->mLastTouched;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetLastTouched(uint32_t aLastTouched)
|
||||
{
|
||||
mShared->mLastTouched = aLastTouched;
|
||||
return NS_OK;
|
||||
}
|
||||
71
docshell/shistory/nsSHEntry.h
Normal file
71
docshell/shistory/nsSHEntry.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsSHEntry_h
|
||||
#define nsSHEntry_h
|
||||
|
||||
// Helper Classes
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
// Interfaces needed
|
||||
#include "nsISHEntry.h"
|
||||
#include "nsISHContainer.h"
|
||||
|
||||
class nsSHEntryShared;
|
||||
class nsIInputStream;
|
||||
class nsIURI;
|
||||
|
||||
class nsSHEntry final : public nsISHEntry,
|
||||
public nsISHContainer,
|
||||
public nsISHEntryInternal
|
||||
{
|
||||
public:
|
||||
nsSHEntry();
|
||||
nsSHEntry(const nsSHEntry& aOther);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHENTRY
|
||||
NS_DECL_NSISHENTRYINTERNAL
|
||||
NS_DECL_NSISHCONTAINER
|
||||
|
||||
void DropPresentationState();
|
||||
|
||||
static nsresult Startup();
|
||||
static void Shutdown();
|
||||
|
||||
private:
|
||||
~nsSHEntry();
|
||||
|
||||
// We share the state in here with other SHEntries which correspond to the
|
||||
// same document.
|
||||
RefPtr<nsSHEntryShared> mShared;
|
||||
|
||||
// See nsSHEntry.idl for comments on these members.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
bool mLoadReplace;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsString mTitle;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
uint32_t mLoadType;
|
||||
uint32_t mID;
|
||||
int32_t mScrollPositionX;
|
||||
int32_t mScrollPositionY;
|
||||
nsISHEntry* mParent;
|
||||
nsCOMArray<nsISHEntry> mChildren;
|
||||
bool mURIWasModified;
|
||||
nsCOMPtr<nsIStructuredCloneContainer> mStateData;
|
||||
bool mIsSrcdocEntry;
|
||||
bool mScrollRestorationIsManual;
|
||||
nsString mSrcdocData;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
};
|
||||
|
||||
#endif /* nsSHEntry_h */
|
||||
385
docshell/shistory/nsSHEntryShared.cpp
Normal file
385
docshell/shistory/nsSHEntryShared.cpp
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSHEntryShared.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsDocShellEditorData.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsILayoutHistoryState.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsArray.h"
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
||||
namespace {
|
||||
|
||||
uint64_t gSHEntrySharedID = 0;
|
||||
|
||||
} // namespace
|
||||
|
||||
#define CONTENT_VIEWER_TIMEOUT_SECONDS "browser.sessionhistory.contentViewerTimeout"
|
||||
// Default this to time out unused content viewers after 30 minutes
|
||||
#define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30 * 60)
|
||||
|
||||
typedef nsExpirationTracker<nsSHEntryShared, 3> HistoryTrackerBase;
|
||||
class HistoryTracker final : public HistoryTrackerBase
|
||||
{
|
||||
public:
|
||||
explicit HistoryTracker(uint32_t aTimeout)
|
||||
: HistoryTrackerBase(1000 * aTimeout / 2, "HistoryTracker")
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void NotifyExpired(nsSHEntryShared* aObj)
|
||||
{
|
||||
RemoveObject(aObj);
|
||||
aObj->Expire();
|
||||
}
|
||||
};
|
||||
|
||||
static HistoryTracker* gHistoryTracker = nullptr;
|
||||
|
||||
void
|
||||
nsSHEntryShared::EnsureHistoryTracker()
|
||||
{
|
||||
if (!gHistoryTracker) {
|
||||
// nsExpirationTracker doesn't allow one to change the timer period,
|
||||
// so just set it once when the history tracker is used for the first time.
|
||||
gHistoryTracker = new HistoryTracker(
|
||||
mozilla::Preferences::GetUint(CONTENT_VIEWER_TIMEOUT_SECONDS,
|
||||
CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::Shutdown()
|
||||
{
|
||||
delete gHistoryTracker;
|
||||
gHistoryTracker = nullptr;
|
||||
}
|
||||
|
||||
nsSHEntryShared::nsSHEntryShared()
|
||||
: mDocShellID(0)
|
||||
, mIsFrameNavigation(false)
|
||||
, mSaveLayoutState(true)
|
||||
, mSticky(true)
|
||||
, mDynamicallyCreated(false)
|
||||
, mLastTouched(0)
|
||||
, mID(gSHEntrySharedID++)
|
||||
, mExpired(false)
|
||||
, mViewerBounds(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
nsSHEntryShared::~nsSHEntryShared()
|
||||
{
|
||||
RemoveFromExpirationTracker();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gHistoryTracker) {
|
||||
// Check that we're not still on track to expire. We shouldn't be, because
|
||||
// we just removed ourselves!
|
||||
nsExpirationTracker<nsSHEntryShared, 3>::Iterator iterator(gHistoryTracker);
|
||||
|
||||
nsSHEntryShared* elem;
|
||||
while ((elem = iterator.Next()) != nullptr) {
|
||||
NS_ASSERTION(elem != this, "Found dead entry still in the tracker!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mContentViewer) {
|
||||
RemoveFromBFCacheSync();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSHEntryShared, nsIBFCacheEntry, nsIMutationObserver)
|
||||
|
||||
already_AddRefed<nsSHEntryShared>
|
||||
nsSHEntryShared::Duplicate(nsSHEntryShared* aEntry)
|
||||
{
|
||||
RefPtr<nsSHEntryShared> newEntry = new nsSHEntryShared();
|
||||
|
||||
newEntry->mDocShellID = aEntry->mDocShellID;
|
||||
newEntry->mChildShells.AppendObjects(aEntry->mChildShells);
|
||||
newEntry->mTriggeringPrincipal = aEntry->mTriggeringPrincipal;
|
||||
newEntry->mPrincipalToInherit = aEntry->mPrincipalToInherit;
|
||||
newEntry->mContentType.Assign(aEntry->mContentType);
|
||||
newEntry->mIsFrameNavigation = aEntry->mIsFrameNavigation;
|
||||
newEntry->mSaveLayoutState = aEntry->mSaveLayoutState;
|
||||
newEntry->mSticky = aEntry->mSticky;
|
||||
newEntry->mDynamicallyCreated = aEntry->mDynamicallyCreated;
|
||||
newEntry->mCacheKey = aEntry->mCacheKey;
|
||||
newEntry->mLastTouched = aEntry->mLastTouched;
|
||||
|
||||
return newEntry.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::RemoveFromExpirationTracker()
|
||||
{
|
||||
if (gHistoryTracker && GetExpirationState()->IsTracked()) {
|
||||
gHistoryTracker->RemoveObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::SyncPresentationState()
|
||||
{
|
||||
if (mContentViewer && mWindowState) {
|
||||
// If we have a content viewer and a window state, we should be ok.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DropPresentationState();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::DropPresentationState()
|
||||
{
|
||||
RefPtr<nsSHEntryShared> kungFuDeathGrip = this;
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->SetBFCacheEntry(nullptr);
|
||||
mDocument->RemoveMutationObserver(this);
|
||||
mDocument = nullptr;
|
||||
}
|
||||
if (mContentViewer) {
|
||||
mContentViewer->ClearHistoryEntry();
|
||||
}
|
||||
|
||||
RemoveFromExpirationTracker();
|
||||
mContentViewer = nullptr;
|
||||
mSticky = true;
|
||||
mWindowState = nullptr;
|
||||
mViewerBounds.SetRect(0, 0, 0, 0);
|
||||
mChildShells.Clear();
|
||||
mRefreshURIList = nullptr;
|
||||
mEditorData = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::Expire()
|
||||
{
|
||||
// This entry has timed out. If we still have a content viewer, we need to
|
||||
// evict it.
|
||||
if (!mContentViewer) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> container;
|
||||
mContentViewer->GetContainer(getter_AddRefs(container));
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(container);
|
||||
if (!treeItem) {
|
||||
return;
|
||||
}
|
||||
// We need to find the root DocShell since only that object has an
|
||||
// SHistory and we need the SHistory to evict content viewers
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(root);
|
||||
nsCOMPtr<nsISHistory> history;
|
||||
webNav->GetSessionHistory(getter_AddRefs(history));
|
||||
nsCOMPtr<nsISHistoryInternal> historyInt = do_QueryInterface(history);
|
||||
if (!historyInt) {
|
||||
return;
|
||||
}
|
||||
historyInt->EvictExpiredContentViewerForEntry(this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::SetContentViewer(nsIContentViewer* aViewer)
|
||||
{
|
||||
NS_PRECONDITION(!aViewer || !mContentViewer,
|
||||
"SHEntryShared already contains viewer");
|
||||
|
||||
if (mContentViewer || !aViewer) {
|
||||
DropPresentationState();
|
||||
}
|
||||
|
||||
mContentViewer = aViewer;
|
||||
|
||||
if (mContentViewer) {
|
||||
EnsureHistoryTracker();
|
||||
gHistoryTracker->AddObject(this);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
|
||||
// Store observed document in strong pointer in case it is removed from
|
||||
// the contentviewer
|
||||
mDocument = do_QueryInterface(domDoc);
|
||||
if (mDocument) {
|
||||
mDocument->SetBFCacheEntry(this);
|
||||
mDocument->AddMutationObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::RemoveFromBFCacheSync()
|
||||
{
|
||||
NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!");
|
||||
|
||||
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
|
||||
DropPresentationState();
|
||||
|
||||
// Warning! The call to DropPresentationState could have dropped the last
|
||||
// reference to this object, so don't access members beyond here.
|
||||
|
||||
if (viewer) {
|
||||
viewer->Destroy();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class DestroyViewerEvent : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument)
|
||||
: mViewer(aViewer)
|
||||
, mDocument(aDocument)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
if (mViewer) {
|
||||
mViewer->Destroy();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentViewer> mViewer;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::RemoveFromBFCacheAsync()
|
||||
{
|
||||
NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!");
|
||||
|
||||
// Release the reference to the contentviewer asynchronously so that the
|
||||
// document doesn't get nuked mid-mutation.
|
||||
|
||||
nsCOMPtr<nsIRunnable> evt = new DestroyViewerEvent(mContentViewer, mDocument);
|
||||
nsresult rv = NS_DispatchToCurrentThread(evt);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to dispatch DestroyViewerEvent");
|
||||
} else {
|
||||
// Drop presentation. Only do this if we succeeded in posting the event
|
||||
// since otherwise the document could be torn down mid-mutation, causing
|
||||
// crashes.
|
||||
DropPresentationState();
|
||||
}
|
||||
|
||||
// Careful! The call to DropPresentationState could have dropped the last
|
||||
// reference to this nsSHEntryShared, so don't access members beyond here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::GetID(uint64_t* aID)
|
||||
{
|
||||
*aID = mID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
{
|
||||
NS_NOTREACHED("Document destroyed while we're holding a strong ref to it");
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument,
|
||||
dom::Element* aContent,
|
||||
int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aNewValue)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::NativeAnonymousChildListChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
bool aIsRemove)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::AttributeChanged(nsIDocument* aDocument,
|
||||
dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent,
|
||||
int32_t /* unused */)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
int32_t /* unused */)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
int32_t aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
RemoveFromBFCacheAsync();
|
||||
}
|
||||
|
||||
void
|
||||
nsSHEntryShared::ParentChainChanged(nsIContent* aContent)
|
||||
{
|
||||
}
|
||||
97
docshell/shistory/nsSHEntryShared.h
Normal file
97
docshell/shistory/nsSHEntryShared.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsSHEntryShared_h__
|
||||
#define nsSHEntryShared_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIBFCacheEntry.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsSHEntry;
|
||||
class nsISHEntry;
|
||||
class nsIDocument;
|
||||
class nsIContentViewer;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsILayoutHistoryState;
|
||||
class nsDocShellEditorData;
|
||||
class nsIMutableArray;
|
||||
|
||||
// A document may have multiple SHEntries, either due to hash navigations or
|
||||
// calls to history.pushState. SHEntries corresponding to the same document
|
||||
// share many members; in particular, they share state related to the
|
||||
// back/forward cache.
|
||||
//
|
||||
// nsSHEntryShared is the vehicle for this sharing.
|
||||
class nsSHEntryShared final
|
||||
: public nsIBFCacheEntry
|
||||
, public nsIMutationObserver
|
||||
{
|
||||
public:
|
||||
static void EnsureHistoryTracker();
|
||||
static void Shutdown();
|
||||
|
||||
nsSHEntryShared();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMUTATIONOBSERVER
|
||||
NS_DECL_NSIBFCACHEENTRY
|
||||
|
||||
nsExpirationState *GetExpirationState() { return &mExpirationState; }
|
||||
|
||||
private:
|
||||
~nsSHEntryShared();
|
||||
|
||||
friend class nsSHEntry;
|
||||
|
||||
friend class HistoryTracker;
|
||||
|
||||
static already_AddRefed<nsSHEntryShared> Duplicate(nsSHEntryShared* aEntry);
|
||||
|
||||
void RemoveFromExpirationTracker();
|
||||
void Expire();
|
||||
nsresult SyncPresentationState();
|
||||
void DropPresentationState();
|
||||
|
||||
nsresult SetContentViewer(nsIContentViewer* aViewer);
|
||||
|
||||
// See nsISHEntry.idl for an explanation of these members.
|
||||
|
||||
// These members are copied by nsSHEntryShared::Duplicate(). If you add a
|
||||
// member here, be sure to update the Duplicate() implementation.
|
||||
uint64_t mDocShellID;
|
||||
nsCOMArray<nsIDocShellTreeItem> mChildShells;
|
||||
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
|
||||
nsCString mContentType;
|
||||
bool mIsFrameNavigation;
|
||||
bool mSaveLayoutState;
|
||||
bool mSticky;
|
||||
bool mDynamicallyCreated;
|
||||
nsCOMPtr<nsISupports> mCacheKey;
|
||||
uint32_t mLastTouched;
|
||||
|
||||
// These members aren't copied by nsSHEntryShared::Duplicate() because
|
||||
// they're specific to a particular content viewer.
|
||||
uint64_t mID;
|
||||
nsCOMPtr<nsIContentViewer> mContentViewer;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
|
||||
bool mExpired;
|
||||
nsCOMPtr<nsISupports> mWindowState;
|
||||
nsIntRect mViewerBounds;
|
||||
nsCOMPtr<nsIMutableArray> mRefreshURIList;
|
||||
nsExpirationState mExpirationState;
|
||||
nsAutoPtr<nsDocShellEditorData> mEditorData;
|
||||
};
|
||||
|
||||
#endif
|
||||
107
docshell/shistory/nsSHTransaction.cpp
Normal file
107
docshell/shistory/nsSHTransaction.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSHTransaction.h"
|
||||
#include "nsISHEntry.h"
|
||||
|
||||
nsSHTransaction::nsSHTransaction()
|
||||
: mPersist(true)
|
||||
, mPrev(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsSHTransaction::~nsSHTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsSHTransaction)
|
||||
NS_IMPL_RELEASE(nsSHTransaction)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSHTransaction)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISHTransaction)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISHTransaction)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::Create(nsISHEntry* aSHEntry, nsISHTransaction* aPrev)
|
||||
{
|
||||
SetSHEntry(aSHEntry);
|
||||
if (aPrev) {
|
||||
aPrev->SetNext(this);
|
||||
}
|
||||
|
||||
SetPrev(aPrev);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::GetSHEntry(nsISHEntry** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mSHEntry;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::SetSHEntry(nsISHEntry* aSHEntry)
|
||||
{
|
||||
mSHEntry = aSHEntry;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::GetNext(nsISHTransaction** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mNext;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::SetNext(nsISHTransaction* aNext)
|
||||
{
|
||||
if (aNext) {
|
||||
NS_ENSURE_SUCCESS(aNext->SetPrev(this), NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
mNext = aNext;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::SetPrev(nsISHTransaction* aPrev)
|
||||
{
|
||||
/* This is weak reference to parent. Do not Addref it */
|
||||
mPrev = aPrev;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHTransaction::GetPrev(nsISHTransaction** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mPrev;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::SetPersist(bool aPersist)
|
||||
{
|
||||
mPersist = aPersist;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHTransaction::GetPersist(bool* aPersist)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPersist);
|
||||
|
||||
*aPersist = mPersist;
|
||||
return NS_OK;
|
||||
}
|
||||
37
docshell/shistory/nsSHTransaction.h
Normal file
37
docshell/shistory/nsSHTransaction.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsSHTransaction_h
|
||||
#define nsSHTransaction_h
|
||||
|
||||
// Helper Classes
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
// Needed interfaces
|
||||
#include "nsISHTransaction.h"
|
||||
|
||||
class nsISHEntry;
|
||||
|
||||
class nsSHTransaction : public nsISHTransaction
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHTRANSACTION
|
||||
|
||||
nsSHTransaction();
|
||||
|
||||
protected:
|
||||
virtual ~nsSHTransaction();
|
||||
|
||||
protected:
|
||||
bool mPersist;
|
||||
|
||||
nsISHTransaction* mPrev; // Weak Reference
|
||||
nsCOMPtr<nsISHTransaction> mNext;
|
||||
nsCOMPtr<nsISHEntry> mSHEntry;
|
||||
};
|
||||
|
||||
#endif /* nsSHTransaction_h */
|
||||
1932
docshell/shistory/nsSHistory.cpp
Normal file
1932
docshell/shistory/nsSHistory.cpp
Normal file
File diff suppressed because it is too large
Load diff
133
docshell/shistory/nsSHistory.h
Normal file
133
docshell/shistory/nsSHistory.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsSHistory_h
|
||||
#define nsSHistory_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIPartialSHistoryListener.h"
|
||||
|
||||
#include "prclist.h"
|
||||
|
||||
class nsIDocShell;
|
||||
class nsSHEnumerator;
|
||||
class nsSHistoryObserver;
|
||||
class nsISHEntry;
|
||||
class nsISHTransaction;
|
||||
|
||||
class nsSHistory final : public PRCList,
|
||||
public nsISHistory,
|
||||
public nsISHistoryInternal,
|
||||
public nsIWebNavigation
|
||||
{
|
||||
public:
|
||||
nsSHistory();
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHISTORY
|
||||
NS_DECL_NSISHISTORYINTERNAL
|
||||
NS_DECL_NSIWEBNAVIGATION
|
||||
|
||||
// One time initialization method called upon docshell module construction
|
||||
static nsresult Startup();
|
||||
static void Shutdown();
|
||||
static void UpdatePrefs();
|
||||
|
||||
// Max number of total cached content viewers. If the pref
|
||||
// browser.sessionhistory.max_total_viewers is negative, then
|
||||
// this value is calculated based on the total amount of memory.
|
||||
// Otherwise, it comes straight from the pref.
|
||||
static uint32_t GetMaxTotalViewers() { return sHistoryMaxTotalViewers; }
|
||||
|
||||
private:
|
||||
virtual ~nsSHistory();
|
||||
friend class nsSHEnumerator;
|
||||
friend class nsSHistoryObserver;
|
||||
|
||||
// Could become part of nsIWebNavigation
|
||||
NS_IMETHOD GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult);
|
||||
nsresult LoadDifferingEntries(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
|
||||
nsIDocShell* aRootDocShell, long aLoadType,
|
||||
bool& aDifferenceFound);
|
||||
nsresult InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS,
|
||||
long aLoadType);
|
||||
|
||||
NS_IMETHOD LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult PrintHistory();
|
||||
#endif
|
||||
|
||||
// Evict content viewers in this window which don't lie in the "safe" range
|
||||
// around aIndex.
|
||||
void EvictOutOfRangeWindowContentViewers(int32_t aIndex);
|
||||
static void GloballyEvictContentViewers();
|
||||
static void GloballyEvictAllContentViewers();
|
||||
|
||||
// Calculates a max number of total
|
||||
// content viewers to cache, based on amount of total memory
|
||||
static uint32_t CalcMaxTotalViewers();
|
||||
|
||||
void RemoveDynEntries(int32_t aOldIndex, int32_t aNewIndex);
|
||||
|
||||
nsresult LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType,
|
||||
uint32_t aHistCmd);
|
||||
|
||||
// aIndex is the index of the transaction which may be removed.
|
||||
// If aKeepNext is true, aIndex is compared to aIndex + 1,
|
||||
// otherwise comparison is done to aIndex - 1.
|
||||
bool RemoveDuplicate(int32_t aIndex, bool aKeepNext);
|
||||
|
||||
nsCOMPtr<nsISHTransaction> mListRoot;
|
||||
int32_t mIndex;
|
||||
int32_t mLength;
|
||||
int32_t mRequestedIndex;
|
||||
|
||||
// Set to true if attached to a grouped session history.
|
||||
bool mIsPartial;
|
||||
|
||||
// The number of entries before this session history object.
|
||||
int32_t mGlobalIndexOffset;
|
||||
|
||||
// The number of entries after this session history object.
|
||||
int32_t mEntriesInFollowingPartialHistories;
|
||||
|
||||
// Session History listeners
|
||||
nsAutoTObserverArray<nsWeakPtr, 2> mListeners;
|
||||
|
||||
// Partial session history listener
|
||||
nsWeakPtr mPartialHistoryListener;
|
||||
|
||||
// Weak reference. Do not refcount this.
|
||||
nsIDocShell* mRootDocShell;
|
||||
|
||||
// Max viewers allowed total, across all SHistory objects
|
||||
static int32_t sHistoryMaxTotalViewers;
|
||||
};
|
||||
|
||||
class nsSHEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
explicit nsSHEnumerator(nsSHistory* aHistory);
|
||||
|
||||
protected:
|
||||
friend class nsSHistory;
|
||||
virtual ~nsSHEnumerator();
|
||||
|
||||
private:
|
||||
int32_t mIndex;
|
||||
nsSHistory* mSHistory;
|
||||
};
|
||||
|
||||
#endif /* nsSHistory */
|
||||
Loading…
Add table
Add a link
Reference in a new issue