Bug 1866400 - Recognise Asahi Linux as a Fedora distro r=ahochheiden
[gecko.git] / docshell / base / BrowsingContext.h
blobce4e4f80f8e1ebe6ab75d0d89847d61e70ac3bf9
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/. */
7 #ifndef mozilla_dom_BrowsingContext_h
8 #define mozilla_dom_BrowsingContext_h
10 #include <tuple>
11 #include "GVAutoplayRequestUtils.h"
12 #include "mozilla/ErrorResult.h"
13 #include "mozilla/HalScreenConfiguration.h"
14 #include "mozilla/LinkedList.h"
15 #include "mozilla/Maybe.h"
16 #include "mozilla/RefPtr.h"
17 #include "mozilla/Span.h"
19 #include "mozilla/dom/BindingDeclarations.h"
20 #include "mozilla/dom/LocationBase.h"
21 #include "mozilla/dom/MaybeDiscarded.h"
22 #include "mozilla/dom/PopupBlocker.h"
23 #include "mozilla/dom/UserActivation.h"
24 #include "mozilla/dom/BrowsingContextBinding.h"
25 #include "mozilla/dom/ScreenOrientationBinding.h"
26 #include "mozilla/dom/SyncedContext.h"
27 #include "nsCOMPtr.h"
28 #include "nsCycleCollectionParticipant.h"
29 #include "nsIDocShell.h"
30 #include "nsTArray.h"
31 #include "nsWrapperCache.h"
32 #include "nsILoadInfo.h"
33 #include "nsILoadContext.h"
34 #include "nsThreadUtils.h"
36 class nsDocShellLoadState;
37 class nsGlobalWindowInner;
38 class nsGlobalWindowOuter;
39 class nsIPrincipal;
40 class nsOuterWindowProxy;
41 struct nsPoint;
42 class PickleIterator;
44 namespace IPC {
45 class Message;
46 class MessageReader;
47 class MessageWriter;
48 } // namespace IPC
50 namespace mozilla {
52 class ErrorResult;
53 class LogModule;
55 namespace ipc {
56 class IProtocol;
57 class IPCResult;
59 template <typename T>
60 struct IPDLParamTraits;
61 } // namespace ipc
63 namespace dom {
64 class BrowsingContent;
65 class BrowsingContextGroup;
66 class CanonicalBrowsingContext;
67 class ChildSHistory;
68 class ContentParent;
69 class Element;
70 struct LoadingSessionHistoryInfo;
71 class Location;
72 template <typename>
73 struct Nullable;
74 template <typename T>
75 class Sequence;
76 class SessionHistoryInfo;
77 class SessionStorageManager;
78 class StructuredCloneHolder;
79 class WindowContext;
80 class WindowGlobalChild;
81 struct WindowPostMessageOptions;
82 class WindowProxyHolder;
84 enum class ExplicitActiveStatus : uint8_t {
85 None,
86 Active,
87 Inactive,
88 EndGuard_,
91 struct EmbedderColorSchemes {
92 PrefersColorSchemeOverride mUsed{};
93 PrefersColorSchemeOverride mPreferred{};
95 bool operator==(const EmbedderColorSchemes& aOther) const {
96 return mUsed == aOther.mUsed && mPreferred == aOther.mPreferred;
99 bool operator!=(const EmbedderColorSchemes& aOther) const {
100 return !(*this == aOther);
104 // Fields are, by default, settable by any process and readable by any process.
105 // Racy sets will be resolved as-if they occurred in the order the parent
106 // process finds out about them.
108 // The `DidSet` and `CanSet` methods may be overloaded to provide different
109 // behavior for a specific field.
110 // * `DidSet` is called to run code in every process whenever the value is
111 // updated (This currently occurs even if the value didn't change, though
112 // this may change in the future).
113 // * `CanSet` is called before attempting to set the value, in both the process
114 // which calls `Set`, and the parent process, and will kill the misbehaving
115 // process if it fails.
116 #define MOZ_EACH_BC_FIELD(FIELD) \
117 FIELD(Name, nsString) \
118 FIELD(Closed, bool) \
119 FIELD(ExplicitActive, ExplicitActiveStatus) \
120 /* Top()-only. If true, new-playing media will be suspended when in an \
121 * inactive browsing context. */ \
122 FIELD(SuspendMediaWhenInactive, bool) \
123 /* If true, we're within the nested event loop in window.open, and this \
124 * context may not be used as the target of a load */ \
125 FIELD(PendingInitialization, bool) \
126 /* Indicates if the browser window is active for the purpose of the \
127 * :-moz-window-inactive pseudoclass. Only read from or set on the \
128 * top BrowsingContext. */ \
129 FIELD(IsActiveBrowserWindowInternal, bool) \
130 FIELD(OpenerPolicy, nsILoadInfo::CrossOriginOpenerPolicy) \
131 /* Current opener for the BrowsingContext. Weak reference */ \
132 FIELD(OpenerId, uint64_t) \
133 FIELD(OnePermittedSandboxedNavigatorId, uint64_t) \
134 /* WindowID of the inner window which embeds this BC */ \
135 FIELD(EmbedderInnerWindowId, uint64_t) \
136 FIELD(CurrentInnerWindowId, uint64_t) \
137 FIELD(HadOriginalOpener, bool) \
138 FIELD(IsPopupSpam, bool) \
139 /* Hold the audio muted state and should be used on top level browsing \
140 * contexts only */ \
141 FIELD(Muted, bool) \
142 /* Hold the pinned/app-tab state and should be used on top level browsing \
143 * contexts only */ \
144 FIELD(IsAppTab, bool) \
145 /* Whether there's more than 1 tab / toplevel browsing context in this \
146 * parent window. Used to determine if a given BC is allowed to resize \
147 * and/or move the window or not. */ \
148 FIELD(HasSiblings, bool) \
149 /* Indicate that whether we should delay media playback, which would only \
150 be done on an unvisited tab. And this should only be used on the top \
151 level browsing contexts */ \
152 FIELD(ShouldDelayMediaFromStart, bool) \
153 /* See nsSandboxFlags.h for the possible flags. */ \
154 FIELD(SandboxFlags, uint32_t) \
155 /* The value of SandboxFlags when the BrowsingContext is first created. \
156 * Used for sandboxing the initial about:blank document. */ \
157 FIELD(InitialSandboxFlags, uint32_t) \
158 /* A non-zero unique identifier for the browser element that is hosting \
159 * this \
160 * BrowsingContext tree. Every BrowsingContext in the element's tree will \
161 * return the same ID in all processes and it will remain stable \
162 * regardless of process changes. When a browser element's frameloader is \
163 * switched to another browser element this ID will remain the same but \
164 * hosted under the under the new browser element. */ \
165 FIELD(BrowserId, uint64_t) \
166 FIELD(HistoryID, nsID) \
167 FIELD(InRDMPane, bool) \
168 FIELD(Loading, bool) \
169 /* A field only set on top browsing contexts, which indicates that either: \
171 * * This is a browsing context created explicitly for printing or print \
172 * preview (thus hosting static documents). \
174 * * This is a browsing context where something in this tree is calling \
175 * window.print() (and thus showing a modal dialog). \
177 * We use it exclusively to block navigation for both of these cases. */ \
178 FIELD(IsPrinting, bool) \
179 FIELD(AncestorLoading, bool) \
180 FIELD(AllowPlugins, bool) \
181 FIELD(AllowContentRetargeting, bool) \
182 FIELD(AllowContentRetargetingOnChildren, bool) \
183 FIELD(ForceEnableTrackingProtection, bool) \
184 FIELD(UseGlobalHistory, bool) \
185 FIELD(TargetTopLevelLinkClicksToBlankInternal, bool) \
186 FIELD(FullscreenAllowedByOwner, bool) \
187 FIELD(ForceDesktopViewport, bool) \
188 /* \
189 * "is popup" in the spec. \
190 * Set only on top browsing contexts. \
191 * This doesn't indicate whether this is actually a popup or not, \
192 * but whether this browsing context is created by requesting popup or not. \
193 * See also: nsWindowWatcher::ShouldOpenPopup. \
194 */ \
195 FIELD(IsPopupRequested, bool) \
196 /* These field are used to store the states of autoplay media request on \
197 * GeckoView only, and it would only be modified on the top level browsing \
198 * context. */ \
199 FIELD(GVAudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
200 FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
201 /* ScreenOrientation-related APIs */ \
202 FIELD(CurrentOrientationAngle, float) \
203 FIELD(CurrentOrientationType, mozilla::dom::OrientationType) \
204 FIELD(OrientationLock, mozilla::hal::ScreenOrientation) \
205 FIELD(UserAgentOverride, nsString) \
206 FIELD(TouchEventsOverrideInternal, mozilla::dom::TouchEventsOverride) \
207 FIELD(EmbedderElementType, Maybe<nsString>) \
208 FIELD(MessageManagerGroup, nsString) \
209 FIELD(MaxTouchPointsOverride, uint8_t) \
210 FIELD(FullZoom, float) \
211 FIELD(WatchedByDevToolsInternal, bool) \
212 FIELD(TextZoom, float) \
213 FIELD(OverrideDPPX, float) \
214 /* The current in-progress load. */ \
215 FIELD(CurrentLoadIdentifier, Maybe<uint64_t>) \
216 /* See nsIRequest for possible flags. */ \
217 FIELD(DefaultLoadFlags, uint32_t) \
218 /* Signals that session history is enabled for this browsing context tree. \
219 * This is only ever set to true on the top BC, so consumers need to get \
220 * the value from the top BC! */ \
221 FIELD(HasSessionHistory, bool) \
222 /* Tracks if this context is the only top-level document in the session \
223 * history of the context. */ \
224 FIELD(IsSingleToplevelInHistory, bool) \
225 FIELD(UseErrorPages, bool) \
226 FIELD(PlatformOverride, nsString) \
227 /* Specifies if this BC has loaded documents besides the initial \
228 * about:blank document. about:privatebrowsing, about:home, about:newtab \
229 * and non-initial about:blank are not considered to be initial \
230 * documents. */ \
231 FIELD(HasLoadedNonInitialDocument, bool) \
232 /* Default value for nsIDocumentViewer::authorStyleDisabled in any new \
233 * browsing contexts created as a descendant of this one. Valid only for \
234 * top BCs. */ \
235 FIELD(AuthorStyleDisabledDefault, bool) \
236 FIELD(ServiceWorkersTestingEnabled, bool) \
237 FIELD(MediumOverride, nsString) \
238 /* DevTools override for prefers-color-scheme */ \
239 FIELD(PrefersColorSchemeOverride, dom::PrefersColorSchemeOverride) \
240 /* prefers-color-scheme override based on the color-scheme style of our \
241 * <browser> embedder element. */ \
242 FIELD(EmbedderColorSchemes, EmbedderColorSchemes) \
243 FIELD(DisplayMode, dom::DisplayMode) \
244 /* The number of entries added to the session history because of this \
245 * browsing context. */ \
246 FIELD(HistoryEntryCount, uint32_t) \
247 /* Don't use the getter of the field, but IsInBFCache() method */ \
248 FIELD(IsInBFCache, bool) \
249 FIELD(HasRestoreData, bool) \
250 FIELD(SessionStoreEpoch, uint32_t) \
251 /* Whether we can execute scripts in this BrowsingContext. Has no effect \
252 * unless scripts are also allowed in the parent WindowContext. */ \
253 FIELD(AllowJavascript, bool) \
254 /* The count of request that are used to prevent the browsing context tree \
255 * from being suspended, which would ONLY be modified on the top level \
256 * context in the chrome process because that's a non-atomic counter */ \
257 FIELD(PageAwakeRequestCount, uint32_t) \
258 /* This field only gets incrememented when we start navigations in the \
259 * parent process. This is used for keeping track of the racing navigations \
260 * between the parent and content processes. */ \
261 FIELD(ParentInitiatedNavigationEpoch, uint64_t) \
262 /* This browsing context is for a synthetic image document wrapping an \
263 * image embedded in <object> or <embed>. */ \
264 FIELD(SyntheticDocumentContainer, bool) \
265 /* If true, this document is embedded within a content document, either \
266 * loaded in the parent (e.g. about:addons or the devtools toolbox), or in \
267 * a content process. */ \
268 FIELD(EmbeddedInContentDocument, bool) \
269 /* If true, this browsing context is within a hidden embedded document. */ \
270 FIELD(IsUnderHiddenEmbedderElement, bool) \
271 /* If true, this browsing context is offline */ \
272 FIELD(ForceOffline, bool)
274 // BrowsingContext, in this context, is the cross process replicated
275 // environment in which information about documents is stored. In
276 // particular the tree structure of nested browsing contexts is
277 // represented by the tree of BrowsingContexts.
279 // The tree of BrowsingContexts is created in step with its
280 // corresponding nsDocShell, and when nsDocShells are connected
281 // through a parent/child relationship, so are BrowsingContexts. The
282 // major difference is that BrowsingContexts are replicated (synced)
283 // to the parent process, making it possible to traverse the
284 // BrowsingContext tree for a tab, in both the parent and the child
285 // process.
287 // Trees of BrowsingContexts should only ever contain nodes of the
288 // same BrowsingContext::Type. This is enforced by asserts in the
289 // BrowsingContext::Create* methods.
290 class BrowsingContext : public nsILoadContext, public nsWrapperCache {
291 MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD)
293 public:
294 enum class Type { Chrome, Content };
296 static void Init();
297 static LogModule* GetLog();
298 static LogModule* GetSyncLog();
300 // Look up a BrowsingContext in the current process by ID.
301 static already_AddRefed<BrowsingContext> Get(uint64_t aId);
302 static already_AddRefed<BrowsingContext> Get(GlobalObject&, uint64_t aId) {
303 return Get(aId);
305 // Look up the top-level BrowsingContext by BrowserID.
306 static already_AddRefed<BrowsingContext> GetCurrentTopByBrowserId(
307 uint64_t aBrowserId);
308 static already_AddRefed<BrowsingContext> GetCurrentTopByBrowserId(
309 GlobalObject&, uint64_t aId) {
310 return GetCurrentTopByBrowserId(aId);
313 static void UpdateCurrentTopByBrowserId(BrowsingContext* aNewBrowsingContext);
315 static already_AddRefed<BrowsingContext> GetFromWindow(
316 WindowProxyHolder& aProxy);
317 static already_AddRefed<BrowsingContext> GetFromWindow(
318 GlobalObject&, WindowProxyHolder& aProxy) {
319 return GetFromWindow(aProxy);
322 static void DiscardFromContentParent(ContentParent* aCP);
324 // Create a brand-new toplevel BrowsingContext with no relationships to other
325 // BrowsingContexts, and which is not embedded within any <browser> or frame
326 // element.
328 // This BrowsingContext is immediately attached, and cannot have LoadContext
329 // flags customized unless it is of `Type::Chrome`.
331 // The process which created this BrowsingContext is responsible for detaching
332 // it.
333 static already_AddRefed<BrowsingContext> CreateIndependent(Type aType);
335 // Create a brand-new BrowsingContext object, but does not immediately attach
336 // it. State such as OriginAttributes and PrivateBrowsingId may be customized
337 // to configure the BrowsingContext before it is attached.
339 // `EnsureAttached()` must be called before the BrowsingContext is used for a
340 // DocShell, BrowserParent, or BrowserBridgeChild.
341 static already_AddRefed<BrowsingContext> CreateDetached(
342 nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
343 BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
344 bool aIsPopupRequested, bool aCreatedDynamically = false);
346 void EnsureAttached();
348 bool EverAttached() const { return mEverAttached; }
350 // Cast this object to a canonical browsing context, and return it.
351 CanonicalBrowsingContext* Canonical();
353 // Is the most recent Document in this BrowsingContext loaded within this
354 // process? This may be true with a null mDocShell after the Window has been
355 // closed.
356 bool IsInProcess() const { return mIsInProcess; }
358 bool IsOwnedByProcess() const;
360 bool CanHaveRemoteOuterProxies() const {
361 return !mIsInProcess || mDanglingRemoteOuterProxies;
364 // Has this BrowsingContext been discarded. A discarded browsing context has
365 // been destroyed, and may not be available on the other side of an IPC
366 // message.
367 bool IsDiscarded() const { return mIsDiscarded; }
369 // Returns true if none of the BrowsingContext's ancestor BrowsingContexts or
370 // WindowContexts are discarded or cached.
371 bool AncestorsAreCurrent() const;
373 bool Windowless() const { return mWindowless; }
375 // Get the DocShell for this BrowsingContext if it is in-process, or
376 // null if it's not.
377 nsIDocShell* GetDocShell() const { return mDocShell; }
378 void SetDocShell(nsIDocShell* aDocShell);
379 void ClearDocShell() { mDocShell = nullptr; }
381 // Get the Document for this BrowsingContext if it is in-process, or
382 // null if it's not.
383 Document* GetDocument() const {
384 return mDocShell ? mDocShell->GetDocument() : nullptr;
386 Document* GetExtantDocument() const {
387 return mDocShell ? mDocShell->GetExtantDocument() : nullptr;
390 // This cleans up remote outer window proxies that might have been left behind
391 // when the browsing context went from being remote to local. It does this by
392 // turning them into cross-compartment wrappers to aOuter. If there is already
393 // a remote proxy in the compartment of aOuter, then aOuter will get swapped
394 // to it and the value of aOuter will be set to the object that used to be the
395 // remote proxy and is now an OuterWindowProxy.
396 void CleanUpDanglingRemoteOuterWindowProxies(
397 JSContext* aCx, JS::MutableHandle<JSObject*> aOuter);
399 // Get the embedder element for this BrowsingContext if the embedder is
400 // in-process, or null if it's not.
401 Element* GetEmbedderElement() const { return mEmbedderElement; }
402 void SetEmbedderElement(Element* aEmbedder);
404 // Return true if the type of the embedder element is either object
405 // or embed, false otherwise.
406 bool IsEmbedderTypeObjectOrEmbed();
408 // Called after the BrowingContext has been embedded in a FrameLoader. This
409 // happens after `SetEmbedderElement` is called on the BrowsingContext and
410 // after the BrowsingContext has been set on the FrameLoader.
411 void Embed();
413 // Get the outer window object for this BrowsingContext if it is in-process
414 // and still has a docshell, or null otherwise.
415 nsPIDOMWindowOuter* GetDOMWindow() const {
416 return mDocShell ? mDocShell->GetWindow() : nullptr;
419 uint64_t GetRequestContextId() const { return mRequestContextId; }
421 // Detach the current BrowsingContext from its parent, in both the
422 // child and the parent process.
423 void Detach(bool aFromIPC = false);
425 // Prepare this BrowsingContext to leave the current process.
426 void PrepareForProcessChange();
428 // Triggers a load in the process which currently owns this BrowsingContext.
429 nsresult LoadURI(nsDocShellLoadState* aLoadState,
430 bool aSetNavigating = false);
432 nsresult InternalLoad(nsDocShellLoadState* aLoadState);
434 // Removes the root document for this BrowsingContext tree from the BFCache,
435 // if it is cached, and returns true if it was.
436 bool RemoveRootFromBFCacheSync();
438 // If the load state includes a source BrowsingContext has been passed, check
439 // to see if we are sandboxed from it as the result of an iframe or CSP
440 // sandbox.
441 nsresult CheckSandboxFlags(nsDocShellLoadState* aLoadState);
443 void DisplayLoadError(const nsAString& aURI);
445 // Check that this browsing context is targetable for navigations (i.e. that
446 // it is neither closed, cached, nor discarded).
447 bool IsTargetable() const;
449 // True if this browsing context is inactive and is able to be suspended.
450 bool InactiveForSuspend() const;
452 const nsString& Name() const { return GetName(); }
453 void GetName(nsAString& aName) { aName = GetName(); }
454 bool NameEquals(const nsAString& aName) { return GetName().Equals(aName); }
456 Type GetType() const { return mType; }
457 bool IsContent() const { return mType == Type::Content; }
458 bool IsChrome() const { return !IsContent(); }
460 bool IsTop() const { return !GetParent(); }
461 bool IsSubframe() const { return !IsTop(); }
463 bool IsTopContent() const { return IsContent() && IsTop(); }
465 bool IsInSubtreeOf(BrowsingContext* aContext);
467 bool IsContentSubframe() const { return IsContent() && IsSubframe(); }
469 // non-zero
470 uint64_t Id() const { return mBrowsingContextId; }
472 BrowsingContext* GetParent() const;
473 BrowsingContext* Top();
474 const BrowsingContext* Top() const;
476 int32_t IndexOf(BrowsingContext* aChild);
478 // NOTE: Unlike `GetEmbedderWindowGlobal`, `GetParentWindowContext` does not
479 // cross toplevel content browser boundaries.
480 WindowContext* GetParentWindowContext() const { return mParentWindow; }
481 WindowContext* GetTopWindowContext() const;
483 already_AddRefed<BrowsingContext> GetOpener() const {
484 RefPtr<BrowsingContext> opener(Get(GetOpenerId()));
485 if (!mIsDiscarded && opener && !opener->mIsDiscarded) {
486 MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
487 return opener.forget();
489 return nullptr;
491 void SetOpener(BrowsingContext* aOpener);
492 bool HasOpener() const;
494 bool HadOriginalOpener() const { return GetHadOriginalOpener(); }
496 // Returns true if the browsing context and top context are same origin
497 bool SameOriginWithTop();
500 * When a new browsing context is opened by a sandboxed document, it needs to
501 * keep track of the browsing context that opened it, so that it can be
502 * navigated by it. This is the "one permitted sandboxed navigator".
504 already_AddRefed<BrowsingContext> GetOnePermittedSandboxedNavigator() const {
505 return Get(GetOnePermittedSandboxedNavigatorId());
507 [[nodiscard]] nsresult SetOnePermittedSandboxedNavigator(
508 BrowsingContext* aNavigator) {
509 if (GetOnePermittedSandboxedNavigatorId()) {
510 MOZ_ASSERT(false,
511 "One Permitted Sandboxed Navigator should only be set once.");
512 return NS_ERROR_FAILURE;
513 } else {
514 return SetOnePermittedSandboxedNavigatorId(aNavigator ? aNavigator->Id()
515 : 0);
519 uint32_t SandboxFlags() const { return GetSandboxFlags(); }
521 Span<RefPtr<BrowsingContext>> Children() const;
522 void GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren);
524 Span<RefPtr<BrowsingContext>> NonSyntheticChildren() const;
526 const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
527 return mWindowContexts;
529 void GetWindowContexts(nsTArray<RefPtr<WindowContext>>& aWindows);
531 void RegisterWindowContext(WindowContext* aWindow);
532 void UnregisterWindowContext(WindowContext* aWindow);
533 WindowContext* GetCurrentWindowContext() const {
534 return mCurrentWindowContext;
537 // Helpers to traverse this BrowsingContext subtree. Note that these will only
538 // traverse active contexts, and will ignore ones in the BFCache.
539 enum class WalkFlag {
540 Next,
541 Skip,
542 Stop,
546 * Walk the browsing context tree in pre-order and call `aCallback`
547 * for every node in the tree. PreOrderWalk accepts two types of
548 * callbacks, either of the type `void(BrowsingContext*)` or
549 * `WalkFlag(BrowsingContext*)`. The former traverses the entire
550 * tree, but the latter let's you control if a sub-tree should be
551 * skipped by returning `WalkFlag::Skip`, completely abort traversal
552 * by returning `WalkFlag::Stop` or continue as normal with
553 * `WalkFlag::Next`.
555 template <typename F>
556 void PreOrderWalk(F&& aCallback) {
557 if constexpr (std::is_void_v<
558 typename std::invoke_result_t<F, BrowsingContext*>>) {
559 PreOrderWalkVoid(std::forward<F>(aCallback));
560 } else {
561 PreOrderWalkFlag(std::forward<F>(aCallback));
565 void PreOrderWalkVoid(const std::function<void(BrowsingContext*)>& aCallback);
566 WalkFlag PreOrderWalkFlag(
567 const std::function<WalkFlag(BrowsingContext*)>& aCallback);
569 void PostOrderWalk(const std::function<void(BrowsingContext*)>& aCallback);
571 void GetAllBrowsingContextsInSubtree(
572 nsTArray<RefPtr<BrowsingContext>>& aBrowsingContexts);
574 BrowsingContextGroup* Group() { return mGroup; }
576 // WebIDL bindings for nsILoadContext
577 Nullable<WindowProxyHolder> GetAssociatedWindow();
578 Nullable<WindowProxyHolder> GetTopWindow();
579 Element* GetTopFrameElement();
580 bool GetIsContent() { return IsContent(); }
581 void SetUsePrivateBrowsing(bool aUsePrivateBrowsing, ErrorResult& aError);
582 // Needs a different name to disambiguate from the xpidl method with
583 // the same signature but different return value.
584 void SetUseTrackingProtectionWebIDL(bool aUseTrackingProtection,
585 ErrorResult& aRv);
586 bool UseTrackingProtectionWebIDL() { return UseTrackingProtection(); }
587 void GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal,
588 ErrorResult& aError);
590 bool InRDMPane() const { return GetInRDMPane(); }
592 bool WatchedByDevTools();
593 void SetWatchedByDevTools(bool aWatchedByDevTools, ErrorResult& aRv);
595 dom::TouchEventsOverride TouchEventsOverride() const;
596 bool TargetTopLevelLinkClicksToBlank() const;
598 bool FullscreenAllowed() const;
600 float FullZoom() const { return GetFullZoom(); }
601 float TextZoom() const { return GetTextZoom(); }
603 float OverrideDPPX() const { return Top()->GetOverrideDPPX(); }
605 bool SuspendMediaWhenInactive() const {
606 return GetSuspendMediaWhenInactive();
609 bool IsActive() const;
610 void SetIsActive(bool aIsActive, mozilla::ErrorResult& aRv) {
611 SetExplicitActive(aIsActive ? ExplicitActiveStatus::Active
612 : ExplicitActiveStatus::Inactive,
613 aRv);
616 bool ForceOffline() const { return GetForceOffline(); }
618 bool ForceDesktopViewport() const { return GetForceDesktopViewport(); }
620 bool AuthorStyleDisabledDefault() const {
621 return GetAuthorStyleDisabledDefault();
624 bool UseGlobalHistory() const { return GetUseGlobalHistory(); }
626 bool GetIsActiveBrowserWindow();
628 void SetIsActiveBrowserWindow(bool aActive);
630 uint64_t BrowserId() const { return GetBrowserId(); }
632 bool IsLoading();
634 void GetEmbedderElementType(nsString& aElementType) {
635 if (GetEmbedderElementType().isSome()) {
636 aElementType = GetEmbedderElementType().value();
640 bool IsLoadingIdentifier(uint64_t aLoadIdentifer) {
641 if (GetCurrentLoadIdentifier() &&
642 *GetCurrentLoadIdentifier() == aLoadIdentifer) {
643 return true;
645 return false;
648 // ScreenOrientation related APIs
649 [[nodiscard]] nsresult SetCurrentOrientation(OrientationType aType,
650 float aAngle) {
651 Transaction txn;
652 txn.SetCurrentOrientationType(aType);
653 txn.SetCurrentOrientationAngle(aAngle);
654 return txn.Commit(this);
657 void SetRDMPaneOrientation(OrientationType aType, float aAngle,
658 ErrorResult& aRv) {
659 if (InRDMPane()) {
660 if (NS_FAILED(SetCurrentOrientation(aType, aAngle))) {
661 aRv.ThrowInvalidStateError("Browsing context is discarded");
666 void SetRDMPaneMaxTouchPoints(uint8_t aMaxTouchPoints, ErrorResult& aRv) {
667 if (InRDMPane()) {
668 SetMaxTouchPointsOverride(aMaxTouchPoints, aRv);
672 // Find a browsing context in this context's list of
673 // children. Doesn't consider the special names, '_self', '_parent',
674 // '_top', or '_blank'. Performs access control checks with regard to
675 // 'this'.
676 BrowsingContext* FindChildWithName(const nsAString& aName,
677 WindowGlobalChild& aRequestingWindow);
679 // Find a browsing context in the subtree rooted at 'this' Doesn't
680 // consider the special names, '_self', '_parent', '_top', or
681 // '_blank'.
683 // If passed, performs access control checks with regard to
684 // 'aRequestingContext', otherwise performs no access checks.
685 BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
686 WindowGlobalChild* aRequestingWindow);
688 // Find the special browsing context if aName is '_self', '_parent',
689 // '_top', but not '_blank'. The latter is handled in FindWithName
690 BrowsingContext* FindWithSpecialName(const nsAString& aName,
691 WindowGlobalChild& aRequestingWindow);
693 nsISupports* GetParentObject() const;
694 JSObject* WrapObject(JSContext* aCx,
695 JS::Handle<JSObject*> aGivenProto) override;
697 // Return the window proxy object that corresponds to this browsing context.
698 inline JSObject* GetWindowProxy() const { return mWindowProxy; }
699 inline JSObject* GetUnbarrieredWindowProxy() const {
700 return mWindowProxy.unbarrieredGet();
703 // Set the window proxy object that corresponds to this browsing context.
704 void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) {
705 mWindowProxy = aWindowProxy;
708 Nullable<WindowProxyHolder> GetWindow();
710 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
711 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(BrowsingContext)
712 NS_DECL_NSILOADCONTEXT
714 // Window APIs that are cross-origin-accessible (from the HTML spec).
715 WindowProxyHolder Window();
716 BrowsingContext* GetBrowsingContext() { return this; };
717 BrowsingContext* Self() { return this; }
718 void Location(JSContext* aCx, JS::MutableHandle<JSObject*> aLocation,
719 ErrorResult& aError);
720 void Close(CallerType aCallerType, ErrorResult& aError);
721 bool GetClosed(ErrorResult&) { return GetClosed(); }
722 void Focus(CallerType aCallerType, ErrorResult& aError);
723 void Blur(CallerType aCallerType, ErrorResult& aError);
724 WindowProxyHolder GetFrames(ErrorResult& aError);
725 int32_t Length() const { return Children().Length(); }
726 Nullable<WindowProxyHolder> GetTop(ErrorResult& aError);
727 void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aOpener,
728 ErrorResult& aError) const;
729 Nullable<WindowProxyHolder> GetParent(ErrorResult& aError);
730 void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
731 const nsAString& aTargetOrigin,
732 const Sequence<JSObject*>& aTransfer,
733 nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
734 void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
735 const WindowPostMessageOptions& aOptions,
736 nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
738 void GetCustomUserAgent(nsAString& aUserAgent) {
739 aUserAgent = Top()->GetUserAgentOverride();
741 nsresult SetCustomUserAgent(const nsAString& aUserAgent);
742 void SetCustomUserAgent(const nsAString& aUserAgent, ErrorResult& aRv);
744 void GetCustomPlatform(nsAString& aPlatform) {
745 aPlatform = Top()->GetPlatformOverride();
747 void SetCustomPlatform(const nsAString& aPlatform, ErrorResult& aRv);
749 JSObject* WrapObject(JSContext* aCx);
751 static JSObject* ReadStructuredClone(JSContext* aCx,
752 JSStructuredCloneReader* aReader,
753 StructuredCloneHolder* aHolder);
754 bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
755 StructuredCloneHolder* aHolder);
757 void StartDelayedAutoplayMediaComponents();
759 [[nodiscard]] nsresult ResetGVAutoplayRequestStatus();
762 * Information required to initialize a BrowsingContext in another process.
763 * This object may be serialized over IPC.
765 struct IPCInitializer {
766 uint64_t mId = 0;
768 // IDs are used for Parent and Opener to allow for this object to be
769 // deserialized before other BrowsingContext in the BrowsingContextGroup
770 // have been initialized.
771 uint64_t mParentId = 0;
772 already_AddRefed<WindowContext> GetParent();
773 already_AddRefed<BrowsingContext> GetOpener();
775 uint64_t GetOpenerId() const { return mFields.Get<IDX_OpenerId>(); }
777 bool mWindowless = false;
778 bool mUseRemoteTabs = false;
779 bool mUseRemoteSubframes = false;
780 bool mCreatedDynamically = false;
781 int32_t mChildOffset = 0;
782 int32_t mSessionHistoryIndex = -1;
783 int32_t mSessionHistoryCount = 0;
784 OriginAttributes mOriginAttributes;
785 uint64_t mRequestContextId = 0;
787 FieldValues mFields;
790 // Create an IPCInitializer object for this BrowsingContext.
791 IPCInitializer GetIPCInitializer();
793 // Create a BrowsingContext object from over IPC.
794 static mozilla::ipc::IPCResult CreateFromIPC(IPCInitializer&& aInitializer,
795 BrowsingContextGroup* aGroup,
796 ContentParent* aOriginProcess);
798 bool IsSandboxedFrom(BrowsingContext* aTarget);
800 // The runnable will be called once there is idle time, or the top level
801 // page has been loaded or if a timeout has fired.
802 // Must be called only on the top level BrowsingContext.
803 void AddDeprioritizedLoadRunner(nsIRunnable* aRunner);
805 RefPtr<SessionStorageManager> GetSessionStorageManager();
807 // Set PendingInitialization on this BrowsingContext before the context has
808 // been attached.
809 void InitPendingInitialization(bool aPendingInitialization) {
810 MOZ_ASSERT(!EverAttached());
811 mFields.SetWithoutSyncing<IDX_PendingInitialization>(
812 aPendingInitialization);
815 bool CreatedDynamically() const { return mCreatedDynamically; }
817 // Returns true if this browsing context, or any ancestor to this browsing
818 // context was created dynamically. See also `CreatedDynamically`.
819 bool IsDynamic() const;
821 int32_t ChildOffset() const { return mChildOffset; }
823 bool GetOffsetPath(nsTArray<uint32_t>& aPath) const;
825 const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
826 nsresult SetOriginAttributes(const OriginAttributes& aAttrs);
828 void GetHistoryID(JSContext* aCx, JS::MutableHandle<JS::Value> aVal,
829 ErrorResult& aError);
831 // This should only be called on the top browsing context.
832 void InitSessionHistory();
834 // This will only ever return a non-null value if called on the top browsing
835 // context.
836 ChildSHistory* GetChildSessionHistory();
838 bool CrossOriginIsolated();
840 // Check if it is allowed to open a popup from the current browsing
841 // context or any of its ancestors.
842 bool IsPopupAllowed();
844 // aCurrentURI is only required to be non-null if the load type contains the
845 // nsIWebNavigation::LOAD_FLAGS_IS_REFRESH flag and aInfo is for a refresh to
846 // the current URI.
847 void SessionHistoryCommit(const LoadingSessionHistoryInfo& aInfo,
848 uint32_t aLoadType, nsIURI* aCurrentURI,
849 SessionHistoryInfo* aPreviousActiveEntry,
850 bool aPersist, bool aCloneEntryChildren,
851 bool aChannelExpired, uint32_t aCacheKey);
853 // Set a new active entry on this browsing context. This is used for
854 // implementing history.pushState/replaceState and same document navigations.
855 // The new active entry will be linked to the current active entry through
856 // its shared state.
857 // aPreviousScrollPos is the scroll position that needs to be saved on the
858 // previous active entry.
859 // aUpdatedCacheKey is the cache key to set on the new active entry. If
860 // aUpdatedCacheKey is 0 then it will be ignored.
861 void SetActiveSessionHistoryEntry(const Maybe<nsPoint>& aPreviousScrollPos,
862 SessionHistoryInfo* aInfo,
863 uint32_t aLoadType,
864 uint32_t aUpdatedCacheKey,
865 bool aUpdateLength = true);
867 // Replace the active entry for this browsing context. This is used for
868 // implementing history.replaceState and same document navigations.
869 void ReplaceActiveSessionHistoryEntry(SessionHistoryInfo* aInfo);
871 // Removes dynamic child entries of the active entry.
872 void RemoveDynEntriesFromActiveSessionHistoryEntry();
874 // Removes entries corresponding to this BrowsingContext from session history.
875 void RemoveFromSessionHistory(const nsID& aChangeID);
877 void SetTriggeringAndInheritPrincipals(nsIPrincipal* aTriggeringPrincipal,
878 nsIPrincipal* aPrincipalToInherit,
879 uint64_t aLoadIdentifier);
881 // Return mTriggeringPrincipal and mPrincipalToInherit if the load id
882 // saved with the principal matches the current load identifier of this BC.
883 std::tuple<nsCOMPtr<nsIPrincipal>, nsCOMPtr<nsIPrincipal>>
884 GetTriggeringAndInheritPrincipalsForCurrentLoad();
886 void HistoryGo(int32_t aOffset, uint64_t aHistoryEpoch,
887 bool aRequireUserInteraction, bool aUserActivation,
888 std::function<void(Maybe<int32_t>&&)>&& aResolver);
890 bool ShouldUpdateSessionHistory(uint32_t aLoadType);
892 // Checks if we reached the rate limit for calls to Location and History API.
893 // The rate limit is controlled by the
894 // "dom.navigation.locationChangeRateLimit" prefs.
895 // Rate limit applies per BrowsingContext.
896 // Returns NS_OK if we are below the rate limit and increments the counter.
897 // Returns NS_ERROR_DOM_SECURITY_ERR if limit is reached.
898 nsresult CheckLocationChangeRateLimit(CallerType aCallerType);
900 void ResetLocationChangeRateLimit();
902 mozilla::dom::DisplayMode DisplayMode() { return Top()->GetDisplayMode(); }
904 // Returns canFocus, isActive
905 std::tuple<bool, bool> CanFocusCheck(CallerType aCallerType);
907 bool CanBlurCheck(CallerType aCallerType);
909 PopupBlocker::PopupControlState RevisePopupAbuseLevel(
910 PopupBlocker::PopupControlState aControl);
912 void IncrementHistoryEntryCountForBrowsingContext();
914 bool ServiceWorkersTestingEnabled() const {
915 return GetServiceWorkersTestingEnabled();
918 void GetMediumOverride(nsAString& aOverride) const {
919 aOverride = GetMediumOverride();
922 dom::PrefersColorSchemeOverride PrefersColorSchemeOverride() const {
923 return GetPrefersColorSchemeOverride();
926 bool IsInBFCache() const;
928 bool AllowJavascript() const { return GetAllowJavascript(); }
929 bool CanExecuteScripts() const { return mCanExecuteScripts; }
931 uint32_t DefaultLoadFlags() const { return GetDefaultLoadFlags(); }
933 // When request for page awake, it would increase a count that is used to
934 // prevent whole browsing context tree from being suspended. The request can
935 // be called multiple times. When calling the revoke, it would decrease the
936 // count and once the count reaches to zero, the browsing context tree could
937 // be suspended when the tree is inactive.
938 void RequestForPageAwake();
939 void RevokeForPageAwake();
941 void AddDiscardListener(std::function<void(uint64_t)>&& aListener);
943 bool IsAppTab() { return GetIsAppTab(); }
944 bool HasSiblings() { return GetHasSiblings(); }
946 bool IsUnderHiddenEmbedderElement() const {
947 return GetIsUnderHiddenEmbedderElement();
950 void LocationCreated(dom::Location* aLocation);
951 void ClearCachedValuesOfLocations();
953 protected:
954 virtual ~BrowsingContext();
955 BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
956 uint64_t aBrowsingContextId, Type aType, FieldValues&& aInit);
958 void SetChildSHistory(ChildSHistory* aChildSHistory);
959 already_AddRefed<ChildSHistory> ForgetChildSHistory() {
960 // FIXME Do we need to unset mHasSessionHistory?
961 return mChildSessionHistory.forget();
964 static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI,
965 const SessionHistoryInfo& aInfo);
966 static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI, nsIURI* aNewURI,
967 bool aHasPostData);
969 private:
970 mozilla::ipc::IPCResult Attach(bool aFromIPC, ContentParent* aOriginProcess);
972 // Recomputes whether we can execute scripts in this BrowsingContext based on
973 // the value of AllowJavascript() and whether scripts are allowed in the
974 // parent WindowContext. Called whenever the AllowJavascript() flag or the
975 // parent WC changes.
976 void RecomputeCanExecuteScripts();
978 // Is it early enough in the BrowsingContext's lifecycle that it is still
979 // OK to set OriginAttributes?
980 bool CanSetOriginAttributes();
982 void AssertOriginAttributesMatchPrivateBrowsing();
984 // Assert that the BrowsingContext's LoadContext flags appear coherent
985 // relative to related BrowsingContexts.
986 void AssertCoherentLoadContext();
988 friend class ::nsOuterWindowProxy;
989 friend class ::nsGlobalWindowOuter;
990 friend class WindowContext;
992 // Update the window proxy object that corresponds to this browsing context.
993 // This should be called from the window proxy object's objectMoved hook, if
994 // the object mWindowProxy points to was moved by the JS GC.
995 void UpdateWindowProxy(JSObject* obj, JSObject* old) {
996 if (mWindowProxy) {
997 MOZ_ASSERT(mWindowProxy == old);
998 mWindowProxy = obj;
1001 // Clear the window proxy object that corresponds to this browsing context.
1002 // This should be called if the window proxy object is finalized, or it can't
1003 // reach its browsing context anymore.
1004 void ClearWindowProxy() { mWindowProxy = nullptr; }
1006 friend class Location;
1007 friend class RemoteLocationProxy;
1009 * LocationProxy is the class for the native object stored as a private in a
1010 * RemoteLocationProxy proxy representing a Location object in a different
1011 * process. It forwards all operations to its BrowsingContext and aggregates
1012 * its refcount to that BrowsingContext.
1014 class LocationProxy final : public LocationBase {
1015 public:
1016 MozExternalRefCountType AddRef() { return GetBrowsingContext()->AddRef(); }
1017 MozExternalRefCountType Release() {
1018 return GetBrowsingContext()->Release();
1021 protected:
1022 friend class RemoteLocationProxy;
1023 BrowsingContext* GetBrowsingContext() override {
1024 return reinterpret_cast<BrowsingContext*>(
1025 uintptr_t(this) - offsetof(BrowsingContext, mLocation));
1028 nsIDocShell* GetDocShell() override { return nullptr; }
1031 // Send a given `BaseTransaction` object to the correct remote.
1032 void SendCommitTransaction(ContentParent* aParent,
1033 const BaseTransaction& aTxn, uint64_t aEpoch);
1034 void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
1035 uint64_t aEpoch);
1037 bool CanSet(FieldIndex<IDX_SessionStoreEpoch>, uint32_t aEpoch,
1038 ContentParent* aSource) {
1039 return IsTop() && !aSource;
1042 void DidSet(FieldIndex<IDX_SessionStoreEpoch>, uint32_t aOldValue);
1044 using CanSetResult = syncedcontext::CanSetResult;
1046 // Ensure that opener is in the same BrowsingContextGroup.
1047 bool CanSet(FieldIndex<IDX_OpenerId>, const uint64_t& aValue,
1048 ContentParent* aSource) {
1049 if (aValue != 0) {
1050 RefPtr<BrowsingContext> opener = Get(aValue);
1051 return opener && opener->Group() == Group();
1053 return true;
1056 bool CanSet(FieldIndex<IDX_OpenerPolicy>,
1057 nsILoadInfo::CrossOriginOpenerPolicy, ContentParent*);
1059 bool CanSet(FieldIndex<IDX_ServiceWorkersTestingEnabled>, bool,
1060 ContentParent*) {
1061 return IsTop();
1064 bool CanSet(FieldIndex<IDX_MediumOverride>, const nsString&, ContentParent*) {
1065 return IsTop();
1068 bool CanSet(FieldIndex<IDX_EmbedderColorSchemes>, const EmbedderColorSchemes&,
1069 ContentParent* aSource) {
1070 return CheckOnlyEmbedderCanSet(aSource);
1073 bool CanSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
1074 dom::PrefersColorSchemeOverride, ContentParent*) {
1075 return IsTop();
1078 void DidSet(FieldIndex<IDX_InRDMPane>, bool aOldValue);
1080 void DidSet(FieldIndex<IDX_EmbedderColorSchemes>,
1081 EmbedderColorSchemes&& aOldValue);
1083 void DidSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
1084 dom::PrefersColorSchemeOverride aOldValue);
1086 template <typename Callback>
1087 void WalkPresContexts(Callback&&);
1088 void PresContextAffectingFieldChanged();
1090 void DidSet(FieldIndex<IDX_MediumOverride>, nsString&& aOldValue);
1092 bool CanSet(FieldIndex<IDX_SuspendMediaWhenInactive>, bool, ContentParent*) {
1093 return IsTop();
1096 bool CanSet(FieldIndex<IDX_TouchEventsOverrideInternal>,
1097 dom::TouchEventsOverride aTouchEventsOverride,
1098 ContentParent* aSource);
1099 void DidSet(FieldIndex<IDX_TouchEventsOverrideInternal>,
1100 dom::TouchEventsOverride&& aOldValue);
1102 bool CanSet(FieldIndex<IDX_DisplayMode>, const enum DisplayMode& aDisplayMode,
1103 ContentParent* aSource) {
1104 return IsTop();
1107 void DidSet(FieldIndex<IDX_DisplayMode>, enum DisplayMode aOldValue);
1109 void DidSet(FieldIndex<IDX_ExplicitActive>, ExplicitActiveStatus aOldValue);
1111 bool CanSet(FieldIndex<IDX_IsActiveBrowserWindowInternal>, const bool& aValue,
1112 ContentParent* aSource);
1113 void DidSet(FieldIndex<IDX_IsActiveBrowserWindowInternal>, bool aOldValue);
1115 // Ensure that we only set the flag on the top level browsingContext.
1116 // And then, we do a pre-order walk in the tree to refresh the
1117 // volume of all media elements.
1118 void DidSet(FieldIndex<IDX_Muted>);
1120 bool CanSet(FieldIndex<IDX_IsAppTab>, const bool& aValue,
1121 ContentParent* aSource);
1123 bool CanSet(FieldIndex<IDX_HasSiblings>, const bool& aValue,
1124 ContentParent* aSource);
1126 bool CanSet(FieldIndex<IDX_ShouldDelayMediaFromStart>, const bool& aValue,
1127 ContentParent* aSource);
1128 void DidSet(FieldIndex<IDX_ShouldDelayMediaFromStart>, bool aOldValue);
1130 bool CanSet(FieldIndex<IDX_OverrideDPPX>, const float& aValue,
1131 ContentParent* aSource);
1132 void DidSet(FieldIndex<IDX_OverrideDPPX>, float aOldValue);
1134 bool CanSet(FieldIndex<IDX_EmbedderInnerWindowId>, const uint64_t& aValue,
1135 ContentParent* aSource);
1137 CanSetResult CanSet(FieldIndex<IDX_CurrentInnerWindowId>,
1138 const uint64_t& aValue, ContentParent* aSource);
1140 void DidSet(FieldIndex<IDX_CurrentInnerWindowId>);
1142 bool CanSet(FieldIndex<IDX_ParentInitiatedNavigationEpoch>,
1143 const uint64_t& aValue, ContentParent* aSource);
1145 bool CanSet(FieldIndex<IDX_IsPopupSpam>, const bool& aValue,
1146 ContentParent* aSource);
1148 void DidSet(FieldIndex<IDX_IsPopupSpam>);
1150 void DidSet(FieldIndex<IDX_GVAudibleAutoplayRequestStatus>);
1151 void DidSet(FieldIndex<IDX_GVInaudibleAutoplayRequestStatus>);
1153 void DidSet(FieldIndex<IDX_Loading>);
1155 void DidSet(FieldIndex<IDX_AncestorLoading>);
1157 void DidSet(FieldIndex<IDX_PlatformOverride>);
1158 CanSetResult CanSet(FieldIndex<IDX_PlatformOverride>,
1159 const nsString& aPlatformOverride,
1160 ContentParent* aSource);
1162 void DidSet(FieldIndex<IDX_UserAgentOverride>);
1163 CanSetResult CanSet(FieldIndex<IDX_UserAgentOverride>,
1164 const nsString& aUserAgent, ContentParent* aSource);
1165 bool CanSet(FieldIndex<IDX_OrientationLock>,
1166 const mozilla::hal::ScreenOrientation& aOrientationLock,
1167 ContentParent* aSource);
1169 bool CanSet(FieldIndex<IDX_EmbedderElementType>,
1170 const Maybe<nsString>& aInitiatorType, ContentParent* aSource);
1172 bool CanSet(FieldIndex<IDX_MessageManagerGroup>,
1173 const nsString& aMessageManagerGroup, ContentParent* aSource);
1175 CanSetResult CanSet(FieldIndex<IDX_AllowContentRetargeting>,
1176 const bool& aAllowContentRetargeting,
1177 ContentParent* aSource);
1178 CanSetResult CanSet(FieldIndex<IDX_AllowContentRetargetingOnChildren>,
1179 const bool& aAllowContentRetargetingOnChildren,
1180 ContentParent* aSource);
1181 CanSetResult CanSet(FieldIndex<IDX_AllowPlugins>, const bool& aAllowPlugins,
1182 ContentParent* aSource);
1183 bool CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>, const bool&,
1184 ContentParent*);
1185 bool CanSet(FieldIndex<IDX_WatchedByDevToolsInternal>,
1186 const bool& aWatchedByDevToolsInternal, ContentParent* aSource);
1188 CanSetResult CanSet(FieldIndex<IDX_DefaultLoadFlags>,
1189 const uint32_t& aDefaultLoadFlags,
1190 ContentParent* aSource);
1191 void DidSet(FieldIndex<IDX_DefaultLoadFlags>);
1193 bool CanSet(FieldIndex<IDX_UseGlobalHistory>, const bool& aUseGlobalHistory,
1194 ContentParent* aSource);
1196 bool CanSet(FieldIndex<IDX_TargetTopLevelLinkClicksToBlankInternal>,
1197 const bool& aTargetTopLevelLinkClicksToBlankInternal,
1198 ContentParent* aSource);
1200 void DidSet(FieldIndex<IDX_HasSessionHistory>, bool aOldValue);
1202 bool CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue,
1203 ContentParent* aSource);
1205 bool CanSet(FieldIndex<IDX_UseErrorPages>, const bool& aUseErrorPages,
1206 ContentParent* aSource);
1208 bool CanSet(FieldIndex<IDX_PendingInitialization>, bool aNewValue,
1209 ContentParent* aSource);
1211 bool CanSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aNewValue,
1212 ContentParent* aSource);
1213 void DidSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aOldValue);
1215 CanSetResult CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
1216 ContentParent* aSource);
1217 void DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue);
1219 bool CanSet(FieldIndex<IDX_ForceDesktopViewport>, bool aValue,
1220 ContentParent* aSource) {
1221 return IsTop() && XRE_IsParentProcess();
1224 // TODO(emilio): Maybe handle the flag being set dynamically without
1225 // navigating? The previous code didn't do it tho, and a reload is probably
1226 // worth it regardless.
1227 // void DidSet(FieldIndex<IDX_ForceDesktopViewport>, bool aOldValue);
1229 bool CanSet(FieldIndex<IDX_HasRestoreData>, bool aNewValue,
1230 ContentParent* aSource);
1232 bool CanSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>,
1233 const bool& aIsUnderHiddenEmbedderElement,
1234 ContentParent* aSource);
1236 bool CanSet(FieldIndex<IDX_ForceOffline>, bool aNewValue,
1237 ContentParent* aSource);
1239 bool CanSet(FieldIndex<IDX_EmbeddedInContentDocument>, bool,
1240 ContentParent* aSource) {
1241 return CheckOnlyEmbedderCanSet(aSource);
1244 template <size_t I, typename T>
1245 bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
1246 return true;
1249 // Overload `DidSet` to get notifications for a particular field being set.
1251 // You can also overload the variant that gets the old value if you need it.
1252 template <size_t I>
1253 void DidSet(FieldIndex<I>) {}
1254 template <size_t I, typename T>
1255 void DidSet(FieldIndex<I>, T&& aOldValue) {}
1257 void DidSet(FieldIndex<IDX_FullZoom>, float aOldValue);
1258 void DidSet(FieldIndex<IDX_TextZoom>, float aOldValue);
1259 void DidSet(FieldIndex<IDX_AuthorStyleDisabledDefault>);
1261 bool CanSet(FieldIndex<IDX_IsInBFCache>, bool, ContentParent* aSource);
1262 void DidSet(FieldIndex<IDX_IsInBFCache>);
1264 void DidSet(FieldIndex<IDX_SyntheticDocumentContainer>);
1266 void DidSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>, bool aOldValue);
1268 // Allow if the process attemping to set field is the same as the owning
1269 // process. Deprecated. New code that might use this should generally be moved
1270 // to WindowContext or be settable only by the parent process.
1271 CanSetResult LegacyRevertIfNotOwningOrParentProcess(ContentParent* aSource);
1273 // True if the process attempting to set field is the same as the embedder's
1274 // process.
1275 bool CheckOnlyEmbedderCanSet(ContentParent* aSource);
1277 void CreateChildSHistory();
1279 using PrincipalWithLoadIdentifierTuple =
1280 std::tuple<nsCOMPtr<nsIPrincipal>, uint64_t>;
1282 nsIPrincipal* GetSavedPrincipal(
1283 Maybe<PrincipalWithLoadIdentifierTuple> aPrincipalTuple);
1285 // Type of BrowsingContent
1286 const Type mType;
1288 // Unique id identifying BrowsingContext
1289 const uint64_t mBrowsingContextId;
1291 RefPtr<BrowsingContextGroup> mGroup;
1292 RefPtr<WindowContext> mParentWindow;
1293 nsCOMPtr<nsIDocShell> mDocShell;
1295 RefPtr<Element> mEmbedderElement;
1297 nsTArray<RefPtr<WindowContext>> mWindowContexts;
1298 RefPtr<WindowContext> mCurrentWindowContext;
1300 // This is not a strong reference, but using a JS::Heap for that should be
1301 // fine. The JSObject stored in here should be a proxy with a
1302 // nsOuterWindowProxy handler, which will update the pointer from its
1303 // objectMoved hook and clear it from its finalize hook.
1304 JS::Heap<JSObject*> mWindowProxy;
1305 LocationProxy mLocation;
1307 // OriginAttributes for this BrowsingContext. May not be changed after this
1308 // BrowsingContext is attached.
1309 OriginAttributes mOriginAttributes;
1311 // The network request context id, representing the nsIRequestContext
1312 // associated with this BrowsingContext, and LoadGroups created for it.
1313 uint64_t mRequestContextId = 0;
1315 // Determines if private browsing should be used. May not be changed after
1316 // this BrowsingContext is attached. This field matches mOriginAttributes in
1317 // content Browsing Contexts. Currently treated as a binary value: 1 - in
1318 // private mode, 0 - not private mode.
1319 uint32_t mPrivateBrowsingId;
1321 // True if Attach() has been called on this BrowsingContext already.
1322 bool mEverAttached : 1;
1324 // Is the most recent Document in this BrowsingContext loaded within this
1325 // process? This may be true with a null mDocShell after the Window has been
1326 // closed.
1327 bool mIsInProcess : 1;
1329 // Has this browsing context been discarded? BrowsingContexts should
1330 // only be discarded once.
1331 bool mIsDiscarded : 1;
1333 // True if this BrowsingContext has no associated visible window, and is owned
1334 // by whichever process created it, even if top-level.
1335 bool mWindowless : 1;
1337 // This is true if the BrowsingContext was out of process, but is now in
1338 // process, and might have remote window proxies that need to be cleaned up.
1339 bool mDanglingRemoteOuterProxies : 1;
1341 // True if this BrowsingContext has been embedded in a element in this
1342 // process.
1343 bool mEmbeddedByThisProcess : 1;
1345 // Determines if remote (out-of-process) tabs should be used. May not be
1346 // changed after this BrowsingContext is attached.
1347 bool mUseRemoteTabs : 1;
1349 // Determines if out-of-process iframes should be used. May not be changed
1350 // after this BrowsingContext is attached.
1351 bool mUseRemoteSubframes : 1;
1353 // True if this BrowsingContext is for a frame that was added dynamically.
1354 bool mCreatedDynamically : 1;
1356 // Set to true if the browsing context is in the bfcache and pagehide has been
1357 // dispatched. When coming out from the bfcache, the value is set to false
1358 // before dispatching pageshow.
1359 bool mIsInBFCache : 1;
1361 // Determines if we can execute scripts in this BrowsingContext. True if
1362 // AllowJavascript() is true and script execution is allowed in the parent
1363 // WindowContext.
1364 bool mCanExecuteScripts : 1;
1366 // The original offset of this context in its container. This property is -1
1367 // if this BrowsingContext is for a frame that was added dynamically.
1368 int32_t mChildOffset;
1370 // The start time of user gesture, this is only available if the browsing
1371 // context is in process.
1372 TimeStamp mUserGestureStart;
1374 // Triggering principal and principal to inherit need to point to original
1375 // principal instances if the document is loaded in the same process as the
1376 // process that initiated the load. When the load starts we save the
1377 // principals along with the current load id.
1378 // These principals correspond to the most recent load that took place within
1379 // the process of this browsing context.
1380 Maybe<PrincipalWithLoadIdentifierTuple> mTriggeringPrincipal;
1381 Maybe<PrincipalWithLoadIdentifierTuple> mPrincipalToInherit;
1383 class DeprioritizedLoadRunner
1384 : public mozilla::Runnable,
1385 public mozilla::LinkedListElement<DeprioritizedLoadRunner> {
1386 public:
1387 explicit DeprioritizedLoadRunner(nsIRunnable* aInner)
1388 : Runnable("DeprioritizedLoadRunner"), mInner(aInner) {}
1390 NS_IMETHOD Run() override {
1391 if (mInner) {
1392 RefPtr<nsIRunnable> inner = std::move(mInner);
1393 inner->Run();
1396 return NS_OK;
1399 private:
1400 RefPtr<nsIRunnable> mInner;
1403 mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
1405 RefPtr<SessionStorageManager> mSessionStorageManager;
1406 RefPtr<ChildSHistory> mChildSessionHistory;
1408 nsTArray<std::function<void(uint64_t)>> mDiscardListeners;
1410 // Counter and time span for rate limiting Location and History API calls.
1411 // Used by CheckLocationChangeRateLimit. Do not apply cross-process.
1412 uint32_t mLocationChangeRateLimitCount;
1413 mozilla::TimeStamp mLocationChangeRateLimitSpanStart;
1415 mozilla::LinkedList<dom::Location> mLocations;
1419 * Gets a WindowProxy object for a BrowsingContext that lives in a different
1420 * process (creating the object if it doesn't already exist). The WindowProxy
1421 * object will be in the compartment that aCx is currently in. This should only
1422 * be called if aContext doesn't hold a docshell, otherwise the BrowsingContext
1423 * lives in this process, and a same-process WindowProxy should be used (see
1424 * nsGlobalWindowOuter). This should only be called by bindings code, ToJSValue
1425 * is the right API to get a WindowProxy for a BrowsingContext.
1427 * If aTransplantTo is non-null, then the WindowProxy object will eventually be
1428 * transplanted onto it. Therefore it should be used as the value in the remote
1429 * proxy map. We assume that in this case the failure is unrecoverable, so we
1430 * crash immediately rather than return false.
1432 extern bool GetRemoteOuterWindowProxy(JSContext* aCx, BrowsingContext* aContext,
1433 JS::Handle<JSObject*> aTransplantTo,
1434 JS::MutableHandle<JSObject*> aRetVal);
1436 using BrowsingContextTransaction = BrowsingContext::BaseTransaction;
1437 using BrowsingContextInitializer = BrowsingContext::IPCInitializer;
1438 using MaybeDiscardedBrowsingContext = MaybeDiscarded<BrowsingContext>;
1440 // Specialize the transaction object for every translation unit it's used in.
1441 extern template class syncedcontext::Transaction<BrowsingContext>;
1443 } // namespace dom
1445 // Allow sending BrowsingContext objects over IPC.
1446 namespace ipc {
1447 template <>
1448 struct IPDLParamTraits<dom::MaybeDiscarded<dom::BrowsingContext>> {
1449 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
1450 const dom::MaybeDiscarded<dom::BrowsingContext>& aParam);
1451 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
1452 dom::MaybeDiscarded<dom::BrowsingContext>* aResult);
1455 template <>
1456 struct IPDLParamTraits<dom::BrowsingContext::IPCInitializer> {
1457 static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
1458 const dom::BrowsingContext::IPCInitializer& aInitializer);
1460 static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
1461 dom::BrowsingContext::IPCInitializer* aInitializer);
1463 } // namespace ipc
1464 } // namespace mozilla
1466 #endif // !defined(mozilla_dom_BrowsingContext_h)