LCOV - code coverage report
Current view: top level - docshell/shistory - nsSHEntry.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 161 445 36.2 %
Date: 2017-07-14 16:53:18 Functions: 42 101 41.6 %
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 "nsSHEntry.h"
       8             : 
       9             : #include <algorithm>
      10             : 
      11             : #include "nsDocShellEditorData.h"
      12             : #include "nsIContentViewer.h"
      13             : #include "nsIDocShellLoadInfo.h"
      14             : #include "nsIDocShellTreeItem.h"
      15             : #include "nsIInputStream.h"
      16             : #include "nsILayoutHistoryState.h"
      17             : #include "nsIStructuredCloneContainer.h"
      18             : #include "nsIURI.h"
      19             : #include "nsSHEntryShared.h"
      20             : #include "nsSHistory.h"
      21             : 
      22             : #include "mozilla/net/ReferrerPolicy.h"
      23             : 
      24             : namespace dom = mozilla::dom;
      25             : 
      26             : static uint32_t gEntryID = 0;
      27             : 
      28           1 : nsSHEntry::nsSHEntry()
      29           1 :   : mShared(new nsSHEntryShared())
      30             :   , mReferrerPolicy(mozilla::net::RP_Unset)
      31             :   , mLoadType(0)
      32           1 :   , mID(gEntryID++)
      33             :   , mScrollPositionX(0)
      34             :   , mScrollPositionY(0)
      35             :   , mParent(nullptr)
      36             :   , mLoadReplace(false)
      37             :   , mURIWasModified(false)
      38             :   , mIsSrcdocEntry(false)
      39             :   , mScrollRestorationIsManual(false)
      40           3 :   , mLoadedInThisProcess(false)
      41             : {
      42           1 : }
      43             : 
      44           0 : nsSHEntry::nsSHEntry(const nsSHEntry& aOther)
      45             :   : mShared(aOther.mShared)
      46             :   , mURI(aOther.mURI)
      47             :   , mOriginalURI(aOther.mOriginalURI)
      48             :   , mReferrerURI(aOther.mReferrerURI)
      49           0 :   , mReferrerPolicy(aOther.mReferrerPolicy)
      50             :   , mTitle(aOther.mTitle)
      51             :   , mPostData(aOther.mPostData)
      52             :   , mLoadType(0)         // XXX why not copy?
      53           0 :   , mID(aOther.mID)
      54             :   , mScrollPositionX(0)  // XXX why not copy?
      55             :   , mScrollPositionY(0)  // XXX why not copy?
      56           0 :   , mParent(aOther.mParent)
      57             :   , mStateData(aOther.mStateData)
      58             :   , mSrcdocData(aOther.mSrcdocData)
      59             :   , mBaseURI(aOther.mBaseURI)
      60           0 :   , mLoadReplace(aOther.mLoadReplace)
      61           0 :   , mURIWasModified(aOther.mURIWasModified)
      62           0 :   , mIsSrcdocEntry(aOther.mIsSrcdocEntry)
      63             :   , mScrollRestorationIsManual(false)
      64           0 :   , mLoadedInThisProcess(aOther.mLoadedInThisProcess)
      65             : {
      66           0 : }
      67             : 
      68           0 : nsSHEntry::~nsSHEntry()
      69             : {
      70             :   // Null out the mParent pointers on all our kids.
      71           0 :   for (nsISHEntry* entry : mChildren) {
      72           0 :     if (entry) {
      73           0 :       entry->SetParent(nullptr);
      74             :     }
      75             :   }
      76           0 : }
      77             : 
      78          77 : NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry, nsISHEntryInternal)
      79             : 
      80             : NS_IMETHODIMP
      81           0 : nsSHEntry::SetScrollPosition(int32_t aX, int32_t aY)
      82             : {
      83           0 :   mScrollPositionX = aX;
      84           0 :   mScrollPositionY = aY;
      85           0 :   return NS_OK;
      86             : }
      87             : 
      88             : NS_IMETHODIMP
      89           2 : nsSHEntry::GetScrollPosition(int32_t* aX, int32_t* aY)
      90             : {
      91           2 :   *aX = mScrollPositionX;
      92           2 :   *aY = mScrollPositionY;
      93           2 :   return NS_OK;
      94             : }
      95             : 
      96             : NS_IMETHODIMP
      97           0 : nsSHEntry::GetURIWasModified(bool* aOut)
      98             : {
      99           0 :   *aOut = mURIWasModified;
     100           0 :   return NS_OK;
     101             : }
     102             : 
     103             : NS_IMETHODIMP
     104           0 : nsSHEntry::SetURIWasModified(bool aIn)
     105             : {
     106           0 :   mURIWasModified = aIn;
     107           0 :   return NS_OK;
     108             : }
     109             : 
     110             : NS_IMETHODIMP
     111           5 : nsSHEntry::GetURI(nsIURI** aURI)
     112             : {
     113           5 :   *aURI = mURI;
     114           5 :   NS_IF_ADDREF(*aURI);
     115           5 :   return NS_OK;
     116             : }
     117             : 
     118             : NS_IMETHODIMP
     119           0 : nsSHEntry::SetURI(nsIURI* aURI)
     120             : {
     121           0 :   mURI = aURI;
     122           0 :   return NS_OK;
     123             : }
     124             : 
     125             : NS_IMETHODIMP
     126           4 : nsSHEntry::GetOriginalURI(nsIURI** aOriginalURI)
     127             : {
     128           4 :   *aOriginalURI = mOriginalURI;
     129           4 :   NS_IF_ADDREF(*aOriginalURI);
     130           4 :   return NS_OK;
     131             : }
     132             : 
     133             : NS_IMETHODIMP
     134           1 : nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
     135             : {
     136           1 :   mOriginalURI = aOriginalURI;
     137           1 :   return NS_OK;
     138             : }
     139             : 
     140             : NS_IMETHODIMP
     141           2 : nsSHEntry::GetResultPrincipalURI(nsIURI** aResultPrincipalURI)
     142             : {
     143           2 :   *aResultPrincipalURI = mResultPrincipalURI;
     144           2 :   NS_IF_ADDREF(*aResultPrincipalURI);
     145           2 :   return NS_OK;
     146             : }
     147             : 
     148             : NS_IMETHODIMP
     149           1 : nsSHEntry::SetResultPrincipalURI(nsIURI* aResultPrincipalURI)
     150             : {
     151           1 :   mResultPrincipalURI = aResultPrincipalURI;
     152           1 :   return NS_OK;
     153             : }
     154             : 
     155             : NS_IMETHODIMP
     156           2 : nsSHEntry::GetLoadReplace(bool* aLoadReplace)
     157             : {
     158           2 :   *aLoadReplace = mLoadReplace;
     159           2 :   return NS_OK;
     160             : }
     161             : 
     162             : NS_IMETHODIMP
     163           1 : nsSHEntry::SetLoadReplace(bool aLoadReplace)
     164             : {
     165           1 :   mLoadReplace = aLoadReplace;
     166           1 :   return NS_OK;
     167             : }
     168             : 
     169             : NS_IMETHODIMP
     170           2 : nsSHEntry::GetReferrerURI(nsIURI** aReferrerURI)
     171             : {
     172           2 :   *aReferrerURI = mReferrerURI;
     173           2 :   NS_IF_ADDREF(*aReferrerURI);
     174           2 :   return NS_OK;
     175             : }
     176             : 
     177             : NS_IMETHODIMP
     178           1 : nsSHEntry::SetReferrerURI(nsIURI* aReferrerURI)
     179             : {
     180           1 :   mReferrerURI = aReferrerURI;
     181           1 :   return NS_OK;
     182             : }
     183             : 
     184             : NS_IMETHODIMP
     185           0 : nsSHEntry::GetReferrerPolicy(uint32_t* aReferrerPolicy)
     186             : {
     187           0 :   *aReferrerPolicy = mReferrerPolicy;
     188           0 :   return NS_OK;
     189             : }
     190             : 
     191             : NS_IMETHODIMP
     192           1 : nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy)
     193             : {
     194           1 :   mReferrerPolicy = aReferrerPolicy;
     195           1 :   return NS_OK;
     196             : }
     197             : 
     198             : NS_IMETHODIMP
     199           0 : nsSHEntry::SetContentViewer(nsIContentViewer* aViewer)
     200             : {
     201           0 :   return mShared->SetContentViewer(aViewer);
     202             : }
     203             : 
     204             : NS_IMETHODIMP
     205           3 : nsSHEntry::GetContentViewer(nsIContentViewer** aResult)
     206             : {
     207           3 :   *aResult = mShared->mContentViewer;
     208           3 :   NS_IF_ADDREF(*aResult);
     209           3 :   return NS_OK;
     210             : }
     211             : 
     212             : NS_IMETHODIMP
     213           3 : nsSHEntry::GetAnyContentViewer(nsISHEntry** aOwnerEntry,
     214             :                                nsIContentViewer** aResult)
     215             : {
     216             :   // Find a content viewer in the root node or any of its children,
     217             :   // assuming that there is only one content viewer total in any one
     218             :   // nsSHEntry tree
     219           3 :   GetContentViewer(aResult);
     220           3 :   if (*aResult) {
     221             : #ifdef DEBUG_PAGE_CACHE
     222             :     printf("Found content viewer\n");
     223             : #endif
     224           0 :     *aOwnerEntry = this;
     225           0 :     NS_ADDREF(*aOwnerEntry);
     226           0 :     return NS_OK;
     227             :   }
     228             :   // The root SHEntry doesn't have a ContentViewer, so check child nodes
     229           3 :   for (int32_t i = 0; i < mChildren.Count(); i++) {
     230           0 :     nsISHEntry* child = mChildren[i];
     231           0 :     if (child) {
     232             : #ifdef DEBUG_PAGE_CACHE
     233             :       printf("Evaluating SHEntry child %d\n", i);
     234             : #endif
     235           0 :       child->GetAnyContentViewer(aOwnerEntry, aResult);
     236           0 :       if (*aResult) {
     237           0 :         return NS_OK;
     238             :       }
     239             :     }
     240             :   }
     241           3 :   return NS_OK;
     242             : }
     243             : 
     244             : NS_IMETHODIMP
     245           0 : nsSHEntry::SetSticky(bool aSticky)
     246             : {
     247           0 :   mShared->mSticky = aSticky;
     248           0 :   return NS_OK;
     249             : }
     250             : 
     251             : NS_IMETHODIMP
     252           0 : nsSHEntry::GetSticky(bool* aSticky)
     253             : {
     254           0 :   *aSticky = mShared->mSticky;
     255           0 :   return NS_OK;
     256             : }
     257             : 
     258             : NS_IMETHODIMP
     259           2 : nsSHEntry::GetTitle(char16_t** aTitle)
     260             : {
     261             :   // Check for empty title...
     262           2 :   if (mTitle.IsEmpty() && mURI) {
     263             :     // Default title is the URL.
     264           4 :     nsAutoCString spec;
     265           2 :     if (NS_SUCCEEDED(mURI->GetSpec(spec))) {
     266           2 :       AppendUTF8toUTF16(spec, mTitle);
     267             :     }
     268             :   }
     269             : 
     270           2 :   *aTitle = ToNewUnicode(mTitle);
     271           2 :   return NS_OK;
     272             : }
     273             : 
     274             : NS_IMETHODIMP
     275           1 : nsSHEntry::SetTitle(const nsAString& aTitle)
     276             : {
     277           1 :   mTitle = aTitle;
     278           1 :   return NS_OK;
     279             : }
     280             : 
     281             : NS_IMETHODIMP
     282           0 : nsSHEntry::GetPostData(nsIInputStream** aResult)
     283             : {
     284           0 :   *aResult = mPostData;
     285           0 :   NS_IF_ADDREF(*aResult);
     286           0 :   return NS_OK;
     287             : }
     288             : 
     289             : NS_IMETHODIMP
     290           0 : nsSHEntry::SetPostData(nsIInputStream* aPostData)
     291             : {
     292           0 :   mPostData = aPostData;
     293           0 :   return NS_OK;
     294             : }
     295             : 
     296             : NS_IMETHODIMP
     297           6 : nsSHEntry::GetLayoutHistoryState(nsILayoutHistoryState** aResult)
     298             : {
     299           6 :   *aResult = mShared->mLayoutHistoryState;
     300           6 :   NS_IF_ADDREF(*aResult);
     301           6 :   return NS_OK;
     302             : }
     303             : 
     304             : NS_IMETHODIMP
     305           1 : nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState)
     306             : {
     307           1 :   mShared->mLayoutHistoryState = aState;
     308           1 :   if (mShared->mLayoutHistoryState) {
     309           2 :     mShared->mLayoutHistoryState->SetScrollPositionOnly(
     310           2 :       !mShared->mSaveLayoutState);
     311             :   }
     312             : 
     313           1 :   return NS_OK;
     314             : }
     315             : 
     316             : NS_IMETHODIMP
     317           0 : nsSHEntry::InitLayoutHistoryState(nsILayoutHistoryState** aState)
     318             : {
     319           0 :   if (!mShared->mLayoutHistoryState) {
     320           0 :     nsCOMPtr<nsILayoutHistoryState> historyState;
     321           0 :     historyState = NS_NewLayoutHistoryState();
     322           0 :     nsresult rv = SetLayoutHistoryState(historyState);
     323           0 :     NS_ENSURE_SUCCESS(rv, rv);
     324             :   }
     325             : 
     326           0 :   return GetLayoutHistoryState(aState);
     327             : }
     328             : 
     329             : NS_IMETHODIMP
     330           0 : nsSHEntry::GetLoadType(uint32_t* aResult)
     331             : {
     332           0 :   *aResult = mLoadType;
     333           0 :   return NS_OK;
     334             : }
     335             : 
     336             : NS_IMETHODIMP
     337           1 : nsSHEntry::SetLoadType(uint32_t aLoadType)
     338             : {
     339           1 :   mLoadType = aLoadType;
     340           1 :   return NS_OK;
     341             : }
     342             : 
     343             : NS_IMETHODIMP
     344           2 : nsSHEntry::GetID(uint32_t* aResult)
     345             : {
     346           2 :   *aResult = mID;
     347           2 :   return NS_OK;
     348             : }
     349             : 
     350             : NS_IMETHODIMP
     351           0 : nsSHEntry::SetID(uint32_t aID)
     352             : {
     353           0 :   mID = aID;
     354           0 :   return NS_OK;
     355             : }
     356             : 
     357             : nsSHEntryShared*
     358           0 : nsSHEntry::GetSharedState()
     359             : {
     360           0 :   return mShared;
     361             : }
     362             : 
     363             : NS_IMETHODIMP
     364           3 : nsSHEntry::GetIsSubFrame(bool* aFlag)
     365             : {
     366           3 :   *aFlag = mShared->mIsFrameNavigation;
     367           3 :   return NS_OK;
     368             : }
     369             : 
     370             : NS_IMETHODIMP
     371           0 : nsSHEntry::SetIsSubFrame(bool aFlag)
     372             : {
     373           0 :   mShared->mIsFrameNavigation = aFlag;
     374           0 :   return NS_OK;
     375             : }
     376             : 
     377             : NS_IMETHODIMP
     378           2 : nsSHEntry::GetCacheKey(nsISupports** aResult)
     379             : {
     380           2 :   *aResult = mShared->mCacheKey;
     381           2 :   NS_IF_ADDREF(*aResult);
     382           2 :   return NS_OK;
     383             : }
     384             : 
     385             : NS_IMETHODIMP
     386           0 : nsSHEntry::SetCacheKey(nsISupports* aCacheKey)
     387             : {
     388           0 :   mShared->mCacheKey = aCacheKey;
     389           0 :   return NS_OK;
     390             : }
     391             : 
     392             : NS_IMETHODIMP
     393           0 : nsSHEntry::GetSaveLayoutStateFlag(bool* aFlag)
     394             : {
     395           0 :   *aFlag = mShared->mSaveLayoutState;
     396           0 :   return NS_OK;
     397             : }
     398             : 
     399             : NS_IMETHODIMP
     400           0 : nsSHEntry::SetSaveLayoutStateFlag(bool aFlag)
     401             : {
     402           0 :   mShared->mSaveLayoutState = aFlag;
     403           0 :   if (mShared->mLayoutHistoryState) {
     404           0 :     mShared->mLayoutHistoryState->SetScrollPositionOnly(!aFlag);
     405             :   }
     406             : 
     407           0 :   return NS_OK;
     408             : }
     409             : 
     410             : NS_IMETHODIMP
     411           0 : nsSHEntry::GetExpirationStatus(bool* aFlag)
     412             : {
     413           0 :   *aFlag = mShared->mExpired;
     414           0 :   return NS_OK;
     415             : }
     416             : 
     417             : NS_IMETHODIMP
     418           0 : nsSHEntry::SetExpirationStatus(bool aFlag)
     419             : {
     420           0 :   mShared->mExpired = aFlag;
     421           0 :   return NS_OK;
     422             : }
     423             : 
     424             : NS_IMETHODIMP
     425           2 : nsSHEntry::GetContentType(nsACString& aContentType)
     426             : {
     427           2 :   aContentType = mShared->mContentType;
     428           2 :   return NS_OK;
     429             : }
     430             : 
     431             : NS_IMETHODIMP
     432           0 : nsSHEntry::SetContentType(const nsACString& aContentType)
     433             : {
     434           0 :   mShared->mContentType = aContentType;
     435           0 :   return NS_OK;
     436             : }
     437             : 
     438             : NS_IMETHODIMP
     439           1 : nsSHEntry::Create(nsIURI* aURI, const nsAString& aTitle,
     440             :                   nsIInputStream* aInputStream,
     441             :                   nsILayoutHistoryState* aLayoutHistoryState,
     442             :                   nsISupports* aCacheKey, const nsACString& aContentType,
     443             :                   nsIPrincipal* aTriggeringPrincipal,
     444             :                   nsIPrincipal* aPrincipalToInherit,
     445             :                   const nsID& aDocShellID,
     446             :                   bool aDynamicCreation)
     447             : {
     448           1 :   MOZ_ASSERT(aTriggeringPrincipal,
     449             :              "need a valid triggeringPrincipal to create a session history entry");
     450             : 
     451           1 :   mURI = aURI;
     452           1 :   mTitle = aTitle;
     453           1 :   mPostData = aInputStream;
     454             : 
     455             :   // Set the LoadType by default to loadHistory during creation
     456           1 :   mLoadType = (uint32_t)nsIDocShellLoadInfo::loadHistory;
     457             : 
     458           1 :   mShared->mCacheKey = aCacheKey;
     459           1 :   mShared->mContentType = aContentType;
     460           1 :   mShared->mTriggeringPrincipal = aTriggeringPrincipal;
     461           1 :   mShared->mPrincipalToInherit = aPrincipalToInherit;
     462           1 :   mShared->mDocShellID = aDocShellID;
     463           1 :   mShared->mDynamicallyCreated = aDynamicCreation;
     464             : 
     465             :   // By default all entries are set false for subframe flag.
     466             :   // nsDocShell::CloneAndReplace() which creates entries for
     467             :   // all subframe navigations, sets the flag to true.
     468           1 :   mShared->mIsFrameNavigation = false;
     469             : 
     470             :   // By default we save LayoutHistoryState
     471           1 :   mShared->mSaveLayoutState = true;
     472           1 :   mShared->mLayoutHistoryState = aLayoutHistoryState;
     473             : 
     474             :   // By default the page is not expired
     475           1 :   mShared->mExpired = false;
     476             : 
     477           1 :   mIsSrcdocEntry = false;
     478           1 :   mSrcdocData = NullString();
     479             : 
     480           1 :   mLoadedInThisProcess = true;
     481             : 
     482           1 :   return NS_OK;
     483             : }
     484             : 
     485             : NS_IMETHODIMP
     486           0 : nsSHEntry::Clone(nsISHEntry** aResult)
     487             : {
     488           0 :   *aResult = new nsSHEntry(*this);
     489           0 :   NS_ADDREF(*aResult);
     490           0 :   return NS_OK;
     491             : }
     492             : 
     493             : NS_IMETHODIMP
     494           1 : nsSHEntry::GetParent(nsISHEntry** aResult)
     495             : {
     496           1 :   NS_ENSURE_ARG_POINTER(aResult);
     497           1 :   *aResult = mParent;
     498           1 :   NS_IF_ADDREF(*aResult);
     499           1 :   return NS_OK;
     500             : }
     501             : 
     502             : NS_IMETHODIMP
     503           0 : nsSHEntry::SetParent(nsISHEntry* aParent)
     504             : {
     505             :   /* parent not Addrefed on purpose to avoid cyclic reference
     506             :    * Null parent is OK
     507             :    *
     508             :    * XXX this method should not be scriptable if this is the case!!
     509             :    */
     510           0 :   mParent = aParent;
     511           0 :   return NS_OK;
     512             : }
     513             : 
     514             : NS_IMETHODIMP
     515           0 : nsSHEntry::SetWindowState(nsISupports* aState)
     516             : {
     517           0 :   mShared->mWindowState = aState;
     518           0 :   return NS_OK;
     519             : }
     520             : 
     521             : NS_IMETHODIMP
     522           0 : nsSHEntry::GetWindowState(nsISupports** aState)
     523             : {
     524           0 :   NS_IF_ADDREF(*aState = mShared->mWindowState);
     525           0 :   return NS_OK;
     526             : }
     527             : 
     528             : NS_IMETHODIMP
     529           0 : nsSHEntry::SetViewerBounds(const nsIntRect& aBounds)
     530             : {
     531           0 :   mShared->mViewerBounds = aBounds;
     532           0 :   return NS_OK;
     533             : }
     534             : 
     535             : NS_IMETHODIMP
     536           0 : nsSHEntry::GetViewerBounds(nsIntRect& aBounds)
     537             : {
     538           0 :   aBounds = mShared->mViewerBounds;
     539           0 :   return NS_OK;
     540             : }
     541             : 
     542             : NS_IMETHODIMP
     543           4 : nsSHEntry::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal)
     544             : {
     545           4 :   NS_IF_ADDREF(*aTriggeringPrincipal = mShared->mTriggeringPrincipal);
     546           4 :   return NS_OK;
     547             : }
     548             : 
     549             : NS_IMETHODIMP
     550           0 : nsSHEntry::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal)
     551             : {
     552           0 :   mShared->mTriggeringPrincipal = aTriggeringPrincipal;
     553           0 :   return NS_OK;
     554             : }
     555             : 
     556             : NS_IMETHODIMP
     557           2 : nsSHEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit)
     558             : {
     559           2 :   NS_IF_ADDREF(*aPrincipalToInherit = mShared->mPrincipalToInherit);
     560           2 :   return NS_OK;
     561             : }
     562             : 
     563             : NS_IMETHODIMP
     564           0 : nsSHEntry::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit)
     565             : {
     566           0 :   mShared->mPrincipalToInherit = aPrincipalToInherit;
     567           0 :   return NS_OK;
     568             : }
     569             : 
     570             : NS_IMETHODIMP
     571           2 : nsSHEntry::GetBFCacheEntry(nsIBFCacheEntry** aEntry)
     572             : {
     573           2 :   NS_ENSURE_ARG_POINTER(aEntry);
     574           2 :   NS_IF_ADDREF(*aEntry = mShared);
     575           2 :   return NS_OK;
     576             : }
     577             : 
     578             : bool
     579           0 : nsSHEntry::HasBFCacheEntry(nsIBFCacheEntry* aEntry)
     580             : {
     581           0 :   return static_cast<nsIBFCacheEntry*>(mShared) == aEntry;
     582             : }
     583             : 
     584             : NS_IMETHODIMP
     585           0 : nsSHEntry::AdoptBFCacheEntry(nsISHEntry* aEntry)
     586             : {
     587           0 :   nsCOMPtr<nsISHEntryInternal> shEntry = do_QueryInterface(aEntry);
     588           0 :   NS_ENSURE_STATE(shEntry);
     589             : 
     590           0 :   nsSHEntryShared* shared = shEntry->GetSharedState();
     591           0 :   NS_ENSURE_STATE(shared);
     592             : 
     593           0 :   mShared = shared;
     594           0 :   return NS_OK;
     595             : }
     596             : 
     597             : NS_IMETHODIMP
     598           0 : nsSHEntry::SharesDocumentWith(nsISHEntry* aEntry, bool* aOut)
     599             : {
     600           0 :   NS_ENSURE_ARG_POINTER(aOut);
     601             : 
     602           0 :   nsCOMPtr<nsISHEntryInternal> internal = do_QueryInterface(aEntry);
     603           0 :   NS_ENSURE_STATE(internal);
     604             : 
     605           0 :   *aOut = mShared == internal->GetSharedState();
     606           0 :   return NS_OK;
     607             : }
     608             : 
     609             : NS_IMETHODIMP
     610           0 : nsSHEntry::AbandonBFCacheEntry()
     611             : {
     612           0 :   mShared = nsSHEntryShared::Duplicate(mShared);
     613           0 :   return NS_OK;
     614             : }
     615             : 
     616             : NS_IMETHODIMP
     617           2 : nsSHEntry::GetIsSrcdocEntry(bool* aIsSrcdocEntry)
     618             : {
     619           2 :   *aIsSrcdocEntry = mIsSrcdocEntry;
     620           2 :   return NS_OK;
     621             : }
     622             : 
     623             : NS_IMETHODIMP
     624           2 : nsSHEntry::GetSrcdocData(nsAString& aSrcdocData)
     625             : {
     626           2 :   aSrcdocData = mSrcdocData;
     627           2 :   return NS_OK;
     628             : }
     629             : 
     630             : NS_IMETHODIMP
     631           0 : nsSHEntry::SetSrcdocData(const nsAString& aSrcdocData)
     632             : {
     633           0 :   mSrcdocData = aSrcdocData;
     634           0 :   mIsSrcdocEntry = true;
     635           0 :   return NS_OK;
     636             : }
     637             : 
     638             : NS_IMETHODIMP
     639           2 : nsSHEntry::GetBaseURI(nsIURI** aBaseURI)
     640             : {
     641           2 :   *aBaseURI = mBaseURI;
     642           2 :   NS_IF_ADDREF(*aBaseURI);
     643           2 :   return NS_OK;
     644             : }
     645             : 
     646             : NS_IMETHODIMP
     647           0 : nsSHEntry::SetBaseURI(nsIURI* aBaseURI)
     648             : {
     649           0 :   mBaseURI = aBaseURI;
     650           0 :   return NS_OK;
     651             : }
     652             : 
     653             : NS_IMETHODIMP
     654           2 : nsSHEntry::GetScrollRestorationIsManual(bool* aIsManual)
     655             : {
     656           2 :   *aIsManual = mScrollRestorationIsManual;
     657           2 :   return NS_OK;
     658             : }
     659             : 
     660             : NS_IMETHODIMP
     661           0 : nsSHEntry::SetScrollRestorationIsManual(bool aIsManual)
     662             : {
     663           0 :   mScrollRestorationIsManual = aIsManual;
     664           0 :   return NS_OK;
     665             : }
     666             : 
     667             : NS_IMETHODIMP
     668           0 : nsSHEntry::GetLoadedInThisProcess(bool* aLoadedInThisProcess)
     669             : {
     670           0 :   *aLoadedInThisProcess = mLoadedInThisProcess;
     671           0 :   return NS_OK;
     672             : }
     673             : 
     674             : NS_IMETHODIMP
     675           2 : nsSHEntry::GetChildCount(int32_t* aCount)
     676             : {
     677           2 :   *aCount = mChildren.Count();
     678           2 :   return NS_OK;
     679             : }
     680             : 
     681             : NS_IMETHODIMP
     682           0 : nsSHEntry::AddChild(nsISHEntry* aChild, int32_t aOffset)
     683             : {
     684           0 :   if (aChild) {
     685           0 :     NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
     686             :   }
     687             : 
     688           0 :   if (aOffset < 0) {
     689           0 :     mChildren.AppendObject(aChild);
     690           0 :     return NS_OK;
     691             :   }
     692             : 
     693             :   //
     694             :   // Bug 52670: Ensure children are added in order.
     695             :   //
     696             :   //  Later frames in the child list may load faster and get appended
     697             :   //  before earlier frames, causing session history to be scrambled.
     698             :   //  By growing the list here, they are added to the right position.
     699             :   //
     700             :   //  Assert that aOffset will not be so high as to grow us a lot.
     701             :   //
     702           0 :   NS_ASSERTION(aOffset < (mChildren.Count() + 1023), "Large frames array!\n");
     703             : 
     704           0 :   bool newChildIsDyn = false;
     705           0 :   if (aChild) {
     706           0 :     aChild->IsDynamicallyAdded(&newChildIsDyn);
     707             :   }
     708             : 
     709             :   // If the new child is dynamically added, try to add it to aOffset, but if
     710             :   // there are non-dynamically added children, the child must be after those.
     711           0 :   if (newChildIsDyn) {
     712           0 :     int32_t lastNonDyn = aOffset - 1;
     713           0 :     for (int32_t i = aOffset; i < mChildren.Count(); ++i) {
     714           0 :       nsISHEntry* entry = mChildren[i];
     715           0 :       if (entry) {
     716           0 :         bool dyn = false;
     717           0 :         entry->IsDynamicallyAdded(&dyn);
     718           0 :         if (dyn) {
     719           0 :           break;
     720             :         } else {
     721           0 :           lastNonDyn = i;
     722             :         }
     723             :       }
     724             :     }
     725             :     // InsertObjectAt allows only appending one object.
     726             :     // If aOffset is larger than Count(), we must first manually
     727             :     // set the capacity.
     728           0 :     if (aOffset > mChildren.Count()) {
     729           0 :       mChildren.SetCount(aOffset);
     730             :     }
     731           0 :     if (!mChildren.InsertObjectAt(aChild, lastNonDyn + 1)) {
     732           0 :       NS_WARNING("Adding a child failed!");
     733           0 :       aChild->SetParent(nullptr);
     734           0 :       return NS_ERROR_FAILURE;
     735             :     }
     736             :   } else {
     737             :     // If the new child isn't dynamically added, it should be set to aOffset.
     738             :     // If there are dynamically added children before that, those must be
     739             :     // moved to be after aOffset.
     740           0 :     if (mChildren.Count() > 0) {
     741           0 :       int32_t start = std::min(mChildren.Count() - 1, aOffset);
     742           0 :       int32_t dynEntryIndex = -1;
     743           0 :       nsISHEntry* dynEntry = nullptr;
     744           0 :       for (int32_t i = start; i >= 0; --i) {
     745           0 :         nsISHEntry* entry = mChildren[i];
     746           0 :         if (entry) {
     747           0 :           bool dyn = false;
     748           0 :           entry->IsDynamicallyAdded(&dyn);
     749           0 :           if (dyn) {
     750           0 :             dynEntryIndex = i;
     751           0 :             dynEntry = entry;
     752             :           } else {
     753           0 :             break;
     754             :           }
     755             :         }
     756             :       }
     757             : 
     758           0 :       if (dynEntry) {
     759           0 :         nsCOMArray<nsISHEntry> tmp;
     760           0 :         tmp.SetCount(aOffset - dynEntryIndex + 1);
     761           0 :         mChildren.InsertObjectsAt(tmp, dynEntryIndex);
     762           0 :         NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?");
     763             :       }
     764             :     }
     765             : 
     766             :     // Make sure there isn't anything at aOffset.
     767           0 :     if (aOffset < mChildren.Count()) {
     768           0 :       nsISHEntry* oldChild = mChildren[aOffset];
     769           0 :       if (oldChild && oldChild != aChild) {
     770           0 :         NS_ERROR("Adding a child where we already have a child? This may misbehave");
     771           0 :         oldChild->SetParent(nullptr);
     772             :       }
     773             :     }
     774             : 
     775           0 :     mChildren.ReplaceObjectAt(aChild, aOffset);
     776             :   }
     777             : 
     778           0 :   return NS_OK;
     779             : }
     780             : 
     781             : NS_IMETHODIMP
     782           0 : nsSHEntry::RemoveChild(nsISHEntry* aChild)
     783             : {
     784           0 :   NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
     785           0 :   bool childRemoved = false;
     786           0 :   bool dynamic = false;
     787           0 :   aChild->IsDynamicallyAdded(&dynamic);
     788           0 :   if (dynamic) {
     789           0 :     childRemoved = mChildren.RemoveObject(aChild);
     790             :   } else {
     791           0 :     int32_t index = mChildren.IndexOfObject(aChild);
     792           0 :     if (index >= 0) {
     793             :       // Other alive non-dynamic child docshells still keep mChildOffset,
     794             :       // so we don't want to change the indices here.
     795           0 :       mChildren.ReplaceObjectAt(nullptr, index);
     796           0 :       childRemoved = true;
     797             :     }
     798             :   }
     799           0 :   if (childRemoved) {
     800           0 :     aChild->SetParent(nullptr);
     801             : 
     802             :     // reduce the child count, i.e. remove empty children at the end
     803           0 :     for (int32_t i = mChildren.Count() - 1; i >= 0 && !mChildren[i]; --i) {
     804           0 :       if (!mChildren.RemoveObjectAt(i)) {
     805           0 :         break;
     806             :       }
     807             :     }
     808             :   }
     809           0 :   return NS_OK;
     810             : }
     811             : 
     812             : NS_IMETHODIMP
     813           0 : nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry** aResult)
     814             : {
     815           0 :   if (aIndex >= 0 && aIndex < mChildren.Count()) {
     816           0 :     *aResult = mChildren[aIndex];
     817             :     // yes, mChildren can have holes in it.  AddChild's offset parameter makes
     818             :     // that possible.
     819           0 :     NS_IF_ADDREF(*aResult);
     820             :   } else {
     821           0 :     *aResult = nullptr;
     822             :   }
     823           0 :   return NS_OK;
     824             : }
     825             : 
     826             : NS_IMETHODIMP
     827           0 : nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry)
     828             : {
     829           0 :   NS_ENSURE_STATE(aNewEntry);
     830             : 
     831           0 :   nsID docshellID = aNewEntry->DocshellID();
     832             : 
     833           0 :   for (int32_t i = 0; i < mChildren.Count(); ++i) {
     834           0 :     if (mChildren[i] && docshellID == mChildren[i]->DocshellID()) {
     835           0 :       mChildren[i]->SetParent(nullptr);
     836           0 :       mChildren.ReplaceObjectAt(aNewEntry, i);
     837           0 :       return aNewEntry->SetParent(this);
     838             :     }
     839             :   }
     840           0 :   return NS_ERROR_FAILURE;
     841             : }
     842             : 
     843             : NS_IMETHODIMP
     844           0 : nsSHEntry::AddChildShell(nsIDocShellTreeItem* aShell)
     845             : {
     846           0 :   NS_ASSERTION(aShell, "Null child shell added to history entry");
     847           0 :   mShared->mChildShells.AppendObject(aShell);
     848           0 :   return NS_OK;
     849             : }
     850             : 
     851             : NS_IMETHODIMP
     852           0 : nsSHEntry::ChildShellAt(int32_t aIndex, nsIDocShellTreeItem** aShell)
     853             : {
     854           0 :   NS_IF_ADDREF(*aShell = mShared->mChildShells.SafeObjectAt(aIndex));
     855           0 :   return NS_OK;
     856             : }
     857             : 
     858             : NS_IMETHODIMP
     859           0 : nsSHEntry::ClearChildShells()
     860             : {
     861           0 :   mShared->mChildShells.Clear();
     862           0 :   return NS_OK;
     863             : }
     864             : 
     865             : NS_IMETHODIMP
     866           0 : nsSHEntry::GetRefreshURIList(nsIMutableArray** aList)
     867             : {
     868           0 :   NS_IF_ADDREF(*aList = mShared->mRefreshURIList);
     869           0 :   return NS_OK;
     870             : }
     871             : 
     872             : NS_IMETHODIMP
     873           0 : nsSHEntry::SetRefreshURIList(nsIMutableArray* aList)
     874             : {
     875           0 :   mShared->mRefreshURIList = aList;
     876           0 :   return NS_OK;
     877             : }
     878             : 
     879             : NS_IMETHODIMP
     880           0 : nsSHEntry::SyncPresentationState()
     881             : {
     882           0 :   return mShared->SyncPresentationState();
     883             : }
     884             : 
     885             : void
     886           0 : nsSHEntry::RemoveFromBFCacheSync()
     887             : {
     888           0 :   mShared->RemoveFromBFCacheSync();
     889           0 : }
     890             : 
     891             : void
     892           0 : nsSHEntry::RemoveFromBFCacheAsync()
     893             : {
     894           0 :   mShared->RemoveFromBFCacheAsync();
     895           0 : }
     896             : 
     897             : nsDocShellEditorData*
     898           0 : nsSHEntry::ForgetEditorData()
     899             : {
     900             :   // XXX jlebar Check how this is used.
     901           0 :   return mShared->mEditorData.forget();
     902             : }
     903             : 
     904             : void
     905           0 : nsSHEntry::SetEditorData(nsDocShellEditorData* aData)
     906             : {
     907           0 :   NS_ASSERTION(!(aData && mShared->mEditorData),
     908             :                "We're going to overwrite an owning ref!");
     909           0 :   if (mShared->mEditorData != aData) {
     910           0 :     mShared->mEditorData = aData;
     911             :   }
     912           0 : }
     913             : 
     914             : bool
     915           1 : nsSHEntry::HasDetachedEditor()
     916             : {
     917           1 :   return mShared->mEditorData != nullptr;
     918             : }
     919             : 
     920             : NS_IMETHODIMP
     921           3 : nsSHEntry::GetStateData(nsIStructuredCloneContainer** aContainer)
     922             : {
     923           3 :   NS_ENSURE_ARG_POINTER(aContainer);
     924           3 :   NS_IF_ADDREF(*aContainer = mStateData);
     925           3 :   return NS_OK;
     926             : }
     927             : 
     928             : NS_IMETHODIMP
     929           0 : nsSHEntry::SetStateData(nsIStructuredCloneContainer* aContainer)
     930             : {
     931           0 :   mStateData = aContainer;
     932           0 :   return NS_OK;
     933             : }
     934             : 
     935             : NS_IMETHODIMP
     936           0 : nsSHEntry::IsDynamicallyAdded(bool* aAdded)
     937             : {
     938           0 :   *aAdded = mShared->mDynamicallyCreated;
     939           0 :   return NS_OK;
     940             : }
     941             : 
     942             : NS_IMETHODIMP
     943           0 : nsSHEntry::HasDynamicallyAddedChild(bool* aAdded)
     944             : {
     945           0 :   *aAdded = false;
     946           0 :   for (int32_t i = 0; i < mChildren.Count(); ++i) {
     947           0 :     nsISHEntry* entry = mChildren[i];
     948           0 :     if (entry) {
     949           0 :       entry->IsDynamicallyAdded(aAdded);
     950           0 :       if (*aAdded) {
     951           0 :         break;
     952             :       }
     953             :     }
     954             :   }
     955           0 :   return NS_OK;
     956             : }
     957             : 
     958             : NS_IMETHODIMP
     959           2 : nsSHEntry::GetDocshellID(nsID** aID)
     960             : {
     961           2 :   *aID = static_cast<nsID*>(nsMemory::Clone(&mShared->mDocShellID, sizeof(nsID)));
     962           2 :   return NS_OK;
     963             : }
     964             : 
     965             : const nsID
     966           0 : nsSHEntry::DocshellID()
     967             : {
     968           0 :   return mShared->mDocShellID;
     969             : }
     970             : 
     971             : NS_IMETHODIMP
     972           1 : nsSHEntry::SetDocshellID(const nsID* aID)
     973             : {
     974           1 :   mShared->mDocShellID = *aID;
     975           1 :   return NS_OK;
     976             : }
     977             : 
     978             : NS_IMETHODIMP
     979           0 : nsSHEntry::GetLastTouched(uint32_t* aLastTouched)
     980             : {
     981           0 :   *aLastTouched = mShared->mLastTouched;
     982           0 :   return NS_OK;
     983             : }
     984             : 
     985             : NS_IMETHODIMP
     986           0 : nsSHEntry::SetLastTouched(uint32_t aLastTouched)
     987             : {
     988           0 :   mShared->mLastTouched = aLastTouched;
     989           0 :   return NS_OK;
     990             : }
     991             : 
     992             : NS_IMETHODIMP
     993           1 : nsSHEntry::GetSHistory(nsISHistory** aSHistory)
     994             : {
     995           2 :   nsCOMPtr<nsISHistory> shistory(do_QueryReferent(mShared->mSHistory));
     996           1 :   shistory.forget(aSHistory);
     997           2 :   return NS_OK;
     998             : }
     999             : 
    1000             : NS_IMETHODIMP
    1001           1 : nsSHEntry::SetSHistory(nsISHistory* aSHistory)
    1002             : {
    1003           2 :   nsWeakPtr shistory = do_GetWeakReference(aSHistory);
    1004             :   // mSHistory can not be changed once it's set
    1005           1 :   MOZ_ASSERT(!mShared->mSHistory || (mShared->mSHistory == shistory));
    1006           1 :   mShared->mSHistory = shistory;
    1007           2 :   return NS_OK;
    1008             : }

Generated by: LCOV version 1.13