diff options
Diffstat (limited to 'dom/base/PartialSHistory.cpp')
-rw-r--r-- | dom/base/PartialSHistory.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/dom/base/PartialSHistory.cpp b/dom/base/PartialSHistory.cpp new file mode 100644 index 000000000..2da5ca536 --- /dev/null +++ b/dom/base/PartialSHistory.cpp @@ -0,0 +1,294 @@ +/* -*- 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 "PartialSHistory.h" + +#include "nsIWebNavigation.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION(PartialSHistory, mOwnerFrameLoader) +NS_IMPL_CYCLE_COLLECTING_ADDREF(PartialSHistory) +NS_IMPL_CYCLE_COLLECTING_RELEASE(PartialSHistory) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PartialSHistory) + NS_INTERFACE_MAP_ENTRY(nsIPartialSHistory) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPartialSHistory) + NS_INTERFACE_MAP_ENTRY(nsISHistoryListener) + NS_INTERFACE_MAP_ENTRY(nsIPartialSHistoryListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) +NS_INTERFACE_MAP_END + +PartialSHistory::PartialSHistory(nsIFrameLoader* aOwnerFrameLoader) + : mCount(0), + mGlobalIndexOffset(0), + mOwnerFrameLoader(aOwnerFrameLoader) +{ + MOZ_ASSERT(aOwnerFrameLoader); +} + +already_AddRefed<nsISHistory> +PartialSHistory::GetSessionHistory() +{ + if (!mOwnerFrameLoader) { + // Cycle collected? + return nullptr; + } + + nsCOMPtr<nsIDocShell> docShell; + mOwnerFrameLoader->GetDocShell(getter_AddRefs(docShell)); + if (!docShell) { + return nullptr; + } + + nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell)); + nsCOMPtr<nsISHistory> shistory; + webNav->GetSessionHistory(getter_AddRefs(shistory)); + return shistory.forget(); +} + +already_AddRefed<TabParent> +PartialSHistory::GetTabParent() +{ + if (!mOwnerFrameLoader) { + // Cycle collected? + return nullptr; + } + + nsCOMPtr<nsITabParent> tabParent; + mOwnerFrameLoader->GetTabParent(getter_AddRefs(tabParent)); + return RefPtr<TabParent>(static_cast<TabParent*>(tabParent.get())).forget(); +} + +NS_IMETHODIMP +PartialSHistory::GetCount(uint32_t* aResult) +{ + if (!aResult) { + return NS_ERROR_INVALID_POINTER; + } + + // If we have direct reference to nsISHistory, simply pass through. + nsCOMPtr<nsISHistory> shistory(GetSessionHistory()); + if (shistory) { + int32_t count; + nsresult rv = shistory->GetCount(&count); + if (NS_FAILED(rv) || count < 0) { + *aResult = 0; + return NS_ERROR_FAILURE; + } + *aResult = count; + return NS_OK; + } + + // Otherwise use the cached value. + *aResult = mCount; + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::GetGlobalIndexOffset(uint32_t* aResult) +{ + if (!aResult) { + return NS_ERROR_INVALID_POINTER; + } + + // If we have direct reference to nsISHistory, simply pass through. + nsCOMPtr<nsISHistory> shistory(GetSessionHistory()); + if (shistory) { + int32_t offset; + nsresult rv = shistory->GetGlobalIndexOffset(&offset); + if (NS_FAILED(rv) || offset < 0) { + *aResult = 0; + return NS_ERROR_FAILURE; + } + *aResult = offset; + return NS_OK; + } + + // Otherwise use the cached value. + *aResult = mGlobalIndexOffset; + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::GetOwnerFrameLoader(nsIFrameLoader** aResult) +{ + nsCOMPtr<nsIFrameLoader> loader(mOwnerFrameLoader); + loader.forget(aResult); + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::OnAttachGroupedSessionHistory(uint32_t aOffset) +{ + mGlobalIndexOffset = aOffset; + + // If we have direct reference to nsISHistory, simply pass through. + nsCOMPtr<nsISHistory> shistory(GetSessionHistory()); + if (shistory) { + // nsISHistory uses int32_t + if (aOffset > INT32_MAX) { + return NS_ERROR_FAILURE; + } + return shistory->OnAttachGroupedSessionHistory(aOffset); + } + + // Otherwise notify through TabParent. + RefPtr<TabParent> tabParent(GetTabParent()); + if (!tabParent) { + // We have neither shistory nor tabParent? + NS_WARNING("Unable to get shitory nor tabParent!"); + return NS_ERROR_UNEXPECTED; + } + Unused << tabParent->SendNotifyAttachGroupedSessionHistory(aOffset); + + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::OnSessionHistoryChange(uint32_t aCount) +{ + mCount = aCount; + return OnLengthChange(aCount); +} + +NS_IMETHODIMP +PartialSHistory::OnActive(uint32_t aGlobalLength, uint32_t aTargetLocalIndex) +{ + // In-process case. + nsCOMPtr<nsISHistory> shistory(GetSessionHistory()); + if (shistory) { + // nsISHistory uses int32_t + if (aGlobalLength > INT32_MAX || aTargetLocalIndex > INT32_MAX) { + return NS_ERROR_FAILURE; + } + return shistory->OnPartialSessionHistoryActive(aGlobalLength, + aTargetLocalIndex); + } + + // Cross-process case. + RefPtr<TabParent> tabParent(GetTabParent()); + if (!tabParent) { + // We have neither shistory nor tabParent? + NS_WARNING("Unable to get shitory nor tabParent!"); + return NS_ERROR_UNEXPECTED; + } + Unused << tabParent->SendNotifyPartialSessionHistoryActive(aGlobalLength, + aTargetLocalIndex); + + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::OnDeactive() +{ + // In-process case. + nsCOMPtr<nsISHistory> shistory(GetSessionHistory()); + if (shistory) { + if (NS_FAILED(shistory->OnPartialSessionHistoryDeactive())) { + return NS_ERROR_FAILURE; + } + return NS_OK; + } + + // Cross-process case. + RefPtr<TabParent> tabParent(GetTabParent()); + if (!tabParent) { + // We have neither shistory nor tabParent? + NS_WARNING("Unable to get shitory nor tabParent!"); + return NS_ERROR_UNEXPECTED; + } + Unused << tabParent->SendNotifyPartialSessionHistoryDeactive(); + return NS_OK; +} + +/******************************************************************************* + * nsIPartialSHistoryListener + ******************************************************************************/ + +NS_IMETHODIMP +PartialSHistory::OnRequestCrossBrowserNavigation(uint32_t aIndex) +{ + if (!mOwnerFrameLoader) { + // Cycle collected? + return NS_ERROR_UNEXPECTED; + } + return mOwnerFrameLoader->RequestGroupedHistoryNavigation(aIndex); +} + +/******************************************************************************* + * nsISHistoryListener + ******************************************************************************/ + +NS_IMETHODIMP +PartialSHistory::OnLengthChange(int32_t aCount) +{ + if (!mOwnerFrameLoader) { + // Cycle collected? + return NS_ERROR_UNEXPECTED; + } + + if (aCount < 0) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIGroupedSHistory> groupedHistory; + mOwnerFrameLoader->GetGroupedSessionHistory(getter_AddRefs(groupedHistory)); + if (!groupedHistory) { + // Maybe we're not the active partial history, but in this case we shouldn't + // receive any update from session history object either. + return NS_ERROR_FAILURE; + } + + groupedHistory->OnPartialSessionHistoryChange(this); + return NS_OK; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryNewEntry(nsIURI *aNewURI, int32_t aOldIndex) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryGoBack(nsIURI *aBackURI, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryGoForward(nsIURI *aForwardURI, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryReload(nsIURI *aReloadURI, uint32_t aReloadFlags, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryGotoIndex(int32_t aIndex, nsIURI *aGotoURI, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryPurge(int32_t aNumEntries, bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +PartialSHistory::OnHistoryReplaceEntry(int32_t aIndex) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +} // namespace dom +} // namespace mozilla |