nsSHEntryShared.h (7328B)
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 "nsIPolicyContainer.h" 15 #include "nsIWeakReferenceUtils.h" 16 #include "nsRect.h" 17 #include "nsString.h" 18 #include "nsStructuredCloneContainer.h" 19 #include "nsStubMutationObserver.h" 20 21 #include "mozilla/UniquePtr.h" 22 23 class nsSHEntry; 24 class nsISHEntry; 25 class nsISHistory; 26 class nsIDocShellTreeItem; 27 class nsIDocumentViewer; 28 class nsILayoutHistoryState; 29 class nsIPolicyContainer; 30 class nsIPrincipal; 31 class nsDocShellEditorData; 32 class nsFrameLoader; 33 class nsIMutableArray; 34 class nsSHistory; 35 36 // A document may have multiple SHEntries, either due to hash navigations or 37 // calls to history.pushState. SHEntries corresponding to the same document 38 // share many members; in particular, they share state related to the 39 // back/forward cache. 40 // 41 // The classes defined here are the vehicle for this sharing. 42 // 43 // Some of the state can only be stored in the process where we did the actual 44 // load, because that's where the objects live (eg. the content viewer). 45 46 namespace mozilla { 47 namespace dom { 48 class Document; 49 50 /** 51 * SHEntrySharedState holds shared state both in the child process and in the 52 * parent process. 53 */ 54 struct SHEntrySharedState { 55 SHEntrySharedState() : mId(GenerateId()) {} 56 SHEntrySharedState(const SHEntrySharedState& aState) = default; 57 SHEntrySharedState(nsIPrincipal* aTriggeringPrincipal, 58 nsIPrincipal* aPrincipalToInherit, 59 nsIPrincipal* aPartitionedPrincipalToInherit, 60 nsIPolicyContainer* aPolicyContainer, 61 const nsACString& aContentType) 62 : mId(GenerateId()), 63 mTriggeringPrincipal(aTriggeringPrincipal), 64 mPrincipalToInherit(aPrincipalToInherit), 65 mPartitionedPrincipalToInherit(aPartitionedPrincipalToInherit), 66 mPolicyContainer(aPolicyContainer), 67 mContentType(aContentType) {} 68 69 // These members aren't copied by SHEntrySharedParentState::CopyFrom() because 70 // they're specific to a particular content viewer. 71 uint64_t mId = 0; 72 73 // These members are copied by SHEntrySharedParentState::CopyFrom(). If you 74 // add a member here, be sure to update the CopyFrom() implementation. 75 nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; 76 nsCOMPtr<nsIPrincipal> mPrincipalToInherit; 77 nsCOMPtr<nsIPrincipal> mPartitionedPrincipalToInherit; 78 nsCOMPtr<nsIPolicyContainer> mPolicyContainer; 79 nsCString mContentType; 80 // Child side updates layout history state when page is being unloaded or 81 // moved to bfcache. 82 nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState; 83 uint32_t mCacheKey = 0; 84 bool mIsFrameNavigation = false; 85 bool mSaveLayoutState = true; 86 87 protected: 88 static uint64_t GenerateId(); 89 }; 90 91 /** 92 * SHEntrySharedParentState holds the shared state that can live in the parent 93 * process. 94 */ 95 class SHEntrySharedParentState : public SHEntrySharedState { 96 public: 97 friend class SessionHistoryInfo; 98 99 uint64_t GetId() const { return mId; } 100 void ChangeId(uint64_t aId); 101 102 void SetFrameLoader(nsFrameLoader* aFrameLoader); 103 104 nsFrameLoader* GetFrameLoader(); 105 106 void NotifyListenersDocumentViewerEvicted(); 107 108 nsExpirationState* GetExpirationState() { return &mExpirationState; } 109 110 SHEntrySharedParentState(); 111 SHEntrySharedParentState(nsIPrincipal* aTriggeringPrincipal, 112 nsIPrincipal* aPrincipalToInherit, 113 nsIPrincipal* aPartitionedPrincipalToInherit, 114 nsIPolicyContainer* aPolicyContainer, 115 const nsACString& aContentType); 116 117 // This returns the existing SHEntrySharedParentState that was registered for 118 // aId, if one exists. 119 static SHEntrySharedParentState* Lookup(uint64_t aId); 120 121 protected: 122 virtual ~SHEntrySharedParentState(); 123 NS_INLINE_DECL_VIRTUAL_REFCOUNTING_WITH_DESTROY(SHEntrySharedParentState, 124 Destroy()) 125 126 virtual void Destroy() { delete this; } 127 128 void CopyFrom(SHEntrySharedParentState* aSource); 129 130 // These members are copied by SHEntrySharedParentState::CopyFrom(). If you 131 // add a member here, be sure to update the CopyFrom() implementation. 132 nsID mDocShellID{}; 133 134 nsIntRect mViewerBounds{0, 0, 0, 0}; 135 136 uint32_t mLastTouched = 0; 137 138 // These members aren't copied by SHEntrySharedParentState::CopyFrom() because 139 // they're specific to a particular content viewer. 140 nsWeakPtr mSHistory; 141 142 RefPtr<nsFrameLoader> mFrameLoader; 143 144 nsExpirationState mExpirationState; 145 146 bool mSticky = true; 147 bool mDynamicallyCreated = false; 148 149 // This flag is about necko cache, not bfcache. 150 bool mExpired = false; 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<nsIDocumentViewer> mDocumentViewer; 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 SetDocumentViewer(nsIDocumentViewer* aViewer); 218 }; 219 220 #endif