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
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"
28 #include "nsCycleCollectionParticipant.h"
29 #include "nsIDocShell.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
;
40 class nsOuterWindowProxy
;
60 struct IPDLParamTraits
;
64 class BrowsingContent
;
65 class BrowsingContextGroup
;
66 class CanonicalBrowsingContext
;
70 struct LoadingSessionHistoryInfo
;
76 class SessionHistoryInfo
;
77 class SessionStorageManager
;
78 class StructuredCloneHolder
;
80 class WindowGlobalChild
;
81 struct WindowPostMessageOptions
;
82 class WindowProxyHolder
;
84 enum class ExplicitActiveStatus
: uint8_t {
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 \
142 /* Hold the pinned/app-tab state and should be used on top level browsing \
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 \
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(AllowContentRetargeting, bool) \
181 FIELD(AllowContentRetargetingOnChildren, bool) \
182 FIELD(ForceEnableTrackingProtection, bool) \
183 FIELD(UseGlobalHistory, bool) \
184 FIELD(TargetTopLevelLinkClicksToBlankInternal, bool) \
185 FIELD(FullscreenAllowedByOwner, bool) \
186 FIELD(ForceDesktopViewport, bool) \
188 * "is popup" in the spec. \
189 * Set only on top browsing contexts. \
190 * This doesn't indicate whether this is actually a popup or not, \
191 * but whether this browsing context is created by requesting popup or not. \
192 * See also: nsWindowWatcher::ShouldOpenPopup. \
194 FIELD(IsPopupRequested, bool) \
195 /* These field are used to store the states of autoplay media request on \
196 * GeckoView only, and it would only be modified on the top level browsing \
198 FIELD(GVAudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
199 FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
200 /* ScreenOrientation-related APIs */ \
201 FIELD(CurrentOrientationAngle, float) \
202 FIELD(CurrentOrientationType, mozilla::dom::OrientationType) \
203 FIELD(OrientationLock, mozilla::hal::ScreenOrientation) \
204 FIELD(UserAgentOverride, nsString) \
205 FIELD(TouchEventsOverrideInternal, mozilla::dom::TouchEventsOverride) \
206 FIELD(EmbedderElementType, Maybe<nsString>) \
207 FIELD(MessageManagerGroup, nsString) \
208 FIELD(MaxTouchPointsOverride, uint8_t) \
209 FIELD(FullZoom, float) \
210 FIELD(WatchedByDevToolsInternal, bool) \
211 FIELD(TextZoom, float) \
212 FIELD(OverrideDPPX, float) \
213 /* The current in-progress load. */ \
214 FIELD(CurrentLoadIdentifier, Maybe<uint64_t>) \
215 /* See nsIRequest for possible flags. */ \
216 FIELD(DefaultLoadFlags, uint32_t) \
217 /* Signals that session history is enabled for this browsing context tree. \
218 * This is only ever set to true on the top BC, so consumers need to get \
219 * the value from the top BC! */ \
220 FIELD(HasSessionHistory, bool) \
221 /* Tracks if this context is the only top-level document in the session \
222 * history of the context. */ \
223 FIELD(IsSingleToplevelInHistory, bool) \
224 FIELD(UseErrorPages, bool) \
225 FIELD(PlatformOverride, nsString) \
226 /* Specifies if this BC has loaded documents besides the initial \
227 * about:blank document. about:privatebrowsing, about:home, about:newtab \
228 * and non-initial about:blank are not considered to be initial \
230 FIELD(HasLoadedNonInitialDocument, bool) \
231 /* Default value for nsIDocumentViewer::authorStyleDisabled in any new \
232 * browsing contexts created as a descendant of this one. Valid only for \
234 FIELD(AuthorStyleDisabledDefault, bool) \
235 FIELD(ServiceWorkersTestingEnabled, bool) \
236 FIELD(MediumOverride, nsString) \
237 /* DevTools override for prefers-color-scheme */ \
238 FIELD(PrefersColorSchemeOverride, dom::PrefersColorSchemeOverride) \
239 /* prefers-color-scheme override based on the color-scheme style of our \
240 * <browser> embedder element. */ \
241 FIELD(EmbedderColorSchemes, EmbedderColorSchemes) \
242 FIELD(DisplayMode, dom::DisplayMode) \
243 /* The number of entries added to the session history because of this \
244 * browsing context. */ \
245 FIELD(HistoryEntryCount, uint32_t) \
246 /* Don't use the getter of the field, but IsInBFCache() method */ \
247 FIELD(IsInBFCache, bool) \
248 FIELD(HasRestoreData, bool) \
249 FIELD(SessionStoreEpoch, uint32_t) \
250 /* Whether we can execute scripts in this BrowsingContext. Has no effect \
251 * unless scripts are also allowed in the parent WindowContext. */ \
252 FIELD(AllowJavascript, bool) \
253 /* The count of request that are used to prevent the browsing context tree \
254 * from being suspended, which would ONLY be modified on the top level \
255 * context in the chrome process because that's a non-atomic counter */ \
256 FIELD(PageAwakeRequestCount, uint32_t) \
257 /* This field only gets incrememented when we start navigations in the \
258 * parent process. This is used for keeping track of the racing navigations \
259 * between the parent and content processes. */ \
260 FIELD(ParentInitiatedNavigationEpoch, uint64_t) \
261 /* This browsing context is for a synthetic image document wrapping an \
262 * image embedded in <object> or <embed>. */ \
263 FIELD(SyntheticDocumentContainer, bool) \
264 /* If true, this document is embedded within a content document, either \
265 * loaded in the parent (e.g. about:addons or the devtools toolbox), or in \
266 * a content process. */ \
267 FIELD(EmbeddedInContentDocument, bool) \
268 /* If true, this browsing context is within a hidden embedded document. */ \
269 FIELD(IsUnderHiddenEmbedderElement, bool) \
270 /* If true, this browsing context is offline */ \
271 FIELD(ForceOffline, bool)
273 // BrowsingContext, in this context, is the cross process replicated
274 // environment in which information about documents is stored. In
275 // particular the tree structure of nested browsing contexts is
276 // represented by the tree of BrowsingContexts.
278 // The tree of BrowsingContexts is created in step with its
279 // corresponding nsDocShell, and when nsDocShells are connected
280 // through a parent/child relationship, so are BrowsingContexts. The
281 // major difference is that BrowsingContexts are replicated (synced)
282 // to the parent process, making it possible to traverse the
283 // BrowsingContext tree for a tab, in both the parent and the child
286 // Trees of BrowsingContexts should only ever contain nodes of the
287 // same BrowsingContext::Type. This is enforced by asserts in the
288 // BrowsingContext::Create* methods.
289 class BrowsingContext
: public nsILoadContext
, public nsWrapperCache
{
290 MOZ_DECL_SYNCED_CONTEXT(BrowsingContext
, MOZ_EACH_BC_FIELD
)
293 enum class Type
{ Chrome
, Content
};
296 static LogModule
* GetLog();
297 static LogModule
* GetSyncLog();
299 // Look up a BrowsingContext in the current process by ID.
300 static already_AddRefed
<BrowsingContext
> Get(uint64_t aId
);
301 static already_AddRefed
<BrowsingContext
> Get(GlobalObject
&, uint64_t aId
) {
304 // Look up the top-level BrowsingContext by BrowserID.
305 static already_AddRefed
<BrowsingContext
> GetCurrentTopByBrowserId(
306 uint64_t aBrowserId
);
307 static already_AddRefed
<BrowsingContext
> GetCurrentTopByBrowserId(
308 GlobalObject
&, uint64_t aId
) {
309 return GetCurrentTopByBrowserId(aId
);
312 static void UpdateCurrentTopByBrowserId(BrowsingContext
* aNewBrowsingContext
);
314 static already_AddRefed
<BrowsingContext
> GetFromWindow(
315 WindowProxyHolder
& aProxy
);
316 static already_AddRefed
<BrowsingContext
> GetFromWindow(
317 GlobalObject
&, WindowProxyHolder
& aProxy
) {
318 return GetFromWindow(aProxy
);
321 static void DiscardFromContentParent(ContentParent
* aCP
);
323 // Create a brand-new toplevel BrowsingContext with no relationships to other
324 // BrowsingContexts, and which is not embedded within any <browser> or frame
327 // This BrowsingContext is immediately attached, and cannot have LoadContext
328 // flags customized unless it is of `Type::Chrome`.
330 // The process which created this BrowsingContext is responsible for detaching
332 static already_AddRefed
<BrowsingContext
> CreateIndependent(Type aType
);
334 // Create a brand-new BrowsingContext object, but does not immediately attach
335 // it. State such as OriginAttributes and PrivateBrowsingId may be customized
336 // to configure the BrowsingContext before it is attached.
338 // `EnsureAttached()` must be called before the BrowsingContext is used for a
339 // DocShell, BrowserParent, or BrowserBridgeChild.
340 static already_AddRefed
<BrowsingContext
> CreateDetached(
341 nsGlobalWindowInner
* aParent
, BrowsingContext
* aOpener
,
342 BrowsingContextGroup
* aSpecificGroup
, const nsAString
& aName
, Type aType
,
343 bool aIsPopupRequested
, bool aCreatedDynamically
= false);
345 void EnsureAttached();
347 bool EverAttached() const { return mEverAttached
; }
349 // Cast this object to a canonical browsing context, and return it.
350 CanonicalBrowsingContext
* Canonical();
352 // Is the most recent Document in this BrowsingContext loaded within this
353 // process? This may be true with a null mDocShell after the Window has been
355 bool IsInProcess() const { return mIsInProcess
; }
357 bool IsOwnedByProcess() const;
359 bool CanHaveRemoteOuterProxies() const {
360 return !mIsInProcess
|| mDanglingRemoteOuterProxies
;
363 // Has this BrowsingContext been discarded. A discarded browsing context has
364 // been destroyed, and may not be available on the other side of an IPC
366 bool IsDiscarded() const { return mIsDiscarded
; }
368 // Returns true if none of the BrowsingContext's ancestor BrowsingContexts or
369 // WindowContexts are discarded or cached.
370 bool AncestorsAreCurrent() const;
372 bool Windowless() const { return mWindowless
; }
374 // Get the DocShell for this BrowsingContext if it is in-process, or
376 nsIDocShell
* GetDocShell() const { return mDocShell
; }
377 void SetDocShell(nsIDocShell
* aDocShell
);
378 void ClearDocShell() { mDocShell
= nullptr; }
380 // Get the Document for this BrowsingContext if it is in-process, or
382 Document
* GetDocument() const {
383 return mDocShell
? mDocShell
->GetDocument() : nullptr;
385 Document
* GetExtantDocument() const {
386 return mDocShell
? mDocShell
->GetExtantDocument() : nullptr;
389 // This cleans up remote outer window proxies that might have been left behind
390 // when the browsing context went from being remote to local. It does this by
391 // turning them into cross-compartment wrappers to aOuter. If there is already
392 // a remote proxy in the compartment of aOuter, then aOuter will get swapped
393 // to it and the value of aOuter will be set to the object that used to be the
394 // remote proxy and is now an OuterWindowProxy.
395 void CleanUpDanglingRemoteOuterWindowProxies(
396 JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aOuter
);
398 // Get the embedder element for this BrowsingContext if the embedder is
399 // in-process, or null if it's not.
400 Element
* GetEmbedderElement() const { return mEmbedderElement
; }
401 void SetEmbedderElement(Element
* aEmbedder
);
403 // Return true if the type of the embedder element is either object
404 // or embed, false otherwise.
405 bool IsEmbedderTypeObjectOrEmbed();
407 // Called after the BrowingContext has been embedded in a FrameLoader. This
408 // happens after `SetEmbedderElement` is called on the BrowsingContext and
409 // after the BrowsingContext has been set on the FrameLoader.
412 // Get the outer window object for this BrowsingContext if it is in-process
413 // and still has a docshell, or null otherwise.
414 nsPIDOMWindowOuter
* GetDOMWindow() const {
415 return mDocShell
? mDocShell
->GetWindow() : nullptr;
418 uint64_t GetRequestContextId() const { return mRequestContextId
; }
420 // Detach the current BrowsingContext from its parent, in both the
421 // child and the parent process.
422 void Detach(bool aFromIPC
= false);
424 // Prepare this BrowsingContext to leave the current process.
425 void PrepareForProcessChange();
427 // Triggers a load in the process which currently owns this BrowsingContext.
428 nsresult
LoadURI(nsDocShellLoadState
* aLoadState
,
429 bool aSetNavigating
= false);
431 nsresult
InternalLoad(nsDocShellLoadState
* aLoadState
);
433 // Removes the root document for this BrowsingContext tree from the BFCache,
434 // if it is cached, and returns true if it was.
435 bool RemoveRootFromBFCacheSync();
437 // If the load state includes a source BrowsingContext has been passed, check
438 // to see if we are sandboxed from it as the result of an iframe or CSP
440 nsresult
CheckSandboxFlags(nsDocShellLoadState
* aLoadState
);
442 void DisplayLoadError(const nsAString
& aURI
);
444 // Check that this browsing context is targetable for navigations (i.e. that
445 // it is neither closed, cached, nor discarded).
446 bool IsTargetable() const;
448 // True if this browsing context is inactive and is able to be suspended.
449 bool InactiveForSuspend() const;
451 const nsString
& Name() const { return GetName(); }
452 void GetName(nsAString
& aName
) { aName
= GetName(); }
453 bool NameEquals(const nsAString
& aName
) { return GetName().Equals(aName
); }
455 Type
GetType() const { return mType
; }
456 bool IsContent() const { return mType
== Type::Content
; }
457 bool IsChrome() const { return !IsContent(); }
459 bool IsTop() const { return !GetParent(); }
460 bool IsSubframe() const { return !IsTop(); }
462 bool IsTopContent() const { return IsContent() && IsTop(); }
464 bool IsInSubtreeOf(BrowsingContext
* aContext
);
466 bool IsContentSubframe() const { return IsContent() && IsSubframe(); }
469 uint64_t Id() const { return mBrowsingContextId
; }
471 BrowsingContext
* GetParent() const;
472 BrowsingContext
* Top();
473 const BrowsingContext
* Top() const;
475 int32_t IndexOf(BrowsingContext
* aChild
);
477 // NOTE: Unlike `GetEmbedderWindowGlobal`, `GetParentWindowContext` does not
478 // cross toplevel content browser boundaries.
479 WindowContext
* GetParentWindowContext() const { return mParentWindow
; }
480 WindowContext
* GetTopWindowContext() const;
482 already_AddRefed
<BrowsingContext
> GetOpener() const {
483 RefPtr
<BrowsingContext
> opener(Get(GetOpenerId()));
484 if (!mIsDiscarded
&& opener
&& !opener
->mIsDiscarded
) {
485 MOZ_DIAGNOSTIC_ASSERT(opener
->mType
== mType
);
486 return opener
.forget();
490 void SetOpener(BrowsingContext
* aOpener
);
491 bool HasOpener() const;
493 bool HadOriginalOpener() const { return GetHadOriginalOpener(); }
495 // Returns true if the browsing context and top context are same origin
496 bool SameOriginWithTop();
499 * When a new browsing context is opened by a sandboxed document, it needs to
500 * keep track of the browsing context that opened it, so that it can be
501 * navigated by it. This is the "one permitted sandboxed navigator".
503 already_AddRefed
<BrowsingContext
> GetOnePermittedSandboxedNavigator() const {
504 return Get(GetOnePermittedSandboxedNavigatorId());
506 [[nodiscard
]] nsresult
SetOnePermittedSandboxedNavigator(
507 BrowsingContext
* aNavigator
) {
508 if (GetOnePermittedSandboxedNavigatorId()) {
510 "One Permitted Sandboxed Navigator should only be set once.");
511 return NS_ERROR_FAILURE
;
513 return SetOnePermittedSandboxedNavigatorId(aNavigator
? aNavigator
->Id()
518 uint32_t SandboxFlags() const { return GetSandboxFlags(); }
520 Span
<RefPtr
<BrowsingContext
>> Children() const;
521 void GetChildren(nsTArray
<RefPtr
<BrowsingContext
>>& aChildren
);
523 Span
<RefPtr
<BrowsingContext
>> NonSyntheticChildren() const;
525 const nsTArray
<RefPtr
<WindowContext
>>& GetWindowContexts() {
526 return mWindowContexts
;
528 void GetWindowContexts(nsTArray
<RefPtr
<WindowContext
>>& aWindows
);
530 void RegisterWindowContext(WindowContext
* aWindow
);
531 void UnregisterWindowContext(WindowContext
* aWindow
);
532 WindowContext
* GetCurrentWindowContext() const {
533 return mCurrentWindowContext
;
536 // Helpers to traverse this BrowsingContext subtree. Note that these will only
537 // traverse active contexts, and will ignore ones in the BFCache.
538 enum class WalkFlag
{
545 * Walk the browsing context tree in pre-order and call `aCallback`
546 * for every node in the tree. PreOrderWalk accepts two types of
547 * callbacks, either of the type `void(BrowsingContext*)` or
548 * `WalkFlag(BrowsingContext*)`. The former traverses the entire
549 * tree, but the latter let's you control if a sub-tree should be
550 * skipped by returning `WalkFlag::Skip`, completely abort traversal
551 * by returning `WalkFlag::Stop` or continue as normal with
554 template <typename F
>
555 void PreOrderWalk(F
&& aCallback
) {
556 if constexpr (std::is_void_v
<
557 typename
std::invoke_result_t
<F
, BrowsingContext
*>>) {
558 PreOrderWalkVoid(std::forward
<F
>(aCallback
));
560 PreOrderWalkFlag(std::forward
<F
>(aCallback
));
564 void PreOrderWalkVoid(const std::function
<void(BrowsingContext
*)>& aCallback
);
565 WalkFlag
PreOrderWalkFlag(
566 const std::function
<WalkFlag(BrowsingContext
*)>& aCallback
);
568 void PostOrderWalk(const std::function
<void(BrowsingContext
*)>& aCallback
);
570 void GetAllBrowsingContextsInSubtree(
571 nsTArray
<RefPtr
<BrowsingContext
>>& aBrowsingContexts
);
573 BrowsingContextGroup
* Group() { return mGroup
; }
575 // WebIDL bindings for nsILoadContext
576 Nullable
<WindowProxyHolder
> GetAssociatedWindow();
577 Nullable
<WindowProxyHolder
> GetTopWindow();
578 Element
* GetTopFrameElement();
579 bool GetIsContent() { return IsContent(); }
580 void SetUsePrivateBrowsing(bool aUsePrivateBrowsing
, ErrorResult
& aError
);
581 // Needs a different name to disambiguate from the xpidl method with
582 // the same signature but different return value.
583 void SetUseTrackingProtectionWebIDL(bool aUseTrackingProtection
,
585 bool UseTrackingProtectionWebIDL() { return UseTrackingProtection(); }
586 void GetOriginAttributes(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aVal
,
587 ErrorResult
& aError
);
589 bool InRDMPane() const { return GetInRDMPane(); }
591 bool WatchedByDevTools();
592 void SetWatchedByDevTools(bool aWatchedByDevTools
, ErrorResult
& aRv
);
594 dom::TouchEventsOverride
TouchEventsOverride() const;
595 bool TargetTopLevelLinkClicksToBlank() const;
597 bool FullscreenAllowed() const;
599 float FullZoom() const { return GetFullZoom(); }
600 float TextZoom() const { return GetTextZoom(); }
602 float OverrideDPPX() const { return Top()->GetOverrideDPPX(); }
604 bool SuspendMediaWhenInactive() const {
605 return GetSuspendMediaWhenInactive();
608 bool IsActive() const;
609 bool ForceOffline() const { return GetForceOffline(); }
611 bool ForceDesktopViewport() const { return GetForceDesktopViewport(); }
613 bool AuthorStyleDisabledDefault() const {
614 return GetAuthorStyleDisabledDefault();
617 bool UseGlobalHistory() const { return GetUseGlobalHistory(); }
619 bool GetIsActiveBrowserWindow();
621 void SetIsActiveBrowserWindow(bool aActive
);
623 uint64_t BrowserId() const { return GetBrowserId(); }
627 void GetEmbedderElementType(nsString
& aElementType
) {
628 if (GetEmbedderElementType().isSome()) {
629 aElementType
= GetEmbedderElementType().value();
633 bool IsLoadingIdentifier(uint64_t aLoadIdentifer
) {
634 if (GetCurrentLoadIdentifier() &&
635 *GetCurrentLoadIdentifier() == aLoadIdentifer
) {
641 // ScreenOrientation related APIs
642 [[nodiscard
]] nsresult
SetCurrentOrientation(OrientationType aType
,
645 txn
.SetCurrentOrientationType(aType
);
646 txn
.SetCurrentOrientationAngle(aAngle
);
647 return txn
.Commit(this);
650 void SetRDMPaneOrientation(OrientationType aType
, float aAngle
,
653 if (NS_FAILED(SetCurrentOrientation(aType
, aAngle
))) {
654 aRv
.ThrowInvalidStateError("Browsing context is discarded");
659 void SetRDMPaneMaxTouchPoints(uint8_t aMaxTouchPoints
, ErrorResult
& aRv
) {
661 SetMaxTouchPointsOverride(aMaxTouchPoints
, aRv
);
665 // Find a browsing context in this context's list of
666 // children. Doesn't consider the special names, '_self', '_parent',
667 // '_top', or '_blank'. Performs access control checks with regard to
669 BrowsingContext
* FindChildWithName(const nsAString
& aName
,
670 WindowGlobalChild
& aRequestingWindow
);
672 // Find a browsing context in the subtree rooted at 'this' Doesn't
673 // consider the special names, '_self', '_parent', '_top', or
676 // If passed, performs access control checks with regard to
677 // 'aRequestingContext', otherwise performs no access checks.
678 BrowsingContext
* FindWithNameInSubtree(const nsAString
& aName
,
679 WindowGlobalChild
* aRequestingWindow
);
681 // Find the special browsing context if aName is '_self', '_parent',
682 // '_top', but not '_blank'. The latter is handled in FindWithName
683 BrowsingContext
* FindWithSpecialName(const nsAString
& aName
,
684 WindowGlobalChild
& aRequestingWindow
);
686 nsISupports
* GetParentObject() const;
687 JSObject
* WrapObject(JSContext
* aCx
,
688 JS::Handle
<JSObject
*> aGivenProto
) override
;
690 // Return the window proxy object that corresponds to this browsing context.
691 inline JSObject
* GetWindowProxy() const { return mWindowProxy
; }
692 inline JSObject
* GetUnbarrieredWindowProxy() const {
693 return mWindowProxy
.unbarrieredGet();
696 // Set the window proxy object that corresponds to this browsing context.
697 void SetWindowProxy(JS::Handle
<JSObject
*> aWindowProxy
) {
698 mWindowProxy
= aWindowProxy
;
701 Nullable
<WindowProxyHolder
> GetWindow();
703 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
704 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(BrowsingContext
)
705 NS_DECL_NSILOADCONTEXT
707 // Window APIs that are cross-origin-accessible (from the HTML spec).
708 WindowProxyHolder
Window();
709 BrowsingContext
* GetBrowsingContext() { return this; };
710 BrowsingContext
* Self() { return this; }
711 void Location(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aLocation
,
712 ErrorResult
& aError
);
713 void Close(CallerType aCallerType
, ErrorResult
& aError
);
714 bool GetClosed(ErrorResult
&) { return GetClosed(); }
715 void Focus(CallerType aCallerType
, ErrorResult
& aError
);
716 void Blur(CallerType aCallerType
, ErrorResult
& aError
);
717 WindowProxyHolder
GetFrames(ErrorResult
& aError
);
718 int32_t Length() const { return Children().Length(); }
719 Nullable
<WindowProxyHolder
> GetTop(ErrorResult
& aError
);
720 void GetOpener(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aOpener
,
721 ErrorResult
& aError
) const;
722 Nullable
<WindowProxyHolder
> GetParent(ErrorResult
& aError
);
723 void PostMessageMoz(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
724 const nsAString
& aTargetOrigin
,
725 const Sequence
<JSObject
*>& aTransfer
,
726 nsIPrincipal
& aSubjectPrincipal
, ErrorResult
& aError
);
727 void PostMessageMoz(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
728 const WindowPostMessageOptions
& aOptions
,
729 nsIPrincipal
& aSubjectPrincipal
, ErrorResult
& aError
);
731 void GetCustomUserAgent(nsAString
& aUserAgent
) {
732 aUserAgent
= Top()->GetUserAgentOverride();
734 nsresult
SetCustomUserAgent(const nsAString
& aUserAgent
);
735 void SetCustomUserAgent(const nsAString
& aUserAgent
, ErrorResult
& aRv
);
737 void GetCustomPlatform(nsAString
& aPlatform
) {
738 aPlatform
= Top()->GetPlatformOverride();
740 void SetCustomPlatform(const nsAString
& aPlatform
, ErrorResult
& aRv
);
742 JSObject
* WrapObject(JSContext
* aCx
);
744 static JSObject
* ReadStructuredClone(JSContext
* aCx
,
745 JSStructuredCloneReader
* aReader
,
746 StructuredCloneHolder
* aHolder
);
747 bool WriteStructuredClone(JSContext
* aCx
, JSStructuredCloneWriter
* aWriter
,
748 StructuredCloneHolder
* aHolder
);
750 void StartDelayedAutoplayMediaComponents();
752 [[nodiscard
]] nsresult
ResetGVAutoplayRequestStatus();
755 * Information required to initialize a BrowsingContext in another process.
756 * This object may be serialized over IPC.
758 struct IPCInitializer
{
761 // IDs are used for Parent and Opener to allow for this object to be
762 // deserialized before other BrowsingContext in the BrowsingContextGroup
763 // have been initialized.
764 uint64_t mParentId
= 0;
765 already_AddRefed
<WindowContext
> GetParent();
766 already_AddRefed
<BrowsingContext
> GetOpener();
768 uint64_t GetOpenerId() const { return mFields
.Get
<IDX_OpenerId
>(); }
770 bool mWindowless
= false;
771 bool mUseRemoteTabs
= false;
772 bool mUseRemoteSubframes
= false;
773 bool mCreatedDynamically
= false;
774 int32_t mChildOffset
= 0;
775 int32_t mSessionHistoryIndex
= -1;
776 int32_t mSessionHistoryCount
= 0;
777 OriginAttributes mOriginAttributes
;
778 uint64_t mRequestContextId
= 0;
783 // Create an IPCInitializer object for this BrowsingContext.
784 IPCInitializer
GetIPCInitializer();
786 // Create a BrowsingContext object from over IPC.
787 static mozilla::ipc::IPCResult
CreateFromIPC(IPCInitializer
&& aInitializer
,
788 BrowsingContextGroup
* aGroup
,
789 ContentParent
* aOriginProcess
);
791 bool IsSandboxedFrom(BrowsingContext
* aTarget
);
793 // The runnable will be called once there is idle time, or the top level
794 // page has been loaded or if a timeout has fired.
795 // Must be called only on the top level BrowsingContext.
796 void AddDeprioritizedLoadRunner(nsIRunnable
* aRunner
);
798 RefPtr
<SessionStorageManager
> GetSessionStorageManager();
800 // Set PendingInitialization on this BrowsingContext before the context has
802 void InitPendingInitialization(bool aPendingInitialization
) {
803 MOZ_ASSERT(!EverAttached());
804 mFields
.SetWithoutSyncing
<IDX_PendingInitialization
>(
805 aPendingInitialization
);
808 bool CreatedDynamically() const { return mCreatedDynamically
; }
810 // Returns true if this browsing context, or any ancestor to this browsing
811 // context was created dynamically. See also `CreatedDynamically`.
812 bool IsDynamic() const;
814 int32_t ChildOffset() const { return mChildOffset
; }
816 bool GetOffsetPath(nsTArray
<uint32_t>& aPath
) const;
818 const OriginAttributes
& OriginAttributesRef() { return mOriginAttributes
; }
819 nsresult
SetOriginAttributes(const OriginAttributes
& aAttrs
);
821 void GetHistoryID(JSContext
* aCx
, JS::MutableHandle
<JS::Value
> aVal
,
822 ErrorResult
& aError
);
824 // This should only be called on the top browsing context.
825 void InitSessionHistory();
827 // This will only ever return a non-null value if called on the top browsing
829 ChildSHistory
* GetChildSessionHistory();
831 bool CrossOriginIsolated();
833 // Check if it is allowed to open a popup from the current browsing
834 // context or any of its ancestors.
835 bool IsPopupAllowed();
837 // aCurrentURI is only required to be non-null if the load type contains the
838 // nsIWebNavigation::LOAD_FLAGS_IS_REFRESH flag and aInfo is for a refresh to
840 void SessionHistoryCommit(const LoadingSessionHistoryInfo
& aInfo
,
841 uint32_t aLoadType
, nsIURI
* aCurrentURI
,
842 SessionHistoryInfo
* aPreviousActiveEntry
,
843 bool aPersist
, bool aCloneEntryChildren
,
844 bool aChannelExpired
, uint32_t aCacheKey
);
846 // Set a new active entry on this browsing context. This is used for
847 // implementing history.pushState/replaceState and same document navigations.
848 // The new active entry will be linked to the current active entry through
850 // aPreviousScrollPos is the scroll position that needs to be saved on the
851 // previous active entry.
852 // aUpdatedCacheKey is the cache key to set on the new active entry. If
853 // aUpdatedCacheKey is 0 then it will be ignored.
854 void SetActiveSessionHistoryEntry(const Maybe
<nsPoint
>& aPreviousScrollPos
,
855 SessionHistoryInfo
* aInfo
,
857 uint32_t aUpdatedCacheKey
,
858 bool aUpdateLength
= true);
860 // Replace the active entry for this browsing context. This is used for
861 // implementing history.replaceState and same document navigations.
862 void ReplaceActiveSessionHistoryEntry(SessionHistoryInfo
* aInfo
);
864 // Removes dynamic child entries of the active entry.
865 void RemoveDynEntriesFromActiveSessionHistoryEntry();
867 // Removes entries corresponding to this BrowsingContext from session history.
868 void RemoveFromSessionHistory(const nsID
& aChangeID
);
870 void SetTriggeringAndInheritPrincipals(nsIPrincipal
* aTriggeringPrincipal
,
871 nsIPrincipal
* aPrincipalToInherit
,
872 uint64_t aLoadIdentifier
);
874 // Return mTriggeringPrincipal and mPrincipalToInherit if the load id
875 // saved with the principal matches the current load identifier of this BC.
876 std::tuple
<nsCOMPtr
<nsIPrincipal
>, nsCOMPtr
<nsIPrincipal
>>
877 GetTriggeringAndInheritPrincipalsForCurrentLoad();
879 void HistoryGo(int32_t aOffset
, uint64_t aHistoryEpoch
,
880 bool aRequireUserInteraction
, bool aUserActivation
,
881 std::function
<void(Maybe
<int32_t>&&)>&& aResolver
);
883 bool ShouldUpdateSessionHistory(uint32_t aLoadType
);
885 // Checks if we reached the rate limit for calls to Location and History API.
886 // The rate limit is controlled by the
887 // "dom.navigation.locationChangeRateLimit" prefs.
888 // Rate limit applies per BrowsingContext.
889 // Returns NS_OK if we are below the rate limit and increments the counter.
890 // Returns NS_ERROR_DOM_SECURITY_ERR if limit is reached.
891 nsresult
CheckLocationChangeRateLimit(CallerType aCallerType
);
893 void ResetLocationChangeRateLimit();
895 mozilla::dom::DisplayMode
DisplayMode() { return Top()->GetDisplayMode(); }
897 // Returns canFocus, isActive
898 std::tuple
<bool, bool> CanFocusCheck(CallerType aCallerType
);
900 bool CanBlurCheck(CallerType aCallerType
);
902 // Examine the current document state to see if we're in a way that is
903 // typically abused by web designers. The window.open code uses this
904 // routine to determine whether to allow the new window.
905 // Returns a value from the PopupControlState enum.
906 PopupBlocker::PopupControlState
RevisePopupAbuseLevel(
907 PopupBlocker::PopupControlState aControl
);
909 // Get the modifiers associated with the user activation for relevant
910 // documents. The window.open code uses this routine to determine where the
911 // new window should be located.
912 void GetUserActivationModifiersForPopup(
913 UserActivation::Modifiers
* aModifiers
);
915 void IncrementHistoryEntryCountForBrowsingContext();
917 bool ServiceWorkersTestingEnabled() const {
918 return GetServiceWorkersTestingEnabled();
921 void GetMediumOverride(nsAString
& aOverride
) const {
922 aOverride
= GetMediumOverride();
925 dom::PrefersColorSchemeOverride
PrefersColorSchemeOverride() const {
926 return GetPrefersColorSchemeOverride();
929 bool IsInBFCache() const;
931 bool AllowJavascript() const { return GetAllowJavascript(); }
932 bool CanExecuteScripts() const { return mCanExecuteScripts
; }
934 uint32_t DefaultLoadFlags() const { return GetDefaultLoadFlags(); }
936 // When request for page awake, it would increase a count that is used to
937 // prevent whole browsing context tree from being suspended. The request can
938 // be called multiple times. When calling the revoke, it would decrease the
939 // count and once the count reaches to zero, the browsing context tree could
940 // be suspended when the tree is inactive.
941 void RequestForPageAwake();
942 void RevokeForPageAwake();
944 void AddDiscardListener(std::function
<void(uint64_t)>&& aListener
);
946 bool IsAppTab() { return GetIsAppTab(); }
947 bool HasSiblings() { return GetHasSiblings(); }
949 bool IsUnderHiddenEmbedderElement() const {
950 return GetIsUnderHiddenEmbedderElement();
953 void LocationCreated(dom::Location
* aLocation
);
954 void ClearCachedValuesOfLocations();
957 virtual ~BrowsingContext();
958 BrowsingContext(WindowContext
* aParentWindow
, BrowsingContextGroup
* aGroup
,
959 uint64_t aBrowsingContextId
, Type aType
, FieldValues
&& aInit
);
961 void SetChildSHistory(ChildSHistory
* aChildSHistory
);
962 already_AddRefed
<ChildSHistory
> ForgetChildSHistory() {
963 // FIXME Do we need to unset mHasSessionHistory?
964 return mChildSessionHistory
.forget();
967 static bool ShouldAddEntryForRefresh(nsIURI
* aCurrentURI
,
968 const SessionHistoryInfo
& aInfo
);
969 static bool ShouldAddEntryForRefresh(nsIURI
* aCurrentURI
, nsIURI
* aNewURI
,
973 mozilla::ipc::IPCResult
Attach(bool aFromIPC
, ContentParent
* aOriginProcess
);
975 // Recomputes whether we can execute scripts in this BrowsingContext based on
976 // the value of AllowJavascript() and whether scripts are allowed in the
977 // parent WindowContext. Called whenever the AllowJavascript() flag or the
978 // parent WC changes.
979 void RecomputeCanExecuteScripts();
981 // Is it early enough in the BrowsingContext's lifecycle that it is still
982 // OK to set OriginAttributes?
983 bool CanSetOriginAttributes();
985 void AssertOriginAttributesMatchPrivateBrowsing();
987 // Assert that the BrowsingContext's LoadContext flags appear coherent
988 // relative to related BrowsingContexts.
989 void AssertCoherentLoadContext();
991 friend class ::nsOuterWindowProxy
;
992 friend class ::nsGlobalWindowOuter
;
993 friend class WindowContext
;
995 // Update the window proxy object that corresponds to this browsing context.
996 // This should be called from the window proxy object's objectMoved hook, if
997 // the object mWindowProxy points to was moved by the JS GC.
998 void UpdateWindowProxy(JSObject
* obj
, JSObject
* old
) {
1000 MOZ_ASSERT(mWindowProxy
== old
);
1004 // Clear the window proxy object that corresponds to this browsing context.
1005 // This should be called if the window proxy object is finalized, or it can't
1006 // reach its browsing context anymore.
1007 void ClearWindowProxy() { mWindowProxy
= nullptr; }
1009 friend class Location
;
1010 friend class RemoteLocationProxy
;
1012 * LocationProxy is the class for the native object stored as a private in a
1013 * RemoteLocationProxy proxy representing a Location object in a different
1014 * process. It forwards all operations to its BrowsingContext and aggregates
1015 * its refcount to that BrowsingContext.
1017 class LocationProxy final
: public LocationBase
{
1019 MozExternalRefCountType
AddRef() { return GetBrowsingContext()->AddRef(); }
1020 MozExternalRefCountType
Release() {
1021 return GetBrowsingContext()->Release();
1025 friend class RemoteLocationProxy
;
1026 BrowsingContext
* GetBrowsingContext() override
{
1027 return reinterpret_cast<BrowsingContext
*>(
1028 uintptr_t(this) - offsetof(BrowsingContext
, mLocation
));
1031 nsIDocShell
* GetDocShell() override
{ return nullptr; }
1034 // Send a given `BaseTransaction` object to the correct remote.
1035 void SendCommitTransaction(ContentParent
* aParent
,
1036 const BaseTransaction
& aTxn
, uint64_t aEpoch
);
1037 void SendCommitTransaction(ContentChild
* aChild
, const BaseTransaction
& aTxn
,
1040 bool CanSet(FieldIndex
<IDX_SessionStoreEpoch
>, uint32_t aEpoch
,
1041 ContentParent
* aSource
) {
1042 return IsTop() && !aSource
;
1045 void DidSet(FieldIndex
<IDX_SessionStoreEpoch
>, uint32_t aOldValue
);
1047 using CanSetResult
= syncedcontext::CanSetResult
;
1049 // Ensure that opener is in the same BrowsingContextGroup.
1050 bool CanSet(FieldIndex
<IDX_OpenerId
>, const uint64_t& aValue
,
1051 ContentParent
* aSource
) {
1053 RefPtr
<BrowsingContext
> opener
= Get(aValue
);
1054 return opener
&& opener
->Group() == Group();
1059 bool CanSet(FieldIndex
<IDX_OpenerPolicy
>,
1060 nsILoadInfo::CrossOriginOpenerPolicy
, ContentParent
*);
1062 bool CanSet(FieldIndex
<IDX_ServiceWorkersTestingEnabled
>, bool,
1067 bool CanSet(FieldIndex
<IDX_MediumOverride
>, const nsString
&, ContentParent
*) {
1071 bool CanSet(FieldIndex
<IDX_EmbedderColorSchemes
>, const EmbedderColorSchemes
&,
1072 ContentParent
* aSource
) {
1073 return CheckOnlyEmbedderCanSet(aSource
);
1076 bool CanSet(FieldIndex
<IDX_PrefersColorSchemeOverride
>,
1077 dom::PrefersColorSchemeOverride
, ContentParent
*) {
1081 void DidSet(FieldIndex
<IDX_InRDMPane
>, bool aOldValue
);
1083 void DidSet(FieldIndex
<IDX_EmbedderColorSchemes
>,
1084 EmbedderColorSchemes
&& aOldValue
);
1086 void DidSet(FieldIndex
<IDX_PrefersColorSchemeOverride
>,
1087 dom::PrefersColorSchemeOverride aOldValue
);
1089 template <typename Callback
>
1090 void WalkPresContexts(Callback
&&);
1091 void PresContextAffectingFieldChanged();
1093 void DidSet(FieldIndex
<IDX_MediumOverride
>, nsString
&& aOldValue
);
1095 bool CanSet(FieldIndex
<IDX_SuspendMediaWhenInactive
>, bool, ContentParent
*) {
1099 bool CanSet(FieldIndex
<IDX_TouchEventsOverrideInternal
>,
1100 dom::TouchEventsOverride aTouchEventsOverride
,
1101 ContentParent
* aSource
);
1102 void DidSet(FieldIndex
<IDX_TouchEventsOverrideInternal
>,
1103 dom::TouchEventsOverride
&& aOldValue
);
1105 bool CanSet(FieldIndex
<IDX_DisplayMode
>, const enum DisplayMode
& aDisplayMode
,
1106 ContentParent
* aSource
) {
1110 void DidSet(FieldIndex
<IDX_DisplayMode
>, enum DisplayMode aOldValue
);
1112 bool CanSet(FieldIndex
<IDX_ExplicitActive
>, const ExplicitActiveStatus
&,
1113 ContentParent
* aSource
);
1114 void DidSet(FieldIndex
<IDX_ExplicitActive
>, ExplicitActiveStatus aOldValue
);
1116 bool CanSet(FieldIndex
<IDX_IsActiveBrowserWindowInternal
>, const bool& aValue
,
1117 ContentParent
* aSource
);
1118 void DidSet(FieldIndex
<IDX_IsActiveBrowserWindowInternal
>, bool aOldValue
);
1120 // Ensure that we only set the flag on the top level browsingContext.
1121 // And then, we do a pre-order walk in the tree to refresh the
1122 // volume of all media elements.
1123 void DidSet(FieldIndex
<IDX_Muted
>);
1125 bool CanSet(FieldIndex
<IDX_IsAppTab
>, const bool& aValue
,
1126 ContentParent
* aSource
);
1128 bool CanSet(FieldIndex
<IDX_HasSiblings
>, const bool& aValue
,
1129 ContentParent
* aSource
);
1131 bool CanSet(FieldIndex
<IDX_ShouldDelayMediaFromStart
>, const bool& aValue
,
1132 ContentParent
* aSource
);
1133 void DidSet(FieldIndex
<IDX_ShouldDelayMediaFromStart
>, bool aOldValue
);
1135 bool CanSet(FieldIndex
<IDX_OverrideDPPX
>, const float& aValue
,
1136 ContentParent
* aSource
);
1137 void DidSet(FieldIndex
<IDX_OverrideDPPX
>, float aOldValue
);
1139 bool CanSet(FieldIndex
<IDX_EmbedderInnerWindowId
>, const uint64_t& aValue
,
1140 ContentParent
* aSource
);
1142 CanSetResult
CanSet(FieldIndex
<IDX_CurrentInnerWindowId
>,
1143 const uint64_t& aValue
, ContentParent
* aSource
);
1145 void DidSet(FieldIndex
<IDX_CurrentInnerWindowId
>);
1147 bool CanSet(FieldIndex
<IDX_ParentInitiatedNavigationEpoch
>,
1148 const uint64_t& aValue
, ContentParent
* aSource
);
1150 bool CanSet(FieldIndex
<IDX_IsPopupSpam
>, const bool& aValue
,
1151 ContentParent
* aSource
);
1153 void DidSet(FieldIndex
<IDX_IsPopupSpam
>);
1155 void DidSet(FieldIndex
<IDX_GVAudibleAutoplayRequestStatus
>);
1156 void DidSet(FieldIndex
<IDX_GVInaudibleAutoplayRequestStatus
>);
1158 void DidSet(FieldIndex
<IDX_Loading
>);
1160 void DidSet(FieldIndex
<IDX_AncestorLoading
>);
1162 void DidSet(FieldIndex
<IDX_PlatformOverride
>);
1163 CanSetResult
CanSet(FieldIndex
<IDX_PlatformOverride
>,
1164 const nsString
& aPlatformOverride
,
1165 ContentParent
* aSource
);
1167 void DidSet(FieldIndex
<IDX_UserAgentOverride
>);
1168 CanSetResult
CanSet(FieldIndex
<IDX_UserAgentOverride
>,
1169 const nsString
& aUserAgent
, ContentParent
* aSource
);
1170 bool CanSet(FieldIndex
<IDX_OrientationLock
>,
1171 const mozilla::hal::ScreenOrientation
& aOrientationLock
,
1172 ContentParent
* aSource
);
1174 bool CanSet(FieldIndex
<IDX_EmbedderElementType
>,
1175 const Maybe
<nsString
>& aInitiatorType
, ContentParent
* aSource
);
1177 bool CanSet(FieldIndex
<IDX_MessageManagerGroup
>,
1178 const nsString
& aMessageManagerGroup
, ContentParent
* aSource
);
1180 CanSetResult
CanSet(FieldIndex
<IDX_AllowContentRetargeting
>,
1181 const bool& aAllowContentRetargeting
,
1182 ContentParent
* aSource
);
1183 CanSetResult
CanSet(FieldIndex
<IDX_AllowContentRetargetingOnChildren
>,
1184 const bool& aAllowContentRetargetingOnChildren
,
1185 ContentParent
* aSource
);
1186 bool CanSet(FieldIndex
<IDX_FullscreenAllowedByOwner
>, const bool&,
1188 bool CanSet(FieldIndex
<IDX_WatchedByDevToolsInternal
>,
1189 const bool& aWatchedByDevToolsInternal
, ContentParent
* aSource
);
1191 CanSetResult
CanSet(FieldIndex
<IDX_DefaultLoadFlags
>,
1192 const uint32_t& aDefaultLoadFlags
,
1193 ContentParent
* aSource
);
1194 void DidSet(FieldIndex
<IDX_DefaultLoadFlags
>);
1196 bool CanSet(FieldIndex
<IDX_UseGlobalHistory
>, const bool& aUseGlobalHistory
,
1197 ContentParent
* aSource
);
1199 bool CanSet(FieldIndex
<IDX_TargetTopLevelLinkClicksToBlankInternal
>,
1200 const bool& aTargetTopLevelLinkClicksToBlankInternal
,
1201 ContentParent
* aSource
);
1203 void DidSet(FieldIndex
<IDX_HasSessionHistory
>, bool aOldValue
);
1205 bool CanSet(FieldIndex
<IDX_BrowserId
>, const uint32_t& aValue
,
1206 ContentParent
* aSource
);
1208 bool CanSet(FieldIndex
<IDX_UseErrorPages
>, const bool& aUseErrorPages
,
1209 ContentParent
* aSource
);
1211 bool CanSet(FieldIndex
<IDX_PendingInitialization
>, bool aNewValue
,
1212 ContentParent
* aSource
);
1214 bool CanSet(FieldIndex
<IDX_PageAwakeRequestCount
>, uint32_t aNewValue
,
1215 ContentParent
* aSource
);
1216 void DidSet(FieldIndex
<IDX_PageAwakeRequestCount
>, uint32_t aOldValue
);
1218 CanSetResult
CanSet(FieldIndex
<IDX_AllowJavascript
>, bool aValue
,
1219 ContentParent
* aSource
);
1220 void DidSet(FieldIndex
<IDX_AllowJavascript
>, bool aOldValue
);
1222 bool CanSet(FieldIndex
<IDX_ForceDesktopViewport
>, bool aValue
,
1223 ContentParent
* aSource
) {
1224 return IsTop() && XRE_IsParentProcess();
1227 // TODO(emilio): Maybe handle the flag being set dynamically without
1228 // navigating? The previous code didn't do it tho, and a reload is probably
1229 // worth it regardless.
1230 // void DidSet(FieldIndex<IDX_ForceDesktopViewport>, bool aOldValue);
1232 bool CanSet(FieldIndex
<IDX_HasRestoreData
>, bool aNewValue
,
1233 ContentParent
* aSource
);
1235 bool CanSet(FieldIndex
<IDX_IsUnderHiddenEmbedderElement
>,
1236 const bool& aIsUnderHiddenEmbedderElement
,
1237 ContentParent
* aSource
);
1239 bool CanSet(FieldIndex
<IDX_ForceOffline
>, bool aNewValue
,
1240 ContentParent
* aSource
);
1242 bool CanSet(FieldIndex
<IDX_EmbeddedInContentDocument
>, bool,
1243 ContentParent
* aSource
) {
1244 return CheckOnlyEmbedderCanSet(aSource
);
1247 template <size_t I
, typename T
>
1248 bool CanSet(FieldIndex
<I
>, const T
&, ContentParent
*) {
1252 // Overload `DidSet` to get notifications for a particular field being set.
1254 // You can also overload the variant that gets the old value if you need it.
1256 void DidSet(FieldIndex
<I
>) {}
1257 template <size_t I
, typename T
>
1258 void DidSet(FieldIndex
<I
>, T
&& aOldValue
) {}
1260 void DidSet(FieldIndex
<IDX_FullZoom
>, float aOldValue
);
1261 void DidSet(FieldIndex
<IDX_TextZoom
>, float aOldValue
);
1262 void DidSet(FieldIndex
<IDX_AuthorStyleDisabledDefault
>);
1264 bool CanSet(FieldIndex
<IDX_IsInBFCache
>, bool, ContentParent
* aSource
);
1265 void DidSet(FieldIndex
<IDX_IsInBFCache
>);
1267 void DidSet(FieldIndex
<IDX_SyntheticDocumentContainer
>);
1269 void DidSet(FieldIndex
<IDX_IsUnderHiddenEmbedderElement
>, bool aOldValue
);
1271 // Allow if the process attemping to set field is the same as the owning
1272 // process. Deprecated. New code that might use this should generally be moved
1273 // to WindowContext or be settable only by the parent process.
1274 CanSetResult
LegacyRevertIfNotOwningOrParentProcess(ContentParent
* aSource
);
1276 // True if the process attempting to set field is the same as the embedder's
1278 bool CheckOnlyEmbedderCanSet(ContentParent
* aSource
);
1280 void CreateChildSHistory();
1282 using PrincipalWithLoadIdentifierTuple
=
1283 std::tuple
<nsCOMPtr
<nsIPrincipal
>, uint64_t>;
1285 nsIPrincipal
* GetSavedPrincipal(
1286 Maybe
<PrincipalWithLoadIdentifierTuple
> aPrincipalTuple
);
1288 // Type of BrowsingContent
1291 // Unique id identifying BrowsingContext
1292 const uint64_t mBrowsingContextId
;
1294 RefPtr
<BrowsingContextGroup
> mGroup
;
1295 RefPtr
<WindowContext
> mParentWindow
;
1296 nsCOMPtr
<nsIDocShell
> mDocShell
;
1298 RefPtr
<Element
> mEmbedderElement
;
1300 nsTArray
<RefPtr
<WindowContext
>> mWindowContexts
;
1301 RefPtr
<WindowContext
> mCurrentWindowContext
;
1303 // This is not a strong reference, but using a JS::Heap for that should be
1304 // fine. The JSObject stored in here should be a proxy with a
1305 // nsOuterWindowProxy handler, which will update the pointer from its
1306 // objectMoved hook and clear it from its finalize hook.
1307 JS::Heap
<JSObject
*> mWindowProxy
;
1308 LocationProxy mLocation
;
1310 // OriginAttributes for this BrowsingContext. May not be changed after this
1311 // BrowsingContext is attached.
1312 OriginAttributes mOriginAttributes
;
1314 // The network request context id, representing the nsIRequestContext
1315 // associated with this BrowsingContext, and LoadGroups created for it.
1316 uint64_t mRequestContextId
= 0;
1318 // Determines if private browsing should be used. May not be changed after
1319 // this BrowsingContext is attached. This field matches mOriginAttributes in
1320 // content Browsing Contexts. Currently treated as a binary value: 1 - in
1321 // private mode, 0 - not private mode.
1322 uint32_t mPrivateBrowsingId
;
1324 // True if Attach() has been called on this BrowsingContext already.
1325 bool mEverAttached
: 1;
1327 // Is the most recent Document in this BrowsingContext loaded within this
1328 // process? This may be true with a null mDocShell after the Window has been
1330 bool mIsInProcess
: 1;
1332 // Has this browsing context been discarded? BrowsingContexts should
1333 // only be discarded once.
1334 bool mIsDiscarded
: 1;
1336 // True if this BrowsingContext has no associated visible window, and is owned
1337 // by whichever process created it, even if top-level.
1338 bool mWindowless
: 1;
1340 // This is true if the BrowsingContext was out of process, but is now in
1341 // process, and might have remote window proxies that need to be cleaned up.
1342 bool mDanglingRemoteOuterProxies
: 1;
1344 // True if this BrowsingContext has been embedded in a element in this
1346 bool mEmbeddedByThisProcess
: 1;
1348 // Determines if remote (out-of-process) tabs should be used. May not be
1349 // changed after this BrowsingContext is attached.
1350 bool mUseRemoteTabs
: 1;
1352 // Determines if out-of-process iframes should be used. May not be changed
1353 // after this BrowsingContext is attached.
1354 bool mUseRemoteSubframes
: 1;
1356 // True if this BrowsingContext is for a frame that was added dynamically.
1357 bool mCreatedDynamically
: 1;
1359 // Set to true if the browsing context is in the bfcache and pagehide has been
1360 // dispatched. When coming out from the bfcache, the value is set to false
1361 // before dispatching pageshow.
1362 bool mIsInBFCache
: 1;
1364 // Determines if we can execute scripts in this BrowsingContext. True if
1365 // AllowJavascript() is true and script execution is allowed in the parent
1367 bool mCanExecuteScripts
: 1;
1369 // The original offset of this context in its container. This property is -1
1370 // if this BrowsingContext is for a frame that was added dynamically.
1371 int32_t mChildOffset
;
1373 // The start time of user gesture, this is only available if the browsing
1374 // context is in process.
1375 TimeStamp mUserGestureStart
;
1377 // Triggering principal and principal to inherit need to point to original
1378 // principal instances if the document is loaded in the same process as the
1379 // process that initiated the load. When the load starts we save the
1380 // principals along with the current load id.
1381 // These principals correspond to the most recent load that took place within
1382 // the process of this browsing context.
1383 Maybe
<PrincipalWithLoadIdentifierTuple
> mTriggeringPrincipal
;
1384 Maybe
<PrincipalWithLoadIdentifierTuple
> mPrincipalToInherit
;
1386 class DeprioritizedLoadRunner
1387 : public mozilla::Runnable
,
1388 public mozilla::LinkedListElement
<DeprioritizedLoadRunner
> {
1390 explicit DeprioritizedLoadRunner(nsIRunnable
* aInner
)
1391 : Runnable("DeprioritizedLoadRunner"), mInner(aInner
) {}
1393 NS_IMETHOD
Run() override
{
1395 RefPtr
<nsIRunnable
> inner
= std::move(mInner
);
1403 RefPtr
<nsIRunnable
> mInner
;
1406 mozilla::LinkedList
<DeprioritizedLoadRunner
> mDeprioritizedLoadRunner
;
1408 RefPtr
<SessionStorageManager
> mSessionStorageManager
;
1409 RefPtr
<ChildSHistory
> mChildSessionHistory
;
1411 nsTArray
<std::function
<void(uint64_t)>> mDiscardListeners
;
1413 // Counter and time span for rate limiting Location and History API calls.
1414 // Used by CheckLocationChangeRateLimit. Do not apply cross-process.
1415 uint32_t mLocationChangeRateLimitCount
;
1416 mozilla::TimeStamp mLocationChangeRateLimitSpanStart
;
1418 mozilla::LinkedList
<dom::Location
> mLocations
;
1422 * Gets a WindowProxy object for a BrowsingContext that lives in a different
1423 * process (creating the object if it doesn't already exist). The WindowProxy
1424 * object will be in the compartment that aCx is currently in. This should only
1425 * be called if aContext doesn't hold a docshell, otherwise the BrowsingContext
1426 * lives in this process, and a same-process WindowProxy should be used (see
1427 * nsGlobalWindowOuter). This should only be called by bindings code, ToJSValue
1428 * is the right API to get a WindowProxy for a BrowsingContext.
1430 * If aTransplantTo is non-null, then the WindowProxy object will eventually be
1431 * transplanted onto it. Therefore it should be used as the value in the remote
1432 * proxy map. We assume that in this case the failure is unrecoverable, so we
1433 * crash immediately rather than return false.
1435 extern bool GetRemoteOuterWindowProxy(JSContext
* aCx
, BrowsingContext
* aContext
,
1436 JS::Handle
<JSObject
*> aTransplantTo
,
1437 JS::MutableHandle
<JSObject
*> aRetVal
);
1439 using BrowsingContextTransaction
= BrowsingContext::BaseTransaction
;
1440 using BrowsingContextInitializer
= BrowsingContext::IPCInitializer
;
1441 using MaybeDiscardedBrowsingContext
= MaybeDiscarded
<BrowsingContext
>;
1443 // Specialize the transaction object for every translation unit it's used in.
1444 extern template class syncedcontext::Transaction
<BrowsingContext
>;
1448 // Allow sending BrowsingContext objects over IPC.
1451 struct IPDLParamTraits
<dom::MaybeDiscarded
<dom::BrowsingContext
>> {
1452 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
1453 const dom::MaybeDiscarded
<dom::BrowsingContext
>& aParam
);
1454 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
1455 dom::MaybeDiscarded
<dom::BrowsingContext
>* aResult
);
1459 struct IPDLParamTraits
<dom::BrowsingContext::IPCInitializer
> {
1460 static void Write(IPC::MessageWriter
* aWriter
, IProtocol
* aActor
,
1461 const dom::BrowsingContext::IPCInitializer
& aInitializer
);
1463 static bool Read(IPC::MessageReader
* aReader
, IProtocol
* aActor
,
1464 dom::BrowsingContext::IPCInitializer
* aInitializer
);
1467 } // namespace mozilla
1469 #endif // !defined(mozilla_dom_BrowsingContext_h)