LCOV - code coverage report
Current view: top level - dom/base - nsHistory.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 155 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 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 "nsHistory.h"
       8             : 
       9             : #include "jsapi.h"
      10             : #include "nsCOMPtr.h"
      11             : #include "nsPIDOMWindow.h"
      12             : #include "nsIDocument.h"
      13             : #include "nsIPresShell.h"
      14             : #include "nsPresContext.h"
      15             : #include "nsIDocShell.h"
      16             : #include "nsIWebNavigation.h"
      17             : #include "nsIURI.h"
      18             : #include "nsIInterfaceRequestorUtils.h"
      19             : #include "nsReadableUtils.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsISHistory.h"
      22             : #include "nsISHistoryInternal.h"
      23             : #include "mozilla/Preferences.h"
      24             : 
      25             : using namespace mozilla;
      26             : using namespace mozilla::dom;
      27             : 
      28             : //
      29             : //  History class implementation
      30             : //
      31           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsHistory)
      32           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHistory)
      33           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHistory)
      34           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHistory)
      35           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
      36           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      37           0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMHistory) // Empty, needed for extension compat
      38           0 : NS_INTERFACE_MAP_END
      39             : 
      40           0 : nsHistory::nsHistory(nsPIDOMWindowInner* aInnerWindow)
      41           0 :   : mInnerWindow(do_GetWeakReference(aInnerWindow))
      42             : {
      43           0 :   MOZ_ASSERT(aInnerWindow->IsInnerWindow());
      44           0 : }
      45             : 
      46           0 : nsHistory::~nsHistory()
      47             : {
      48           0 : }
      49             : 
      50             : nsPIDOMWindowInner*
      51           0 : nsHistory::GetParentObject() const
      52             : {
      53           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
      54           0 :   return win;
      55             : }
      56             : 
      57             : JSObject*
      58           0 : nsHistory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
      59             : {
      60           0 :   return HistoryBinding::Wrap(aCx, this, aGivenProto);
      61             : }
      62             : 
      63             : uint32_t
      64           0 : nsHistory::GetLength(ErrorResult& aRv) const
      65             : {
      66           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
      67           0 :   if (!win || !win->HasActiveDocument()) {
      68           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
      69             : 
      70           0 :     return 0;
      71             :   }
      72             : 
      73             :   // Get session History from docshell
      74           0 :   nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
      75           0 :   if (!sHistory) {
      76           0 :     aRv.Throw(NS_ERROR_FAILURE);
      77             : 
      78           0 :     return 0;
      79             :   }
      80             : 
      81             :   int32_t len;
      82           0 :   nsresult rv = sHistory->GetGlobalCount(&len);
      83             : 
      84           0 :   if (NS_FAILED(rv)) {
      85           0 :     aRv.Throw(rv);
      86             : 
      87           0 :     return 0;
      88             :   }
      89             : 
      90           0 :   return len >= 0 ? len : 0;
      91             : }
      92             : 
      93             : ScrollRestoration
      94           0 : nsHistory::GetScrollRestoration(mozilla::ErrorResult& aRv)
      95             : {
      96           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
      97           0 :   if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
      98           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
      99           0 :     return mozilla::dom::ScrollRestoration::Auto;
     100             :   }
     101             : 
     102           0 :   bool currentScrollRestorationIsManual = false;
     103           0 :   win->GetDocShell()->
     104           0 :     GetCurrentScrollRestorationIsManual(&currentScrollRestorationIsManual);
     105           0 :   return currentScrollRestorationIsManual ?
     106             :     mozilla::dom::ScrollRestoration::Manual :
     107           0 :     mozilla::dom::ScrollRestoration::Auto;
     108             : }
     109             : 
     110             : void
     111           0 : nsHistory::SetScrollRestoration(mozilla::dom::ScrollRestoration aMode,
     112             :                                 mozilla::ErrorResult& aRv)
     113             : {
     114           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     115           0 :   if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
     116           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     117           0 :     return;
     118             :   }
     119             : 
     120           0 :   win->GetDocShell()->
     121           0 :     SetCurrentScrollRestorationIsManual(
     122           0 :       aMode == mozilla::dom::ScrollRestoration::Manual);
     123             : }
     124             : 
     125             : void
     126           0 : nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
     127             :                     ErrorResult& aRv) const
     128             : {
     129           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     130           0 :   if (!win) {
     131           0 :     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     132           0 :     return;
     133             :   }
     134             : 
     135           0 :   if (!win->HasActiveDocument()) {
     136           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     137           0 :     return;
     138             :   }
     139             : 
     140             :   nsCOMPtr<nsIDocument> doc =
     141           0 :     do_QueryInterface(win->GetExtantDoc());
     142           0 :   if (!doc) {
     143           0 :     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     144           0 :     return;
     145             :   }
     146             : 
     147           0 :   nsCOMPtr<nsIVariant> variant;
     148           0 :   doc->GetStateObject(getter_AddRefs(variant));
     149             : 
     150           0 :   if (variant) {
     151           0 :     aRv = variant->GetAsJSVal(aResult);
     152             : 
     153           0 :     if (aRv.Failed()) {
     154           0 :       return;
     155             :     }
     156             : 
     157           0 :     if (!JS_WrapValue(aCx, aResult)) {
     158           0 :       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     159             :     }
     160             : 
     161           0 :     return;
     162             :   }
     163             : 
     164           0 :   aResult.setNull();
     165             : }
     166             : 
     167             : void
     168           0 : nsHistory::Go(int32_t aDelta, ErrorResult& aRv)
     169             : {
     170           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     171           0 :   if (!win || !win->HasActiveDocument()) {
     172           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     173             : 
     174           0 :     return;
     175             :   }
     176             : 
     177           0 :   if (!aDelta) {
     178           0 :     nsCOMPtr<nsPIDOMWindowOuter> window;
     179           0 :     if (nsIDocShell* docShell = GetDocShell()) {
     180           0 :       window = docShell->GetWindow();
     181             :     }
     182             : 
     183           0 :     if (window && window->IsHandlingResizeEvent()) {
     184             :       // history.go(0) (aka location.reload()) was called on a window
     185             :       // that is handling a resize event. Sites do this since Netscape
     186             :       // 4.x needed it, but we don't, and it's a horrible experience
     187             :       // for nothing.  In stead of reloading the page, just clear
     188             :       // style data and reflow the page since some sites may use this
     189             :       // trick to work around gecko reflow bugs, and this should have
     190             :       // the same effect.
     191             : 
     192           0 :       nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
     193             : 
     194             :       nsIPresShell *shell;
     195             :       nsPresContext *pcx;
     196           0 :       if (doc && (shell = doc->GetShell()) && (pcx = shell->GetPresContext())) {
     197           0 :         pcx->RebuildAllStyleData(NS_STYLE_HINT_REFLOW, eRestyle_Subtree);
     198             :       }
     199             : 
     200           0 :       return;
     201             :     }
     202             :   }
     203             : 
     204           0 :   nsCOMPtr<nsISHistory> session_history = GetSessionHistory();
     205           0 :   nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(session_history));
     206           0 :   if (!webnav) {
     207           0 :     aRv.Throw(NS_ERROR_FAILURE);
     208             : 
     209           0 :     return;
     210             :   }
     211             : 
     212           0 :   int32_t curIndex = -1;
     213           0 :   int32_t len = 0;
     214           0 :   session_history->GetGlobalIndex(&curIndex);
     215           0 :   session_history->GetGlobalCount(&len);
     216             : 
     217           0 :   int32_t index = curIndex + aDelta;
     218           0 :   if (index > -1 && index < len)
     219           0 :     webnav->GotoIndex(index);
     220             : 
     221             :   // Ignore the return value from GotoIndex(), since returning errors
     222             :   // from GotoIndex() can lead to exceptions and a possible leak
     223             :   // of history length
     224             : }
     225             : 
     226             : void
     227           0 : nsHistory::Back(ErrorResult& aRv)
     228             : {
     229           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     230           0 :   if (!win || !win->HasActiveDocument()) {
     231           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     232             : 
     233           0 :     return;
     234             :   }
     235             : 
     236           0 :   nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
     237           0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
     238           0 :   if (!webNav) {
     239           0 :     aRv.Throw(NS_ERROR_FAILURE);
     240             : 
     241           0 :     return;
     242             :   }
     243             : 
     244           0 :   webNav->GoBack();
     245             : }
     246             : 
     247             : void
     248           0 : nsHistory::Forward(ErrorResult& aRv)
     249             : {
     250           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     251           0 :   if (!win || !win->HasActiveDocument()) {
     252           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     253             : 
     254           0 :     return;
     255             :   }
     256             : 
     257           0 :   nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
     258           0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
     259           0 :   if (!webNav) {
     260           0 :     aRv.Throw(NS_ERROR_FAILURE);
     261             : 
     262           0 :     return;
     263             :   }
     264             : 
     265           0 :   webNav->GoForward();
     266             : }
     267             : 
     268             : void
     269           0 : nsHistory::PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
     270             :                      const nsAString& aTitle, const nsAString& aUrl,
     271             :                      ErrorResult& aRv)
     272             : {
     273           0 :   PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, false);
     274           0 : }
     275             : 
     276             : void
     277           0 : nsHistory::ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
     278             :                         const nsAString& aTitle, const nsAString& aUrl,
     279             :                         ErrorResult& aRv)
     280             : {
     281           0 :   PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, true);
     282           0 : }
     283             : 
     284             : void
     285           0 : nsHistory::PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
     286             :                               const nsAString& aTitle, const nsAString& aUrl,
     287             :                               ErrorResult& aRv, bool aReplace)
     288             : {
     289           0 :   nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
     290           0 :   if (!win) {
     291           0 :     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     292             : 
     293           0 :     return;
     294             :   }
     295             : 
     296           0 :   if (!win->HasActiveDocument()) {
     297           0 :     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
     298             : 
     299           0 :     return;
     300             :   }
     301             : 
     302             :   // AddState might run scripts, so we need to hold a strong reference to the
     303             :   // docShell here to keep it from going away.
     304           0 :   nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
     305             : 
     306           0 :   if (!docShell) {
     307           0 :     aRv.Throw(NS_ERROR_FAILURE);
     308             : 
     309           0 :     return;
     310             :   }
     311             : 
     312             :   // The "replace" argument tells the docshell to whether to add a new
     313             :   // history entry or modify the current one.
     314             : 
     315           0 :   aRv = docShell->AddState(aData, aTitle, aUrl, aReplace, aCx);
     316             : }
     317             : 
     318             : nsIDocShell*
     319           0 : nsHistory::GetDocShell() const
     320             : {
     321           0 :   nsCOMPtr<nsPIDOMWindowInner> win = do_QueryReferent(mInnerWindow);
     322           0 :   if (!win) {
     323           0 :     return nullptr;
     324             :   }
     325           0 :   return win->GetDocShell();
     326             : }
     327             : 
     328             : already_AddRefed<nsISHistory>
     329           0 : nsHistory::GetSessionHistory() const
     330             : {
     331           0 :   nsIDocShell *docShell = GetDocShell();
     332           0 :   NS_ENSURE_TRUE(docShell, nullptr);
     333             : 
     334             :   // Get the root DocShell from it
     335           0 :   nsCOMPtr<nsIDocShellTreeItem> root;
     336           0 :   docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
     337           0 :   nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(root));
     338           0 :   NS_ENSURE_TRUE(webNav, nullptr);
     339             : 
     340           0 :   nsCOMPtr<nsISHistory> shistory;
     341             : 
     342             :   // Get SH from nsIWebNavigation
     343           0 :   webNav->GetSessionHistory(getter_AddRefs(shistory));
     344             : 
     345           0 :   return shistory.forget();
     346             : }

Generated by: LCOV version 1.13