Bug 1434768 - Part 2: Replace nsDocShell::mSessionHistory with ChildSHistory, r=bz

This commit is contained in:
Nika Layzell
2018-02-01 17:35:47 -05:00
parent e2506d9c49
commit 6654f0e396
14 changed files with 216 additions and 297 deletions

View File

@@ -53,6 +53,7 @@
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/ChildSHistory.h"
#include "mozilla/net/ReferrerPolicy.h"
@@ -423,9 +424,8 @@ nsDocShell::~nsDocShell()
Destroy();
nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory));
if (shPrivate) {
shPrivate->SetRootDocShell(nullptr);
if (mSessionHistory) {
mSessionHistory->LegacySHistoryInternal()->SetRootDocShell(nullptr);
}
if (--gDocShellCount == 0) {
@@ -506,7 +506,8 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDocShell,
nsDocLoader,
mSessionStorageManager,
mScriptGlobal,
mInitialClientSource)
mInitialClientSource,
mSessionHistory)
NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)
NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader)
@@ -606,10 +607,11 @@ nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
return NS_SUCCEEDED(GetAuthPrompt(PROMPT_NORMAL, aIID, aSink)) ?
NS_OK : NS_NOINTERFACE;
} else if (aIID.Equals(NS_GET_IID(nsISHistory))) {
nsCOMPtr<nsISHistory> shistory;
nsresult rv = GetSessionHistory(getter_AddRefs(shistory));
if (NS_SUCCEEDED(rv) && shistory) {
shistory.forget(aSink);
RefPtr<ChildSHistory> shistory = GetSessionHistory();
if (shistory) {
// XXX(nika): Stop exposing nsISHistory through GetInterface.
nsCOMPtr<nsISHistory> legacy = shistory->LegacySHistory();
legacy.forget(aSink);
return NS_OK;
}
return NS_NOINTERFACE;
@@ -1164,14 +1166,11 @@ nsDocShell::FirePageHideNotificationInternal(bool aIsUnload,
// If the document is unloading, remove all dynamic subframe entries.
if (aIsUnload && !aSkipCheckingDynEntries) {
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsISHistoryInternal> shPrivate = do_QueryInterface(rootSH);
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
nsCOMPtr<nsISHContainer> container(do_QueryInterface(mOSHE));
if (shPrivate && container) {
int32_t index = -1;
rootSH->GetIndex(&index);
shPrivate->RemoveDynEntries(index, container);
if (rootSH && container) {
int32_t index = rootSH->Index();
rootSH->LegacySHistoryInternal()->RemoveDynEntries(index, container);
}
}
@@ -3992,15 +3991,14 @@ nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef,
* and replace the subframe where a new url was loaded with
* a new entry.
*/
int32_t index = -1;
nsCOMPtr<nsISHEntry> currentHE;
mSessionHistory->GetIndex(&index);
int32_t index = mSessionHistory->Index();
if (index < 0) {
return NS_ERROR_FAILURE;
}
rv = mSessionHistory->GetEntryAtIndex(index, false,
getter_AddRefs(currentHE));
rv = mSessionHistory->LegacySHistory()->GetEntryAtIndex(
index, false, getter_AddRefs(currentHE));
NS_ENSURE_TRUE(currentHE, NS_ERROR_FAILURE);
nsCOMPtr<nsISHEntry> currentEntry(do_QueryInterface(currentHE));
@@ -4012,10 +4010,7 @@ nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef,
aNewEntry, aCloneChildren, getter_AddRefs(nextEntry));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
rv = shPrivate->AddEntry(nextEntry, true);
rv = mSessionHistory->LegacySHistoryInternal()->AddEntry(nextEntry, true);
}
}
} else {
@@ -4043,10 +4038,9 @@ nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
// In this case, we will end up calling AddEntry, which increases the
// current index by 1
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (rootSH) {
rootSH->GetIndex(&mPreviousTransIndex);
mPreviousTransIndex = rootSH->Index();
}
nsresult rv;
@@ -4057,7 +4051,7 @@ nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
}
if (rootSH) {
rootSH->GetIndex(&mLoadedTransIndex);
mLoadedTransIndex = rootSH->Index();
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n", mPreviousTransIndex,
mLoadedTransIndex);
@@ -4103,25 +4097,19 @@ nsDocShell::GetUseGlobalHistory(bool* aUseGlobalHistory)
NS_IMETHODIMP
nsDocShell::RemoveFromSessionHistory()
{
nsCOMPtr<nsISHistoryInternal> internalHistory;
nsCOMPtr<nsISHistory> sessionHistory;
nsCOMPtr<nsIDocShellTreeItem> root;
GetSameTypeRootTreeItem(getter_AddRefs(root));
if (root) {
nsCOMPtr<nsIWebNavigation> rootAsWebnav = do_QueryInterface(root);
if (rootAsWebnav) {
rootAsWebnav->GetSessionHistory(getter_AddRefs(sessionHistory));
internalHistory = do_QueryInterface(sessionHistory);
}
}
if (!internalHistory) {
if (!rootAsWebnav) {
return NS_OK;
}
int32_t index = 0;
sessionHistory->GetIndex(&index);
RefPtr<ChildSHistory> sessionHistory = rootAsWebnav->GetSessionHistory();
if (!sessionHistory) {
return NS_OK;
}
int32_t index = sessionHistory->Index();
AutoTArray<nsID, 16> ids({mHistoryID});
internalHistory->RemoveEntries(ids, index);
sessionHistory->LegacySHistoryInternal()->RemoveEntries(ids, index);
return NS_OK;
}
@@ -4202,10 +4190,8 @@ void
nsDocShell::ClearFrameHistory(nsISHEntry* aEntry)
{
nsCOMPtr<nsISHContainer> shcontainer = do_QueryInterface(aEntry);
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsISHistoryInternal> history = do_QueryInterface(rootSH);
if (!history || !shcontainer) {
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (!rootSH || !shcontainer) {
return;
}
@@ -4219,9 +4205,8 @@ nsDocShell::ClearFrameHistory(nsISHEntry* aEntry)
ids.AppendElement(child->DocshellID());
}
}
int32_t index = 0;
rootSH->GetIndex(&index);
history->RemoveEntries(ids, index);
int32_t index = rootSH->Index();
rootSH->LegacySHistoryInternal()->RemoveEntries(ids, index);
}
//-------------------------------------
@@ -4261,33 +4246,31 @@ nsDocShell::IsNavigationAllowed(bool aDisplayPrintErrorDialog,
NS_IMETHODIMP
nsDocShell::GetCanGoBack(bool* aCanGoBack)
{
if (!IsNavigationAllowed(false)) {
*aCanGoBack = false;
if (!IsNavigationAllowed(false)) {
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(rootSH));
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
rv = webnav->GetCanGoBack(aCanGoBack);
return rv;
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (rootSH) {
*aCanGoBack = rootSH->CanGo(-1);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDocShell::GetCanGoForward(bool* aCanGoForward)
{
if (!IsNavigationAllowed(false)) {
*aCanGoForward = false;
if (!IsNavigationAllowed(false)) {
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(rootSH));
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
rv = webnav->GetCanGoForward(aCanGoForward);
return rv;
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (rootSH) {
*aCanGoForward = rootSH->CanGo(1);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@@ -4296,13 +4279,11 @@ nsDocShell::GoBack()
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(rootSH));
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
rv = webnav->GoBack();
return rv;
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE);
ErrorResult rv;
rootSH->Go(-1, rv);
return rv.StealNSResult();
}
NS_IMETHODIMP
@@ -4311,28 +4292,24 @@ nsDocShell::GoForward()
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(rootSH));
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
rv = webnav->GoForward();
return rv;
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE);
ErrorResult rv;
rootSH->Go(1, rv);
return rv.StealNSResult();
}
// XXX(nika): We may want to stop exposing this API in the child process? Going
// to a specific index from multiple different processes could definitely race.
NS_IMETHODIMP
nsDocShell::GotoIndex(int32_t aIndex)
{
if (!IsNavigationAllowed()) {
return NS_OK; // JS may not handle returning of an error code
}
nsresult rv;
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(rootSH));
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
rv = webnav->GotoIndex(aIndex);
return rv;
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
NS_ENSURE_TRUE(rootSH, NS_ERROR_FAILURE);
return rootSH->LegacySHistoryWebNav()->GotoIndex(aIndex);
}
NS_IMETHODIMP
@@ -5056,12 +5033,11 @@ nsDocShell::Reload(uint32_t aReloadFlags)
// Send notifications to the HistoryListener if any, about the impending
// reload
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsISHistoryInternal> shistInt(do_QueryInterface(rootSH));
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
bool canReload = true;
if (rootSH) {
shistInt->NotifyOnHistoryReload(mCurrentURI, aReloadFlags, &canReload);
rootSH->LegacySHistoryInternal()
->NotifyOnHistoryReload(mCurrentURI, aReloadFlags, &canReload);
}
if (!canReload) {
@@ -5242,38 +5218,28 @@ nsDocShell::GetReferringURI(nsIURI** aURI)
}
NS_IMETHODIMP
nsDocShell::SetSessionHistory(nsISHistory* aSessionHistory)
nsDocShell::InitSessionHistory()
{
NS_ENSURE_TRUE(aSessionHistory, NS_ERROR_FAILURE);
// make sure that we are the root docshell and
// set a handle to root docshell in SH.
MOZ_ASSERT(!mIsBeingDestroyed);
// Make sure that we are the root DocShell, and set a handle to root docshell
// in the session history.
nsCOMPtr<nsIDocShellTreeItem> root;
/* Get the root docshell. If *this* is the root docshell
* then save a handle to *this* in SH. SH needs it to do
* traversions thro' its entries
*/
GetSameTypeRootTreeItem(getter_AddRefs(root));
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
if (root.get() == static_cast<nsIDocShellTreeItem*>(this)) {
mSessionHistory = aSessionHistory;
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
shPrivate->SetRootDocShell(this);
return NS_OK;
}
if (root != this) {
return NS_ERROR_FAILURE;
}
mSessionHistory = new ChildSHistory(this);
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionHistory(nsISHistory** aSessionHistory)
nsDocShell::GetSessionHistoryXPCOM(nsISupports** aSessionHistory)
{
NS_ENSURE_ARG_POINTER(aSessionHistory);
*aSessionHistory = mSessionHistory;
NS_IF_ADDREF(*aSessionHistory);
RefPtr<ChildSHistory> shistory = mSessionHistory;
shistory.forget(aSessionHistory);
return NS_OK;
}
@@ -5529,11 +5495,7 @@ nsDocShell::Destroy()
// We want to destroy these content viewers now rather than
// letting their destruction wait for the session history
// entries to get garbage collected. (Bug 488394)
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
if (shPrivate) {
shPrivate->EvictAllContentViewers();
}
mSessionHistory->LegacySHistoryInternal()->EvictAllContentViewers();
mSessionHistory = nullptr;
}
@@ -8309,13 +8271,11 @@ nsDocShell::RestoreFromHistory()
mFiredUnloadEvent = false;
mURIResultedInDocument = true;
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (rootSH) {
nsCOMPtr<nsISHistoryInternal> hist = do_QueryInterface(rootSH);
rootSH->GetIndex(&mPreviousTransIndex);
hist->UpdateIndex();
rootSH->GetIndex(&mLoadedTransIndex);
mPreviousTransIndex = rootSH->Index();
rootSH->LegacySHistoryInternal()->UpdateIndex();
mLoadedTransIndex = rootSH->Index();
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n", mPreviousTransIndex,
mLoadedTransIndex);
@@ -8840,11 +8800,12 @@ nsDocShell::CreateContentViewer(const nsACString& aContentType,
// EndPageLoad. See bug 302115.
if (mSessionHistory && !mLSHE) {
int32_t idx;
mSessionHistory->GetRequestedIndex(&idx);
mSessionHistory->LegacySHistory()->GetRequestedIndex(&idx);
if (idx == -1) {
mSessionHistory->GetIndex(&idx);
idx = mSessionHistory->Index();
}
mSessionHistory->GetEntryAtIndex(idx, false, getter_AddRefs(mLSHE));
mSessionHistory->LegacySHistory()->
GetEntryAtIndex(idx, false, getter_AddRefs(mLSHE));
}
mLoadType = LOAD_ERROR_PAGE;
@@ -10109,10 +10070,10 @@ nsDocShell::InternalLoad(nsIURI* aURI,
* SH menus in go/back/forward buttons won't be empty for this.
*/
if (mSessionHistory) {
int32_t index = -1;
mSessionHistory->GetIndex(&index);
int32_t index = mSessionHistory->Index();
nsCOMPtr<nsISHEntry> shEntry;
mSessionHistory->GetEntryAtIndex(index, false, getter_AddRefs(shEntry));
mSessionHistory->LegacySHistory()->GetEntryAtIndex(
index, false, getter_AddRefs(shEntry));
NS_ENSURE_TRUE(shEntry, NS_ERROR_FAILURE);
shEntry->SetTitle(mTitle);
}
@@ -11478,15 +11439,15 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
// Create SH Entry (mLSHE) only if there is a SessionHistory object in the
// current frame or in the root docshell.
nsCOMPtr<nsISHistory> rootSH = mSessionHistory;
RefPtr<ChildSHistory> rootSH = mSessionHistory;
if (!rootSH) {
// Get the handle to SH from the root docshell
GetRootSessionHistory(getter_AddRefs(rootSH));
rootSH = GetRootSessionHistory();
}
if (!rootSH) {
updateSHistory = false;
updateGHistory = false; // XXX Why global history too?
}
}
// Check if the url to be loaded is the same as the one already loaded.
if (mCurrentURI) {
@@ -11598,16 +11559,15 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
// Even if we don't add anything to SHistory, ensure the current index
// points to the same SHEntry as our mLSHE.
int32_t index = 0;
mSessionHistory->GetRequestedIndex(&index);
mSessionHistory->LegacySHistory()->GetRequestedIndex(&index);
if (index == -1) {
mSessionHistory->GetIndex(&index);
index = mSessionHistory->Index();
}
nsCOMPtr<nsISHEntry> currentSH;
mSessionHistory->GetEntryAtIndex(index, false, getter_AddRefs(currentSH));
mSessionHistory->LegacySHistory()->GetEntryAtIndex(
index, false, getter_AddRefs(currentSH));
if (currentSH != mLSHE) {
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
shPrivate->ReplaceEntry(index, mLSHE);
mSessionHistory->LegacySHistoryInternal()->ReplaceEntry(index, mLSHE);
}
}
@@ -11639,17 +11599,14 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
if (rootSH &&
((mLoadType & (LOAD_CMD_HISTORY | LOAD_CMD_RELOAD)) ||
mLoadType == LOAD_NORMAL_REPLACE)) {
nsCOMPtr<nsISHistoryInternal> shInternal(do_QueryInterface(rootSH));
if (shInternal) {
rootSH->GetIndex(&mPreviousTransIndex);
shInternal->UpdateIndex();
rootSH->GetIndex(&mLoadedTransIndex);
mPreviousTransIndex = rootSH->Index();
rootSH->LegacySHistoryInternal()->UpdateIndex();
mLoadedTransIndex = rootSH->Index();
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n",
mPreviousTransIndex, mLoadedTransIndex);
#endif
}
}
// aCloneSHChildren exactly means "we are not loading a new document".
uint32_t locationFlags =
@@ -11949,26 +11906,19 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
// the history so it can evict content viewers if appropriate. Otherwise
// call ReplaceEntry so that we notify nsIHistoryListeners that an entry
// was replaced.
nsCOMPtr<nsISHistory> rootSH;
GetRootSessionHistory(getter_AddRefs(rootSH));
NS_ENSURE_TRUE(rootSH, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsISHistoryInternal> internalSH = do_QueryInterface(rootSH);
NS_ENSURE_TRUE(internalSH, NS_ERROR_UNEXPECTED);
RefPtr<ChildSHistory> rootSH = GetRootSessionHistory();
if (!aReplace) {
int32_t curIndex = -1;
rv = rootSH->GetIndex(&curIndex);
if (NS_SUCCEEDED(rv) && curIndex > -1) {
internalSH->EvictOutOfRangeContentViewers(curIndex);
int32_t curIndex = rootSH->Index();
if (curIndex > -1) {
rootSH->LegacySHistoryInternal()->EvictOutOfRangeContentViewers(curIndex);
}
} else {
nsCOMPtr<nsISHEntry> rootSHEntry = nsSHistory::GetRootSHEntry(newSHEntry);
int32_t index = -1;
rv = rootSH->GetIndexOfEntry(rootSHEntry, &index);
rv = rootSH->LegacySHistory()->GetIndexOfEntry(rootSHEntry, &index);
if (NS_SUCCEEDED(rv) && index > -1) {
internalSH->ReplaceEntry(index, rootSHEntry);
rootSH->LegacySHistoryInternal()->ReplaceEntry(index, rootSHEntry);
}
}
@@ -12276,17 +12226,15 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
// valid, it indicates the loading was triggered by a history load, and
// we should replace the entry at requested index instead.
int32_t index = 0;
mSessionHistory->GetRequestedIndex(&index);
mSessionHistory->LegacySHistory()->GetRequestedIndex(&index);
if (index == -1) {
mSessionHistory->GetIndex(&index);
index = mSessionHistory->Index();
}
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
// Replace the current entry with the new entry
if (index >= 0) {
if (shPrivate) {
rv = shPrivate->ReplaceEntry(index, entry);
}
rv = mSessionHistory->LegacySHistoryInternal()->ReplaceEntry(index,
entry);
} else {
// If we're trying to replace an inexistant shistory entry, append.
addToSHistory = true;
@@ -12295,14 +12243,12 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
if (addToSHistory) {
// Add to session history
nsCOMPtr<nsISHistoryInternal> shPrivate =
do_QueryInterface(mSessionHistory);
NS_ENSURE_TRUE(shPrivate, NS_ERROR_FAILURE);
mSessionHistory->GetIndex(&mPreviousTransIndex);
mPreviousTransIndex = mSessionHistory->Index();
bool shouldPersist = ShouldAddToSessionHistory(aURI, aChannel);
rv = shPrivate->AddEntry(entry, shouldPersist);
mSessionHistory->GetIndex(&mLoadedTransIndex);
rv = mSessionHistory->LegacySHistoryInternal()->AddEntry(
entry, shouldPersist);
mLoadedTransIndex = mSessionHistory->Index();
#ifdef DEBUG_PAGE_CACHE
printf("Previous index: %d, Loaded index: %d\n\n",
mPreviousTransIndex, mLoadedTransIndex);
@@ -12559,21 +12505,19 @@ nsDocShell::SetHistoryEntry(nsCOMPtr<nsISHEntry>* aPtr, nsISHEntry* aEntry)
*aPtr = aEntry;
}
nsresult
nsDocShell::GetRootSessionHistory(nsISHistory** aReturn)
already_AddRefed<ChildSHistory>
nsDocShell::GetRootSessionHistory()
{
nsresult rv;
nsCOMPtr<nsIDocShellTreeItem> root;
// Get the root docshell
rv = GetSameTypeRootTreeItem(getter_AddRefs(root));
// QI to nsIWebNavigation
nsCOMPtr<nsIWebNavigation> rootAsWebnav(do_QueryInterface(root));
if (rootAsWebnav) {
// Get the handle to SH from the root docshell
rv = rootAsWebnav->GetSessionHistory(aReturn);
nsresult rv = GetSameTypeRootTreeItem(getter_AddRefs(root));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return rv;
nsCOMPtr<nsIWebNavigation> webnav = do_QueryInterface(root);
if (!webnav) {
return nullptr;
}
return webnav->GetSessionHistory();
}
nsresult

View File

@@ -17,6 +17,7 @@
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/dom/ChildSHistory.h"
#include "nsIAuthPromptProvider.h"
#include "nsIBaseWindow.h"
@@ -874,7 +875,6 @@ private: // member functions
nsresult PersistLayoutHistoryState();
nsresult LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType);
nsresult SetBaseUrlForWyciwyg(nsIContentViewer* aContentViewer);
nsresult GetRootSessionHistory(nsISHistory** aReturn);
nsresult GetHttpChannel(nsIChannel* aChannel, nsIHttpChannel** aReturn);
nsresult ConfirmRepost(bool* aRepost);
nsresult GetPromptAndStringBundle(nsIPrompt** aPrompt,
@@ -883,6 +883,8 @@ private: // member functions
nsresult SetCurScrollPosEx(int32_t aCurHorizontalPos,
int32_t aCurVerticalPos);
already_AddRefed<mozilla::dom::ChildSHistory> GetRootSessionHistory();
inline bool UseErrorPages()
{
return (mObserveErrorPages ? sUseErrorPages : mUseErrorPages);
@@ -922,7 +924,7 @@ private: // data members
nsCOMPtr<nsIDOMStorageManager> mSessionStorageManager;
nsCOMPtr<nsIContentViewer> mContentViewer;
nsCOMPtr<nsIWidget> mParentWidget;
nsCOMPtr<nsISHistory> mSessionHistory;
RefPtr<mozilla::dom::ChildSHistory> mSessionHistory;
nsCOMPtr<nsIGlobalHistory2> mGlobalHistory;
nsCOMPtr<nsIWebBrowserFind> mFind;
nsCOMPtr<nsICommandManager> mCommandManager;

View File

@@ -1189,6 +1189,12 @@ interface nsIDocShell : nsIDocShellTreeItem
void getColorMatrix([optional] out unsigned long aMatrixLen,
[array, size_is(aMatrixLen), retval] out float aMatrix);
/**
* Initialize session history for this docshell. The docshell must be the root
* docshell.
*/
void initSessionHistory();
%{C++
/**
* These methods call nsDocShell::GetHTMLEditorInternal() and

View File

@@ -10,6 +10,11 @@ interface nsIInputStream;
interface nsISHistory;
interface nsIURI;
interface nsIPrincipal;
interface nsIChildSHistory;
%{ C++
#include "mozilla/dom/ChildSHistory.h"
%}
/**
* The nsIWebNavigation interface defines an interface for navigating the web.
@@ -374,9 +379,28 @@ interface nsIWebNavigation : nsISupports
readonly attribute nsIURI referringURI;
/**
* The session history object used by this web navigation instance.
* The session history object used by this web navigation instance. This
* object will be a mozilla::dom::ChildSHistory object, but is returned as
* nsISupports so it can be called from JS code.
*/
attribute nsISHistory sessionHistory;
[binaryname(SessionHistoryXPCOM)]
readonly attribute nsISupports sessionHistory;
%{ C++
/**
* Get the session history object used by this nsIWebNavigation instance.
* Use this method instead of the XPCOM method when getting the
* SessionHistory from C++ code.
*/
already_AddRefed<mozilla::dom::ChildSHistory>
GetSessionHistory()
{
nsCOMPtr<nsISupports> history;
GetSessionHistoryXPCOM(getter_AddRefs(history));
return history.forget()
.downcast<mozilla::dom::ChildSHistory>();
}
%}
/**
* Set an OriginAttributes dictionary in the docShell. This can be done only

View File

@@ -39,12 +39,11 @@ ParentSHistory::GetTabParent()
already_AddRefed<ChildSHistory>
ParentSHistory::GetChildIfSameProcess()
{
if (XRE_IsContentProcess()) {
MOZ_ASSERT(!mDocShell);
return nullptr;
if (GetDocShell()) {
return GetDocShell()->GetSessionHistory();
}
MOZ_CRASH("Unimplemented!");
return nullptr;
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ParentSHistory)

View File

@@ -1789,15 +1789,9 @@ nsSHistory::GetReferringURI(nsIURI** aURI)
}
NS_IMETHODIMP
nsSHistory::SetSessionHistory(nsISHistory* aSessionHistory)
{
// Not implemented
return NS_OK;
}
NS_IMETHODIMP
nsSHistory::GetSessionHistory(nsISHistory** aSessionHistory)
nsSHistory::GetSessionHistoryXPCOM(nsISupports** aSessionHistory)
{
*aSessionHistory = nullptr;
// Not implemented
return NS_OK;
}

View File

@@ -255,14 +255,13 @@ MarkDocShell(nsIDocShellTreeItem* aNode, bool aCleanupJS)
MarkContentViewer(cview, aCleanupJS);
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(shell);
nsCOMPtr<nsISHistory> history;
webNav->GetSessionHistory(getter_AddRefs(history));
RefPtr<ChildSHistory> history = webNav->GetSessionHistory();
if (history) {
int32_t i, historyCount;
history->GetCount(&historyCount);
for (i = 0; i < historyCount; ++i) {
int32_t historyCount = history->Count();
for (int32_t i = 0; i < historyCount; ++i) {
nsCOMPtr<nsISHEntry> shEntry;
history->GetEntryAtIndex(i, false, getter_AddRefs(shEntry));
history->LegacySHistory()->GetEntryAtIndex(
i, false, getter_AddRefs(shEntry));
MarkSHEntry(shEntry, aCleanupJS);
}

View File

@@ -98,6 +98,8 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/GroupedHistoryEvent.h"
#include "mozilla/dom/ParentSHistory.h"
#include "mozilla/dom/ChildSHistory.h"
#include "mozilla/dom/HTMLBodyElement.h"
@@ -1376,10 +1378,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsCOMPtr<nsISHistory> ourHistory;
nsCOMPtr<nsISHistory> otherHistory;
ourRootWebnav->GetSessionHistory(getter_AddRefs(ourHistory));
otherRootWebnav->GetSessionHistory(getter_AddRefs(otherHistory));
RefPtr<ChildSHistory> ourHistory = ourRootWebnav->GetSessionHistory();
RefPtr<ChildSHistory> otherHistory = otherRootWebnav->GetSessionHistory();
if ((ourRootTreeItem != ourDocshell || otherRootTreeItem != otherDocshell) &&
(ourHistory || otherHistory)) {
@@ -1609,15 +1609,11 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
aOtherOwner->InternalSetFrameLoader(kungFuDeathGrip);
// Drop any cached content viewers in the two session histories.
nsCOMPtr<nsISHistoryInternal> ourInternalHistory =
do_QueryInterface(ourHistory);
nsCOMPtr<nsISHistoryInternal> otherInternalHistory =
do_QueryInterface(otherHistory);
if (ourInternalHistory) {
ourInternalHistory->EvictAllContentViewers();
if (ourHistory) {
ourHistory->LegacySHistoryInternal()->EvictAllContentViewers();
}
if (otherInternalHistory) {
otherInternalHistory->EvictAllContentViewers();
if (otherHistory) {
otherHistory->LegacySHistoryInternal()->EvictAllContentViewers();
}
NS_ASSERTION(ourFrame == ourContent->GetPrimaryFrame() &&
@@ -2110,13 +2106,9 @@ nsFrameLoader::MaybeCreateDocShell()
if (mIsTopLevelContent &&
mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory)) {
nsresult rv;
nsCOMPtr<nsISHistory> sessionHistory =
do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
// XXX(nika): Set this up more explicitly?
nsresult rv = mDocShell->InitSessionHistory();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
webNav->SetSessionHistory(sessionHistory);
}
OriginAttributes attrs;

View File

@@ -69,22 +69,14 @@ nsHistory::GetLength(ErrorResult& aRv) const
}
// Get session History from docshell
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
RefPtr<ChildSHistory> sHistory = GetSessionHistory();
if (!sHistory) {
aRv.Throw(NS_ERROR_FAILURE);
return 0;
}
int32_t len;
nsresult rv = sHistory->GetCount(&len);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
}
int32_t len = sHistory->Count();;
return len >= 0 ? len : 0;
}
@@ -198,26 +190,16 @@ nsHistory::Go(int32_t aDelta, ErrorResult& aRv)
}
}
nsCOMPtr<nsISHistory> session_history = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(session_history));
if (!webnav) {
RefPtr<ChildSHistory> session_history = GetSessionHistory();
if (!session_history) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
int32_t curIndex = -1;
int32_t len = 0;
session_history->GetIndex(&curIndex);
session_history->GetCount(&len);
int32_t index = curIndex + aDelta;
if (index > -1 && index < len)
webnav->GotoIndex(index);
// Ignore the return value from GotoIndex(), since returning errors
// from GotoIndex() can lead to exceptions and a possible leak
// of history length
// Ignore the return value from Go(), since returning errors from Go() can
// lead to exceptions and a possible leak of history length
session_history->Go(aDelta, IgnoreErrors());
}
void
@@ -230,15 +212,14 @@ nsHistory::Back(ErrorResult& aRv)
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
RefPtr<ChildSHistory> sHistory = GetSessionHistory();
if (!sHistory) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
webNav->GoBack();
sHistory->Go(-1, IgnoreErrors());
}
void
@@ -251,15 +232,14 @@ nsHistory::Forward(ErrorResult& aRv)
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
RefPtr<ChildSHistory> sHistory = GetSessionHistory();
if (!sHistory) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
webNav->GoForward();
sHistory->Go(1, IgnoreErrors());
}
void
@@ -322,7 +302,7 @@ nsHistory::GetDocShell() const
return win->GetDocShell();
}
already_AddRefed<nsISHistory>
already_AddRefed<ChildSHistory>
nsHistory::GetSessionHistory() const
{
nsIDocShell *docShell = GetDocShell();
@@ -334,10 +314,6 @@ nsHistory::GetSessionHistory() const
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(root));
NS_ENSURE_TRUE(webNav, nullptr);
nsCOMPtr<nsISHistory> shistory;
// Get SH from nsIWebNavigation
webNav->GetSessionHistory(getter_AddRefs(shistory));
return shistory.forget();
return webNav->GetSessionHistory();
}

View File

@@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/HistoryBinding.h"
#include "mozilla/dom/ChildSHistory.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsPIDOMWindow.h" // for GetParentObject
@@ -59,7 +60,7 @@ protected:
const nsAString& aTitle, const nsAString& aUrl,
mozilla::ErrorResult& aRv, bool aReplace);
already_AddRefed<nsISHistory> GetSessionHistory() const;
already_AddRefed<mozilla::dom::ChildSHistory> GetSessionHistory() const;
nsCOMPtr<nsIWeakReference> mInnerWindow;
};

View File

@@ -139,8 +139,8 @@ BrowserElementChild.prototype = {
let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
if (!webNavigation.sessionHistory) {
webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
.createInstance(Ci.nsISHistory);
// XXX(nika): We might need to start this up some other way?
docShell.initSessionHistory();
}
// This is necessary to get security web progress notifications.

View File

@@ -2113,10 +2113,8 @@ nsDocumentViewer::Show(void)
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) {
RefPtr<ChildSHistory> history = webNav->GetSessionHistory();
if (history) {
int32_t prevIndex,loadedIndex;
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
docShell->GetPreviousTransIndex(&prevIndex);
@@ -2125,7 +2123,8 @@ nsDocumentViewer::Show(void)
printf("About to evict content viewers: prev=%d, loaded=%d\n",
prevIndex, loadedIndex);
#endif
historyInt->EvictOutOfRangeContentViewers(loadedIndex);
history->LegacySHistoryInternal()->
EvictOutOfRangeContentViewers(loadedIndex);
}
}
}

View File

@@ -731,30 +731,18 @@ nsWebBrowser::GetReferringURI(nsIURI** aURI)
return mDocShellAsNav->GetReferringURI(aURI);
}
// XXX(nika): Consider making the mozilla::dom::ChildSHistory version the
// canonical one?
NS_IMETHODIMP
nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory)
{
if (mDocShell) {
return mDocShellAsNav->SetSessionHistory(aSessionHistory);
} else {
mInitInfo->sessionHistory = aSessionHistory;
}
return NS_OK;
}
NS_IMETHODIMP
nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory)
nsWebBrowser::GetSessionHistoryXPCOM(nsISupports** aSessionHistory)
{
NS_ENSURE_ARG_POINTER(aSessionHistory);
*aSessionHistory = nullptr;
if (mDocShell) {
return mDocShellAsNav->GetSessionHistory(aSessionHistory);
} else {
*aSessionHistory = mInitInfo->sessionHistory;
RefPtr<mozilla::dom::ChildSHistory> shistory =
mDocShellAsNav->GetSessionHistory();
shistory.forget(aSessionHistory);
}
NS_IF_ADDREF(*aSessionHistory);
return NS_OK;
}
@@ -1263,11 +1251,7 @@ nsWebBrowser::Create()
// handler that always gets called (even for subframes) for any bubbling
// event.
if (!mInitInfo->sessionHistory) {
mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
mDocShell->InitSessionHistory();
if (XRE_IsParentProcess()) {
// Hook up global history. Do not fail if we can't - just warn.

View File

@@ -50,7 +50,6 @@ public:
int32_t cx;
int32_t cy;
bool visible;
nsCOMPtr<nsISHistory> sessionHistory;
nsString name;
};