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 #ifndef nsSHEntryShared_h__ 8 #define nsSHEntryShared_h__ 9 10 #include "nsCOMArray.h" 11 #include "nsCOMPtr.h" 12 #include "nsExpirationTracker.h" 13 #include "nsIBFCacheEntry.h" 14 #include "nsIWeakReferenceUtils.h" 15 #include "nsRect.h" 16 #include "nsString.h" 17 #include "nsStubMutationObserver.h" 18 19 #include "mozilla/Attributes.h" 20 #include "mozilla/UniquePtr.h" 21 22 class nsSHEntry; 23 class nsISHEntry; 24 class nsISHistory; 25 class nsIContentSecurityPolicy; 26 class nsIContentViewer; 27 class nsIDocShellTreeItem; 28 class nsILayoutHistoryState; 29 class nsIPrincipal; 30 class nsDocShellEditorData; 31 class nsFrameLoader; 32 class nsIMutableArray; 33 class nsSHistory; 34 35 // A document may have multiple SHEntries, either due to hash navigations or 36 // calls to history.pushState. SHEntries corresponding to the same document 37 // share many members; in particular, they share state related to the 38 // back/forward cache. 39 // 40 // The classes defined here are the vehicle for this sharing. 41 // 42 // Some of the state can only be stored in the process where we did the actual 43 // load, because that's where the objects live (eg. the content viewer). 44 45 namespace mozilla { 46 namespace dom { 47 class Document; 48 49 /** 50 * SHEntrySharedState holds shared state both in the child process and in the 51 * parent process. 52 */ 53 struct SHEntrySharedState { SHEntrySharedStateSHEntrySharedState54 SHEntrySharedState() : mId(GenerateId()) {} 55 SHEntrySharedState(const SHEntrySharedState& aState) = default; SHEntrySharedStateSHEntrySharedState56 SHEntrySharedState(nsIPrincipal* aTriggeringPrincipal, 57 nsIPrincipal* aPrincipalToInherit, 58 nsIPrincipal* aPartitionedPrincipalToInherit, 59 nsIContentSecurityPolicy* aCsp, 60 const nsACString& aContentType) 61 : mId(GenerateId()), 62 mTriggeringPrincipal(aTriggeringPrincipal), 63 mPrincipalToInherit(aPrincipalToInherit), 64 mPartitionedPrincipalToInherit(aPartitionedPrincipalToInherit), 65 mCsp(aCsp), 66 mContentType(aContentType) {} 67 68 // These members aren't copied by SHEntrySharedParentState::CopyFrom() because 69 // they're specific to a particular content viewer. 70 uint64_t mId = 0; 71 72 // These members are copied by SHEntrySharedParentState::CopyFrom(). If you 73 // add a member here, be sure to update the CopyFrom() implementation. 74 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; 75 nsCOMPtr<nsIPrincipal> mPrincipalToInherit; 76 nsCOMPtr<nsIPrincipal> mPartitionedPrincipalToInherit; 77 nsCOMPtr<nsIContentSecurityPolicy> mCsp; 78 nsCString mContentType; 79 // Child side updates layout history state when page is being unloaded or 80 // moved to bfcache. 81 nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState; 82 uint32_t mCacheKey = 0; 83 bool mIsFrameNavigation = false; 84 85 protected: 86 static uint64_t GenerateId(); 87 }; 88 89 /** 90 * SHEntrySharedParentState holds the shared state that can live in the parent 91 * process. 92 */ 93 class SHEntrySharedParentState : public SHEntrySharedState { 94 public: 95 friend class SessionHistoryInfo; 96 GetId()97 uint64_t GetId() const { return mId; } 98 void ChangeId(uint64_t aId); 99 100 void SetFrameLoader(nsFrameLoader* aFrameLoader); 101 102 nsFrameLoader* GetFrameLoader(); 103 104 void NotifyListenersContentViewerEvicted(); 105 GetExpirationState()106 nsExpirationState* GetExpirationState() { return &mExpirationState; } 107 108 SHEntrySharedParentState(); 109 SHEntrySharedParentState(nsIPrincipal* aTriggeringPrincipal, 110 nsIPrincipal* aPrincipalToInherit, 111 nsIPrincipal* aPartitionedPrincipalToInherit, 112 nsIContentSecurityPolicy* aCsp, 113 const nsACString& aContentType); 114 115 // This returns the existing SHEntrySharedParentState that was registered for 116 // aId, if one exists. 117 static SHEntrySharedParentState* Lookup(uint64_t aId); 118 119 protected: 120 virtual ~SHEntrySharedParentState(); NS_INLINE_DECL_VIRTUAL_REFCOUNTING_WITH_DESTROY(SHEntrySharedParentState,Destroy ())121 NS_INLINE_DECL_VIRTUAL_REFCOUNTING_WITH_DESTROY(SHEntrySharedParentState, 122 Destroy()) 123 124 virtual void Destroy() { delete this; } 125 126 void CopyFrom(SHEntrySharedParentState* aSource); 127 128 // These members are copied by SHEntrySharedParentState::CopyFrom(). If you 129 // add a member here, be sure to update the CopyFrom() implementation. 130 nsID mDocShellID{}; 131 132 nsIntRect mViewerBounds{0, 0, 0, 0}; 133 134 uint32_t mLastTouched = 0; 135 136 // These members aren't copied by SHEntrySharedParentState::CopyFrom() because 137 // they're specific to a particular content viewer. 138 nsWeakPtr mSHistory; 139 140 RefPtr<nsFrameLoader> mFrameLoader; 141 142 nsExpirationState mExpirationState; 143 144 bool mSticky = true; 145 bool mDynamicallyCreated = false; 146 147 // This flag is about necko cache, not bfcache. 148 bool mExpired = false; 149 150 bool mSaveLayoutState = true; 151 }; 152 153 /** 154 * SHEntrySharedChildState holds the shared state that needs to live in the 155 * process where the document was loaded. 156 */ 157 class SHEntrySharedChildState { 158 protected: 159 void CopyFrom(SHEntrySharedChildState* aSource); 160 161 public: 162 // These members are copied by SHEntrySharedChildState::CopyFrom(). If you 163 // add a member here, be sure to update the CopyFrom() implementation. 164 nsCOMArray<nsIDocShellTreeItem> mChildShells; 165 166 // These members aren't copied by SHEntrySharedChildState::CopyFrom() because 167 // they're specific to a particular content viewer. 168 nsCOMPtr<nsIContentViewer> mContentViewer; 169 RefPtr<mozilla::dom::Document> mDocument; 170 nsCOMPtr<nsISupports> mWindowState; 171 // FIXME Move to parent? 172 nsCOMPtr<nsIMutableArray> mRefreshURIList; 173 UniquePtr<nsDocShellEditorData> mEditorData; 174 }; 175 176 } // namespace dom 177 } // namespace mozilla 178 179 /** 180 * nsSHEntryShared holds the shared state if the session history is not stored 181 * in the parent process, or if the load itself happens in the parent process. 182 * Note, since nsSHEntryShared inherits both SHEntrySharedParentState and 183 * SHEntrySharedChildState and those have some same member variables, 184 * the ones from SHEntrySharedParentState should be used. 185 */ 186 class nsSHEntryShared final : public nsIBFCacheEntry, 187 public nsStubMutationObserver, 188 public mozilla::dom::SHEntrySharedParentState, 189 public mozilla::dom::SHEntrySharedChildState { 190 public: 191 static void EnsureHistoryTracker(); 192 static void Shutdown(); 193 194 using SHEntrySharedParentState::SHEntrySharedParentState; 195 196 already_AddRefed<nsSHEntryShared> Duplicate(); 197 198 NS_DECL_ISUPPORTS_INHERITED 199 NS_DECL_NSIBFCACHEENTRY 200 201 // The nsIMutationObserver bits we actually care about. 202 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED 203 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED 204 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED 205 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED 206 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED 207 208 private: 209 ~nsSHEntryShared(); 210 211 friend class nsSHEntry; 212 213 void RemoveFromExpirationTracker(); 214 void SyncPresentationState(); 215 void DropPresentationState(); 216 217 nsresult SetContentViewer(nsIContentViewer* aViewer); 218 }; 219 220 #endif 221