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