tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NavigationHistoryEntry.cpp (5721B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/dom/NavigationHistoryEntry.h"
      8 
      9 #include "mozilla/dom/Document.h"
     10 #include "mozilla/dom/NavigationHistoryEntryBinding.h"
     11 #include "mozilla/dom/SessionHistoryEntry.h"
     12 #include "nsDocShell.h"
     13 #include "nsGlobalWindowInner.h"
     14 
     15 extern mozilla::LazyLogModule gNavigationAPILog;
     16 
     17 namespace mozilla::dom {
     18 
     19 NS_IMPL_CYCLE_COLLECTION_INHERITED(NavigationHistoryEntry,
     20                                   DOMEventTargetHelper);
     21 NS_IMPL_ADDREF_INHERITED(NavigationHistoryEntry, DOMEventTargetHelper)
     22 NS_IMPL_RELEASE_INHERITED(NavigationHistoryEntry, DOMEventTargetHelper)
     23 
     24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(NavigationHistoryEntry)
     25 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
     26 
     27 NavigationHistoryEntry::NavigationHistoryEntry(
     28    nsIGlobalObject* aGlobal, const class SessionHistoryInfo* aSHInfo,
     29    int64_t aIndex)
     30    : DOMEventTargetHelper(aGlobal),
     31      mSHInfo(MakeUnique<class SessionHistoryInfo>(*aSHInfo)),
     32      mIndex(aIndex) {}
     33 
     34 NavigationHistoryEntry::~NavigationHistoryEntry() = default;
     35 
     36 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-url
     37 void NavigationHistoryEntry::GetUrl(nsAString& aResult) const {
     38  if (!HasActiveDocument()) {
     39    return;
     40  }
     41 
     42  // HasActiveDocument implies that GetAssociatedDocument returns non-null.
     43  MOZ_DIAGNOSTIC_ASSERT(GetAssociatedDocument());
     44 
     45  if (!SameDocument()) {
     46    const auto referrerPolicy =
     47        GetAssociatedDocument()->ReferrerPolicyUsedToFetchThisDocument();
     48    if (referrerPolicy == ReferrerPolicy::No_referrer ||
     49        referrerPolicy == ReferrerPolicy::Origin) {
     50      aResult.SetIsVoid(true);
     51      return;
     52    }
     53  }
     54 
     55  MOZ_ASSERT(mSHInfo);
     56  nsCOMPtr<nsIURI> uri = mSHInfo->GetURI();
     57  MOZ_ASSERT(uri);
     58  nsCString uriSpec;
     59  uri->GetSpec(uriSpec);
     60  CopyUTF8toUTF16(uriSpec, aResult);
     61 }
     62 
     63 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-key
     64 void NavigationHistoryEntry::GetKey(nsAString& aResult) const {
     65  if (!HasActiveDocument()) {
     66    return;
     67  }
     68 
     69  nsIDToCString keyString(mSHInfo->NavigationKey());
     70  // Omit the curly braces and NUL.
     71  CopyUTF8toUTF16(Substring(keyString.get() + 1, NSID_LENGTH - 3), aResult);
     72 }
     73 
     74 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-id
     75 void NavigationHistoryEntry::GetId(nsAString& aResult) const {
     76  if (!HasActiveDocument()) {
     77    return;
     78  }
     79 
     80  nsIDToCString idString(mSHInfo->NavigationId());
     81  // Omit the curly braces and NUL.
     82  CopyUTF8toUTF16(Substring(idString.get() + 1, NSID_LENGTH - 3), aResult);
     83 }
     84 
     85 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-index
     86 int64_t NavigationHistoryEntry::Index() const {
     87  MOZ_ASSERT(mSHInfo);
     88  if (!HasActiveDocument()) {
     89    return -1;
     90  }
     91  return mIndex;
     92 }
     93 
     94 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-samedocument
     95 bool NavigationHistoryEntry::SameDocument() const {
     96  if (!HasActiveDocument()) {
     97    return false;
     98  }
     99 
    100  // HasActiveDocument implies that GetAssociatedDocument returns non-null.
    101  MOZ_DIAGNOSTIC_ASSERT(GetAssociatedDocument());
    102 
    103  MOZ_ASSERT(mSHInfo);
    104  auto* docShell = nsDocShell::Cast(GetAssociatedDocument()->GetDocShell());
    105  return docShell && docShell->IsSameDocumentAsActiveEntry(*mSHInfo);
    106 }
    107 
    108 // https://html.spec.whatwg.org/#dom-navigationhistoryentry-getstate
    109 void NavigationHistoryEntry::GetState(JSContext* aCx,
    110                                      JS::MutableHandle<JS::Value> aResult,
    111                                      ErrorResult& aRv) const {
    112  // Step 1
    113  aResult.setUndefined();
    114  if (!HasActiveDocument()) {
    115    return;
    116  }
    117 
    118  // Step 2
    119  RefPtr<nsIStructuredCloneContainer> state = mSHInfo->GetNavigationAPIState();
    120  if (!state) {
    121    return;
    122  }
    123  nsresult rv = state->DeserializeToJsval(aCx, aResult);
    124  if (NS_FAILED(rv)) {
    125    // nsStructuredCloneContainer::DeserializeToJsval suppresses exceptions, so
    126    // the best we can do is just re-throw the NS_ERROR_DOM_DATA_CLONE_ERR. When
    127    // nsStructuredCloneContainer::DeserializeToJsval throws better exceptions
    128    // this should too.
    129    // See also: NavigationDestination::GetState
    130    aRv.Throw(rv);
    131  }
    132 }
    133 
    134 void NavigationHistoryEntry::SetNavigationAPIState(
    135    nsIStructuredCloneContainer* aState) {
    136  mSHInfo->SetNavigationAPIState(aState);
    137 }
    138 
    139 bool NavigationHistoryEntry::IsSameEntry(
    140    const class SessionHistoryInfo* aSHInfo) const {
    141  return mSHInfo->NavigationId() == aSHInfo->NavigationId();
    142 }
    143 
    144 bool NavigationHistoryEntry::SharesDocumentWith(
    145    const class SessionHistoryInfo& aSHInfo) const {
    146  return mSHInfo->SharesDocumentWith(aSHInfo);
    147 }
    148 
    149 JSObject* NavigationHistoryEntry::WrapObject(
    150    JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
    151  return NavigationHistoryEntry_Binding::Wrap(aCx, this, aGivenProto);
    152 }
    153 
    154 Document* NavigationHistoryEntry::GetAssociatedDocument() const {
    155  nsGlobalWindowInner* window = GetOwnerWindow();
    156  return window ? window->GetDocument() : nullptr;
    157 }
    158 
    159 bool NavigationHistoryEntry::HasActiveDocument() const {
    160  if (auto* document = GetAssociatedDocument()) {
    161    return document->IsCurrentActiveDocument();
    162  }
    163 
    164  return false;
    165 }
    166 
    167 const nsID& NavigationHistoryEntry::Key() const {
    168  return mSHInfo->NavigationKey();
    169 }
    170 
    171 nsIStructuredCloneContainer* NavigationHistoryEntry::GetNavigationAPIState()
    172    const {
    173  if (!mSHInfo) {
    174    return nullptr;
    175  }
    176 
    177  return mSHInfo->GetNavigationAPIState();
    178 }
    179 
    180 void NavigationHistoryEntry::ResetIndexForDisposal() { mIndex = -1; }
    181 
    182 }  // namespace mozilla::dom