summaryrefslogtreecommitdiffstats
path: root/dom/base/PartialSHistory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/PartialSHistory.cpp')
-rw-r--r--dom/base/PartialSHistory.cpp294
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