tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BrowsingContext.h (72790B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_BrowsingContext_h
      8 #define mozilla_dom_BrowsingContext_h
      9 
     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"
     18 
     19 #include "mozilla/dom/BindingDeclarations.h"
     20 #include "mozilla/dom/LocationBase.h"
     21 #include "mozilla/dom/MaybeDiscarded.h"
     22 #include "mozilla/dom/NavigationBinding.h"
     23 #include "mozilla/dom/PopupBlocker.h"
     24 #include "mozilla/dom/UserActivation.h"
     25 #include "mozilla/dom/BrowsingContextBinding.h"
     26 #include "mozilla/dom/ScreenOrientationBinding.h"
     27 #include "mozilla/dom/SyncedContext.h"
     28 #include "nsCOMPtr.h"
     29 #include "nsCycleCollectionParticipant.h"
     30 #include "nsIDocShell.h"
     31 #include "nsTArray.h"
     32 #include "nsWrapperCache.h"
     33 #include "nsILoadInfo.h"
     34 #include "nsILoadContext.h"
     35 #include "nsThreadUtils.h"
     36 #include "nsIDOMGeoPosition.h"
     37 
     38 class nsDocShellLoadState;
     39 class nsGeolocationService;
     40 class nsGlobalWindowInner;
     41 class nsGlobalWindowOuter;
     42 class nsIPrincipal;
     43 class nsOuterWindowProxy;
     44 struct nsPoint;
     45 class PickleIterator;
     46 
     47 namespace IPC {
     48 class Message;
     49 class MessageReader;
     50 class MessageWriter;
     51 template <typename T>
     52 struct ParamTraits;
     53 }  // namespace IPC
     54 
     55 namespace mozilla {
     56 
     57 class ErrorResult;
     58 class LogModule;
     59 
     60 namespace ipc {
     61 class IProtocol;
     62 class IPCResult;
     63 }  // namespace ipc
     64 
     65 namespace dom {
     66 class BrowsingContent;
     67 class BrowsingContextGroup;
     68 class CanonicalBrowsingContext;
     69 class ChildSHistory;
     70 class ContentParent;
     71 class Element;
     72 struct LoadingSessionHistoryInfo;
     73 class Location;
     74 template <typename>
     75 struct Nullable;
     76 template <typename T>
     77 class Sequence;
     78 class SessionHistoryInfo;
     79 class SessionStorageManager;
     80 class StructuredCloneHolder;
     81 struct NavigationAPIMethodTracker;
     82 class WindowContext;
     83 class WindowGlobalChild;
     84 struct WindowPostMessageOptions;
     85 class WindowProxyHolder;
     86 
     87 enum class ExplicitActiveStatus : uint8_t {
     88  None,
     89  Active,
     90  Inactive,
     91  EndGuard_,
     92 };
     93 
     94 struct EmbedderColorSchemes {
     95  PrefersColorSchemeOverride mUsed{};
     96  PrefersColorSchemeOverride mPreferred{};
     97 
     98  bool operator==(const EmbedderColorSchemes& aOther) const {
     99    return mUsed == aOther.mUsed && mPreferred == aOther.mPreferred;
    100  }
    101 
    102  bool operator!=(const EmbedderColorSchemes& aOther) const {
    103    return !(*this == aOther);
    104  }
    105 };
    106 
    107 // Fields are, by default, settable by any process and readable by any process.
    108 // Racy sets will be resolved as-if they occurred in the order the parent
    109 // process finds out about them.
    110 //
    111 // The `DidSet` and `CanSet` methods may be overloaded to provide different
    112 // behavior for a specific field.
    113 //  * `DidSet` is called to run code in every process whenever the value is
    114 //    updated (This currently occurs even if the value didn't change, though
    115 //    this may change in the future).
    116 //  * `CanSet` is called before attempting to set the value, in both the process
    117 //    which calls `Set`, and the parent process, and will kill the misbehaving
    118 //    process if it fails.
    119 #define MOZ_EACH_BC_FIELD(FIELD)                                              \
    120  FIELD(Name, nsString)                                                       \
    121  FIELD(Closed, bool)                                                         \
    122  FIELD(ExplicitActive, ExplicitActiveStatus)                                 \
    123  /* Top()-only. If true, new-playing media will be suspended when in an      \
    124   * inactive browsing context. */                                            \
    125  FIELD(SuspendMediaWhenInactive, bool)                                       \
    126  /* If true, we're within the nested event loop in window.open, and this     \
    127   * context may not be used as the target of a load */                       \
    128  FIELD(PendingInitialization, bool)                                          \
    129  /* Indicates if the browser window is active for the purpose of the         \
    130   * :-moz-window-inactive pseudoclass. Only read from or set on the          \
    131   * top BrowsingContext. */                                                  \
    132  FIELD(IsActiveBrowserWindowInternal, bool)                                  \
    133  FIELD(OpenerPolicy, nsILoadInfo::CrossOriginOpenerPolicy)                   \
    134  /* Current opener for the BrowsingContext. Weak reference */                \
    135  FIELD(OpenerId, uint64_t)                                                   \
    136  FIELD(OnePermittedSandboxedNavigatorId, uint64_t)                           \
    137  /* WindowID of the inner window which embeds this BC */                     \
    138  FIELD(EmbedderInnerWindowId, uint64_t)                                      \
    139  FIELD(CurrentInnerWindowId, uint64_t)                                       \
    140  FIELD(HadOriginalOpener, bool)                                              \
    141  /* Was this window created by a webpage through window.open or an anchor    \
    142   * link? In general, windows created this way may be manipulated (e.g.      \
    143   * closed, resized or moved) by content JS. */                              \
    144  FIELD(TopLevelCreatedByWebContent, bool)                                    \
    145  FIELD(IsPopupSpam, bool)                                                    \
    146  /* Hold the audio muted state and should be used on top level browsing      \
    147   * contexts only */                                                         \
    148  FIELD(Muted, bool)                                                          \
    149  /* Hold the pinned/app-tab state and should be used on top level browsing   \
    150   * contexts only */                                                         \
    151  FIELD(IsAppTab, bool)                                                       \
    152  /* Whether this is a captive portal tab. Should be used on top level        \
    153   * browsing contexts only */                                                \
    154  FIELD(IsCaptivePortalTab, bool)                                             \
    155  /* Whether there's more than 1 tab / toplevel browsing context in this      \
    156   * parent window. Used to determine if a given BC is allowed to resize      \
    157   * and/or move the window or not. */                                        \
    158  FIELD(HasSiblings, bool)                                                    \
    159  /* Indicate that whether we should delay media playback, which would only   \
    160     be done on an unvisited tab. And this should only be used on the top     \
    161     level browsing contexts */                                               \
    162  FIELD(ShouldDelayMediaFromStart, bool)                                      \
    163  /* See nsSandboxFlags.h for the possible flags. */                          \
    164  FIELD(SandboxFlags, uint32_t)                                               \
    165  /* The value of SandboxFlags when the BrowsingContext is first created.     \
    166   * Used for sandboxing the initial about:blank document. */                 \
    167  FIELD(InitialSandboxFlags, uint32_t)                                        \
    168  /* A non-zero unique identifier for the browser element that is hosting     \
    169   * this                                                                     \
    170   * BrowsingContext tree. Every BrowsingContext in the element's tree will   \
    171   * return the same ID in all processes and it will remain stable            \
    172   * regardless of process changes. When a browser element's frameloader is   \
    173   * switched to another browser element this ID will remain the same but     \
    174   * hosted under the under the new browser element. */                       \
    175  FIELD(BrowserId, uint64_t)                                                  \
    176  FIELD(HistoryID, nsID)                                                      \
    177  FIELD(InRDMPane, bool)                                                      \
    178  FIELD(Loading, bool)                                                        \
    179  /* A field only set on top browsing contexts, which indicates that either:  \
    180   *                                                                          \
    181   *  * This is a browsing context created explicitly for printing or print   \
    182   *    preview (thus hosting static documents).                              \
    183   *                                                                          \
    184   *  * This is a browsing context where something in this tree is calling    \
    185   *    window.print() (and thus showing a modal dialog).                     \
    186   *                                                                          \
    187   * We use it exclusively to block navigation for both of these cases. */    \
    188  FIELD(IsPrinting, bool)                                                     \
    189  FIELD(AncestorLoading, bool)                                                \
    190  FIELD(AllowContentRetargeting, bool)                                        \
    191  FIELD(AllowContentRetargetingOnChildren, bool)                              \
    192  FIELD(ForceEnableTrackingProtection, bool)                                  \
    193  FIELD(UseGlobalHistory, bool)                                               \
    194  FIELD(TargetTopLevelLinkClicksToBlankInternal, bool)                        \
    195  FIELD(FullscreenAllowedByOwner, bool)                                       \
    196  FIELD(ForceDesktopViewport, bool)                                           \
    197  /*                                                                          \
    198   * "is popup" in the spec.                                                  \
    199   * Set only on top browsing contexts.                                       \
    200   * This doesn't indicate whether this is actually a popup or not,           \
    201   * but whether this browsing context is created by requesting popup or not. \
    202   * See also: nsWindowWatcher::ShouldOpenPopup.                              \
    203   */                                                                         \
    204  FIELD(IsPopupRequested, bool)                                               \
    205  /* These field are used to store the states of autoplay media request on    \
    206   * GeckoView only, and it would only be modified on the top level browsing  \
    207   * context. */                                                              \
    208  FIELD(GVAudibleAutoplayRequestStatus, GVAutoplayRequestStatus)              \
    209  FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus)            \
    210  FIELD(ScreenHeightOverride, uint64_t)                                       \
    211  FIELD(ScreenWidthOverride, uint64_t)                                        \
    212  FIELD(HasScreenAreaOverride, bool)                                          \
    213  /* ScreenOrientation-related APIs */                                        \
    214  FIELD(CurrentOrientationAngle, float)                                       \
    215  FIELD(CurrentOrientationType, mozilla::dom::OrientationType)                \
    216  FIELD(OrientationLock, mozilla::hal::ScreenOrientation)                     \
    217  FIELD(HasOrientationOverride, bool)                                         \
    218  FIELD(UserAgentOverride, nsString)                                          \
    219  FIELD(TouchEventsOverrideInternal, mozilla::dom::TouchEventsOverride)       \
    220  FIELD(EmbedderElementType, Maybe<nsString>)                                 \
    221  FIELD(MessageManagerGroup, nsString)                                        \
    222  FIELD(MaxTouchPointsOverride, uint8_t)                                      \
    223  FIELD(FullZoom, float)                                                      \
    224  FIELD(WatchedByDevToolsInternal, bool)                                      \
    225  FIELD(TextZoom, float)                                                      \
    226  FIELD(OverrideDPPX, float)                                                  \
    227  /* The current in-progress load. */                                         \
    228  FIELD(CurrentLoadIdentifier, Maybe<uint64_t>)                               \
    229  /* The android load identifier. Used to map to applink type */              \
    230  FIELD(AndroidAppLinkLoadIdentifier, Maybe<uint64_t>)                        \
    231  /* See nsIRequest for possible flags. */                                    \
    232  FIELD(DefaultLoadFlags, uint32_t)                                           \
    233  /* Signals that session history is enabled for this browsing context tree.  \
    234   * This is only ever set to true on the top BC, so consumers need to get    \
    235   * the value from the top BC! */                                            \
    236  FIELD(HasSessionHistory, bool)                                              \
    237  FIELD(UseErrorPages, bool)                                                  \
    238  FIELD(PlatformOverride, nsString)                                           \
    239  /* Specifies if this BC has loaded documents besides the initial            \
    240   * about:blank document. about:privatebrowsing, about:home, about:newtab    \
    241   * and non-initial about:blank are not considered to be initial             \
    242   * documents. */                                                            \
    243  FIELD(HasLoadedNonInitialDocument, bool)                                    \
    244  /* Default value for nsIDocumentViewer::authorStyleDisabled in any new      \
    245   * browsing contexts created as a descendant of this one.  Valid only for   \
    246   * top BCs. */                                                              \
    247  FIELD(AuthorStyleDisabledDefault, bool)                                     \
    248  FIELD(ServiceWorkersTestingEnabled, bool)                                   \
    249  FIELD(MediumOverride, nsString)                                             \
    250  /* DevTools override for prefers-color-scheme */                            \
    251  FIELD(PrefersColorSchemeOverride, dom::PrefersColorSchemeOverride)          \
    252  FIELD(LanguageOverride, nsCString)                                          \
    253  FIELD(TimezoneOverride, nsString)                                           \
    254  /* DevTools override for forced-colors */                                   \
    255  FIELD(ForcedColorsOverride, dom::ForcedColorsOverride)                      \
    256  /* prefers-color-scheme override based on the color-scheme style of our     \
    257   * <browser> embedder element. */                                           \
    258  FIELD(EmbedderColorSchemes, EmbedderColorSchemes)                           \
    259  FIELD(DisplayMode, dom::DisplayMode)                                        \
    260  /* The number of entries added to the session history because of this       \
    261   * browsing context. */                                                     \
    262  FIELD(HistoryEntryCount, uint32_t)                                          \
    263  /* Don't use the getter of the field, but IsInBFCache() method */           \
    264  FIELD(IsInBFCache, bool)                                                    \
    265  FIELD(HasRestoreData, bool)                                                 \
    266  FIELD(SessionStoreEpoch, uint32_t)                                          \
    267  /* Whether we can execute scripts in this BrowsingContext. Has no effect    \
    268   * unless scripts are also allowed in the parent WindowContext. */          \
    269  FIELD(AllowJavascript, bool)                                                \
    270  /* The count of request that are used to prevent the browsing context tree  \
    271   * from being suspended, which would ONLY be modified on the top level      \
    272   * context in the chrome process because that's a non-atomic counter */     \
    273  FIELD(PageAwakeRequestCount, uint32_t)                                      \
    274  /* This field only gets incrememented when we start navigations in the      \
    275   * parent process. This is used for keeping track of the racing navigations \
    276   * between the parent and content processes. */                             \
    277  FIELD(ParentInitiatedNavigationEpoch, uint64_t)                             \
    278  /* This browsing context is for a synthetic image document wrapping an      \
    279   * image embedded in <object> or <embed>. */                                \
    280  FIELD(IsSyntheticDocumentContainer, bool)                                   \
    281  /* If true, this document is embedded within a content document,  either    \
    282   * loaded in the parent (e.g. about:addons or the devtools toolbox), or in  \
    283   * a content process. */                                                    \
    284  FIELD(EmbeddedInContentDocument, bool)                                      \
    285  /* If true, this browsing context is within a hidden embedded document. */  \
    286  FIELD(IsUnderHiddenEmbedderElement, bool)                                   \
    287  /* If true, this browsing context is offline */                             \
    288  FIELD(ForceOffline, bool)                                                   \
    289  /* Used to propagate window.top's inner size for RFPTarget::Window*         \
    290   * protections */                                                           \
    291  FIELD(TopInnerSizeForRFP, CSSIntSize)                                       \
    292  /* Used to propagate document's IPAddressSpace  */                          \
    293  FIELD(IPAddressSpace, nsILoadInfo::IPAddressSpace)                          \
    294  /* This is true if we should redirect to an error page when inserting *     \
    295   * meta tags flagging adult content into our documents */                   \
    296  FIELD(ParentalControlsEnabled, bool)                                        \
    297  /* If true, this traversable is a Document Picture-in-Picture and           \
    298     is subject to certain restrictions */                                    \
    299  FIELD(IsDocumentPiP, bool)
    300 
    301 // BrowsingContext, in this context, is the cross process replicated
    302 // environment in which information about documents is stored. In
    303 // particular the tree structure of nested browsing contexts is
    304 // represented by the tree of BrowsingContexts.
    305 //
    306 // The tree of BrowsingContexts is created in step with its
    307 // corresponding nsDocShell, and when nsDocShells are connected
    308 // through a parent/child relationship, so are BrowsingContexts. The
    309 // major difference is that BrowsingContexts are replicated (synced)
    310 // to the parent process, making it possible to traverse the
    311 // BrowsingContext tree for a tab, in both the parent and the child
    312 // process.
    313 //
    314 // Trees of BrowsingContexts should only ever contain nodes of the
    315 // same BrowsingContext::Type. This is enforced by asserts in the
    316 // BrowsingContext::Create* methods.
    317 class BrowsingContext : public nsILoadContext, public nsWrapperCache {
    318  MOZ_DECL_SYNCED_CONTEXT(BrowsingContext, MOZ_EACH_BC_FIELD)
    319 
    320 public:
    321  enum class Type { Chrome, Content };
    322 
    323  static void Init();
    324  static LogModule* GetLog();
    325  static LogModule* GetSyncLog();
    326 
    327  // Look up a BrowsingContext in the current process by ID.
    328  static already_AddRefed<BrowsingContext> Get(uint64_t aId);
    329  static already_AddRefed<BrowsingContext> Get(GlobalObject&, uint64_t aId) {
    330    return Get(aId);
    331  }
    332  // Look up the top-level BrowsingContext by BrowserID.
    333  static already_AddRefed<BrowsingContext> GetCurrentTopByBrowserId(
    334      uint64_t aBrowserId);
    335  static already_AddRefed<BrowsingContext> GetCurrentTopByBrowserId(
    336      GlobalObject&, uint64_t aId) {
    337    return GetCurrentTopByBrowserId(aId);
    338  }
    339 
    340  static void UpdateCurrentTopByBrowserId(BrowsingContext* aNewBrowsingContext);
    341 
    342  static already_AddRefed<BrowsingContext> GetFromWindow(
    343      WindowProxyHolder& aProxy);
    344  static already_AddRefed<BrowsingContext> GetFromWindow(
    345      GlobalObject&, WindowProxyHolder& aProxy) {
    346    return GetFromWindow(aProxy);
    347  }
    348 
    349  static void DiscardFromContentParent(ContentParent* aCP);
    350 
    351  // Create a brand-new toplevel BrowsingContext with no relationships to other
    352  // BrowsingContexts, and which is not embedded within any <browser> or frame
    353  // element.
    354  //
    355  // This BrowsingContext is immediately attached, and cannot have LoadContext
    356  // flags customized unless it is of `Type::Chrome`.
    357  //
    358  // The process which created this BrowsingContext is responsible for detaching
    359  // it.
    360  static already_AddRefed<BrowsingContext> CreateIndependent(Type aType,
    361                                                             bool aWindowless);
    362 
    363  // Options which can be passed to CreateDetached.
    364  struct CreateDetachedOptions {
    365    bool isPopupRequested = false;
    366    bool createdDynamically = false;
    367    bool topLevelCreatedByWebContent = false;
    368    bool isForPrinting = false;
    369    bool windowless = false;
    370  };
    371 
    372  // Create a brand-new BrowsingContext object, but does not immediately attach
    373  // it. State such as OriginAttributes and PrivateBrowsingId may be customized
    374  // to configure the BrowsingContext before it is attached.
    375  //
    376  // `EnsureAttached()` must be called before the BrowsingContext is used for a
    377  // DocShell, BrowserParent, or BrowserBridgeChild.
    378  static already_AddRefed<BrowsingContext> CreateDetached(
    379      nsGlobalWindowInner* aParent, BrowsingContext* aOpener,
    380      BrowsingContextGroup* aSpecificGroup, const nsAString& aName, Type aType,
    381      CreateDetachedOptions aOptions);
    382 
    383  void EnsureAttached();
    384 
    385  bool EverAttached() const { return mEverAttached; }
    386 
    387  // Cast this object to a canonical browsing context, and return it.
    388  CanonicalBrowsingContext* Canonical();
    389 
    390  // Is the most recent Document in this BrowsingContext loaded within this
    391  // process? This may be true with a null mDocShell after the Window has been
    392  // closed.
    393  bool IsInProcess() const { return mIsInProcess; }
    394 
    395  bool IsOwnedByProcess() const;
    396 
    397  bool CanHaveRemoteOuterProxies() const {
    398    return !mIsInProcess || mDanglingRemoteOuterProxies;
    399  }
    400 
    401  // Has this BrowsingContext been discarded. A discarded browsing context has
    402  // been destroyed, and may not be available on the other side of an IPC
    403  // message.
    404  bool IsDiscarded() const { return mIsDiscarded; }
    405 
    406  // Returns true if none of the BrowsingContext's ancestor BrowsingContexts or
    407  // WindowContexts are discarded or cached.
    408  bool AncestorsAreCurrent() const;
    409 
    410  bool Windowless() const { return mWindowless; }
    411 
    412  // Get the DocShell for this BrowsingContext if it is in-process, or
    413  // null if it's not.
    414  nsIDocShell* GetDocShell() const { return mDocShell; }
    415  void SetDocShell(nsIDocShell* aDocShell);
    416  void ClearDocShell() { mDocShell = nullptr; }
    417 
    418  // Get the Document for this BrowsingContext if it is in-process, or
    419  // null if it's not.
    420  Document* GetDocument() const {
    421    return mDocShell ? mDocShell->GetDocument() : nullptr;
    422  }
    423  Document* GetExtantDocument() const {
    424    return mDocShell ? mDocShell->GetExtantDocument() : nullptr;
    425  }
    426 
    427  // This cleans up remote outer window proxies that might have been left behind
    428  // when the browsing context went from being remote to local. It does this by
    429  // turning them into cross-compartment wrappers to aOuter. If there is already
    430  // a remote proxy in the compartment of aOuter, then aOuter will get swapped
    431  // to it and the value of aOuter will be set to the object that used to be the
    432  // remote proxy and is now an OuterWindowProxy.
    433  void CleanUpDanglingRemoteOuterWindowProxies(
    434      JSContext* aCx, JS::MutableHandle<JSObject*> aOuter);
    435 
    436  // Get the embedder element for this BrowsingContext if the embedder is
    437  // in-process, or null if it's not.
    438  Element* GetEmbedderElement() const { return mEmbedderElement; }
    439  void SetEmbedderElement(Element* aEmbedder);
    440 
    441  // Return true if the type of the embedder element is either object
    442  // or embed, false otherwise.
    443  bool IsEmbedderTypeObjectOrEmbed();
    444 
    445  // Called after the BrowingContext has been embedded in a FrameLoader. This
    446  // happens after `SetEmbedderElement` is called on the BrowsingContext and
    447  // after the BrowsingContext has been set on the FrameLoader.
    448  void Embed();
    449 
    450  // Get the outer window object for this BrowsingContext if it is in-process
    451  // and still has a docshell, or null otherwise.
    452  nsPIDOMWindowOuter* GetDOMWindow() const {
    453    return mDocShell ? mDocShell->GetWindow() : nullptr;
    454  }
    455 
    456  uint64_t GetRequestContextId() const { return mRequestContextId; }
    457 
    458  // Detach the current BrowsingContext from its parent, in both the
    459  // child and the parent process.
    460  void Detach(bool aFromIPC = false);
    461 
    462  // Prepare this BrowsingContext to leave the current process.
    463  void PrepareForProcessChange();
    464 
    465  // Triggers a load in the process which currently owns this BrowsingContext.
    466  nsresult LoadURI(nsDocShellLoadState* aLoadState,
    467                   bool aSetNavigating = false);
    468 
    469  nsresult InternalLoad(nsDocShellLoadState* aLoadState);
    470 
    471  void Navigate(
    472      nsIURI* aURI, Document* aSourceDocument, nsIPrincipal& aSubjectPrincipal,
    473      ErrorResult& aRv,
    474      NavigationHistoryBehavior aHistoryHandling =
    475          NavigationHistoryBehavior::Auto,
    476      bool aNeedsCompletelyLoadedDocument = false,
    477      nsIStructuredCloneContainer* aNavigationAPIState = nullptr,
    478      dom::NavigationAPIMethodTracker* aNavigationAPIMethodTracker = nullptr);
    479 
    480  // Removes the root document for this BrowsingContext tree from the BFCache,
    481  // if it is cached, and returns true if it was.
    482  bool RemoveRootFromBFCacheSync();
    483 
    484  // If the load state includes a source BrowsingContext has been passed, check
    485  // to see if we are sandboxed from it as the result of an iframe or CSP
    486  // sandbox.
    487  nsresult CheckSandboxFlags(nsDocShellLoadState* aLoadState);
    488 
    489  // If the current BrowsingContext is top-level, we run checks to see if
    490  // the source BrowsingContext is allowed to perform the navigation.
    491  nsresult CheckFramebusting(nsDocShellLoadState* aLoadState);
    492 
    493  // Determines if the current BrowsingContext is allowed to navigate the
    494  // target BrowsingContext (which should be top-level).
    495  bool IsFramebustingAllowed(BrowsingContext* aTarget);
    496 
    497  // A BrowsingContext is allowed to perform a top-level navigation if one
    498  // of the following conditions is met:
    499  // 1. It is top-level (implied by same-origin).
    500  // 2. It is same-origin with the top-level.
    501  // 3. Its associated document has been interacted with by the user.
    502  // 4. Its associated document has explicit `allow-top-navigation`
    503  //    sandbox flags.
    504  bool IsFramebustingAllowedInner();
    505 
    506  void DisplayLoadError(const nsAString& aURI);
    507 
    508  // Check that this browsing context is targetable for navigations (i.e. that
    509  // it is neither closed, cached, nor discarded).
    510  bool IsTargetable() const;
    511 
    512  // True if this browsing context is inactive and is able to be suspended.
    513  bool InactiveForSuspend() const;
    514 
    515  const nsString& Name() const { return GetName(); }
    516  void GetName(nsAString& aName) { aName = GetName(); }
    517  bool NameEquals(const nsAString& aName) { return GetName().Equals(aName); }
    518 
    519  Type GetType() const { return mType; }
    520  bool IsContent() const { return mType == Type::Content; }
    521  bool IsChrome() const { return !IsContent(); }
    522 
    523  bool IsTop() const { return !GetParent(); }
    524  bool IsSubframe() const { return !IsTop(); }
    525 
    526  bool IsTopContent() const { return IsContent() && IsTop(); }
    527 
    528  bool IsInSubtreeOf(BrowsingContext* aContext);
    529 
    530  bool IsContentSubframe() const { return IsContent() && IsSubframe(); }
    531 
    532  RefPtr<nsGeolocationService> GetGeolocationServiceOverride();
    533 
    534  // non-zero
    535  uint64_t Id() const { return mBrowsingContextId; }
    536 
    537  BrowsingContext* GetParent() const;
    538  BrowsingContext* Top();
    539  const BrowsingContext* Top() const;
    540 
    541  int32_t IndexOf(BrowsingContext* aChild);
    542 
    543  // NOTE: Unlike `GetEmbedderWindowGlobal`, `GetParentWindowContext` does not
    544  // cross toplevel content browser boundaries.
    545  WindowContext* GetParentWindowContext() const { return mParentWindow; }
    546  WindowContext* GetTopWindowContext() const;
    547 
    548  already_AddRefed<BrowsingContext> GetOpener() const {
    549    RefPtr<BrowsingContext> opener(Get(GetOpenerId()));
    550    if (!mIsDiscarded && opener && !opener->mIsDiscarded) {
    551      MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
    552      return opener.forget();
    553    }
    554    return nullptr;
    555  }
    556  void SetOpener(BrowsingContext* aOpener);
    557  bool HasOpener() const;
    558 
    559  bool HadOriginalOpener() const { return GetHadOriginalOpener(); }
    560 
    561  // Returns true if the browsing context and top context are same origin
    562  bool SameOriginWithTop();
    563 
    564  /**
    565   * When a new browsing context is opened by a sandboxed document, it needs to
    566   * keep track of the browsing context that opened it, so that it can be
    567   * navigated by it.  This is the "one permitted sandboxed navigator".
    568   */
    569  already_AddRefed<BrowsingContext> GetOnePermittedSandboxedNavigator() const {
    570    return Get(GetOnePermittedSandboxedNavigatorId());
    571  }
    572  [[nodiscard]] nsresult SetOnePermittedSandboxedNavigator(
    573      BrowsingContext* aNavigator) {
    574    if (GetOnePermittedSandboxedNavigatorId()) {
    575      MOZ_ASSERT(false,
    576                 "One Permitted Sandboxed Navigator should only be set once.");
    577      return NS_ERROR_FAILURE;
    578    } else {
    579      return SetOnePermittedSandboxedNavigatorId(aNavigator ? aNavigator->Id()
    580                                                            : 0);
    581    }
    582  }
    583 
    584  uint32_t SandboxFlags() const { return GetSandboxFlags(); }
    585 
    586  Span<RefPtr<BrowsingContext>> Children() const;
    587  void GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren);
    588 
    589  Span<RefPtr<BrowsingContext>> NonSyntheticChildren() const;
    590 
    591  BrowsingContext* NonSyntheticLightDOMChildAt(uint32_t aIndex) const;
    592  uint32_t NonSyntheticLightDOMChildrenCount() const;
    593 
    594  const nsTArray<RefPtr<WindowContext>>& GetWindowContexts() {
    595    return mWindowContexts;
    596  }
    597  void GetWindowContexts(nsTArray<RefPtr<WindowContext>>& aWindows);
    598 
    599  void RegisterWindowContext(WindowContext* aWindow);
    600  void UnregisterWindowContext(WindowContext* aWindow);
    601  WindowContext* GetCurrentWindowContext() const {
    602    return mCurrentWindowContext;
    603  }
    604 
    605  // Helpers to traverse this BrowsingContext subtree. Note that these will only
    606  // traverse active contexts, and will ignore ones in the BFCache.
    607  enum class WalkFlag {
    608    Next,
    609    Skip,
    610    Stop,
    611  };
    612 
    613  /**
    614   * Walk the browsing context tree in pre-order and call `aCallback`
    615   * for every node in the tree. PreOrderWalk accepts two types of
    616   * callbacks, either of the type `void(BrowsingContext*)` or
    617   * `WalkFlag(BrowsingContext*)`. The former traverses the entire
    618   * tree, but the latter let's you control if a sub-tree should be
    619   * skipped by returning `WalkFlag::Skip`, completely abort traversal
    620   * by returning `WalkFlag::Stop` or continue as normal with
    621   * `WalkFlag::Next`.
    622   */
    623  template <typename F>
    624  void PreOrderWalk(F&& aCallback) {
    625    if constexpr (std::is_void_v<
    626                      typename std::invoke_result_t<F, BrowsingContext*>>) {
    627      PreOrderWalkVoid(std::forward<F>(aCallback));
    628    } else {
    629      PreOrderWalkFlag(std::forward<F>(aCallback));
    630    }
    631  }
    632 
    633  void PreOrderWalkVoid(const std::function<void(BrowsingContext*)>& aCallback);
    634  WalkFlag PreOrderWalkFlag(
    635      const std::function<WalkFlag(BrowsingContext*)>& aCallback);
    636 
    637  void PostOrderWalk(const std::function<void(BrowsingContext*)>& aCallback);
    638 
    639  void GetAllBrowsingContextsInSubtree(
    640      nsTArray<RefPtr<BrowsingContext>>& aBrowsingContexts);
    641 
    642  BrowsingContextGroup* Group() { return mGroup; }
    643 
    644  // WebIDL bindings for nsILoadContext
    645  Nullable<WindowProxyHolder> GetAssociatedWindow();
    646  Nullable<WindowProxyHolder> GetTopWindow();
    647  Element* GetTopFrameElement();
    648  bool GetIsContent() { return IsContent(); }
    649  void SetUsePrivateBrowsing(bool aUsePrivateBrowsing, ErrorResult& aError);
    650  // Needs a different name to disambiguate from the xpidl method with
    651  // the same signature but different return value.
    652  void SetUseTrackingProtectionWebIDL(bool aUseTrackingProtection,
    653                                      ErrorResult& aRv);
    654  bool UseTrackingProtectionWebIDL() { return UseTrackingProtection(); }
    655  void GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal,
    656                           ErrorResult& aError);
    657 
    658  bool InRDMPane() const { return GetInRDMPane(); }
    659 
    660  bool WatchedByDevTools();
    661  void SetWatchedByDevTools(bool aWatchedByDevTools, ErrorResult& aRv);
    662 
    663  void SetGeolocationServiceOverride(
    664      const Optional<nsIDOMGeoPosition*>& aGeolocationOverride);
    665 
    666  dom::TouchEventsOverride TouchEventsOverride() const;
    667  bool TargetTopLevelLinkClicksToBlank() const;
    668 
    669  bool FullscreenAllowed() const;
    670 
    671  float FullZoom() const { return GetFullZoom(); }
    672  float TextZoom() const { return GetTextZoom(); }
    673 
    674  float OverrideDPPX() const { return Top()->GetOverrideDPPX(); }
    675 
    676  bool SuspendMediaWhenInactive() const {
    677    return GetSuspendMediaWhenInactive();
    678  }
    679 
    680  bool IsActive() const;
    681  bool ForceOffline() const { return GetForceOffline(); }
    682 
    683  nsILoadInfo::IPAddressSpace GetCurrentIPAddressSpace() const {
    684    return GetIPAddressSpace();
    685  }
    686 
    687  void SetCurrentIPAddressSpace(nsILoadInfo::IPAddressSpace aIPAddressSpace) {
    688    (void)SetIPAddressSpace(aIPAddressSpace);
    689  }
    690 
    691  bool ForceDesktopViewport() const { return GetForceDesktopViewport(); }
    692 
    693  bool AuthorStyleDisabledDefault() const {
    694    return GetAuthorStyleDisabledDefault();
    695  }
    696 
    697  bool UseGlobalHistory() const { return GetUseGlobalHistory(); }
    698 
    699  bool GetIsActiveBrowserWindow();
    700 
    701  void SetIsActiveBrowserWindow(bool aActive);
    702 
    703  uint64_t BrowserId() const { return GetBrowserId(); }
    704 
    705  bool IsLoading();
    706 
    707  void GetEmbedderElementType(nsString& aElementType) {
    708    if (GetEmbedderElementType().isSome()) {
    709      aElementType = GetEmbedderElementType().value();
    710    }
    711  }
    712 
    713  bool IsLoadingIdentifier(uint64_t aLoadIdentifer) {
    714    if (GetCurrentLoadIdentifier() &&
    715        *GetCurrentLoadIdentifier() == aLoadIdentifer) {
    716      return true;
    717    }
    718    return false;
    719  }
    720 
    721  [[nodiscard]] nsresult SetScreenAreaOverride(uint64_t aScreenWidth,
    722                                               uint64_t aScreenHeight) {
    723    if (GetHasScreenAreaOverride() &&
    724        GetScreenWidthOverride() == aScreenWidth &&
    725        GetScreenHeightOverride() == aScreenHeight) {
    726      return NS_OK;
    727    }
    728 
    729    Transaction txn;
    730    txn.SetScreenWidthOverride(aScreenWidth);
    731    txn.SetScreenHeightOverride(aScreenHeight);
    732    txn.SetHasScreenAreaOverride(true);
    733    return txn.Commit(this);
    734  }
    735 
    736  void SetScreenAreaOverride(uint64_t aScreenWidth, uint64_t aScreenHeight,
    737                             ErrorResult& aRv) {
    738    MOZ_ASSERT(IsTop());
    739 
    740    if (NS_FAILED(SetScreenAreaOverride(aScreenWidth, aScreenHeight))) {
    741      aRv.ThrowInvalidStateError("Browsing context is discarded");
    742    }
    743  }
    744 
    745  void ResetScreenAreaOverride() {
    746    MOZ_ASSERT(IsTop());
    747 
    748    (void)SetHasScreenAreaOverride(false);
    749  }
    750 
    751  bool HasScreenAreaOverride() const {
    752    return Top()->GetHasScreenAreaOverride();
    753  }
    754 
    755  Maybe<CSSIntSize> GetScreenAreaOverride() {
    756    if (!HasScreenAreaOverride()) {
    757      return Nothing();
    758    }
    759    CSSIntSize screenSize(Top()->GetScreenWidthOverride(),
    760                          Top()->GetScreenHeightOverride());
    761    return Some(screenSize);
    762  }
    763 
    764  // ScreenOrientation related APIs
    765  [[nodiscard]] nsresult SetCurrentOrientation(OrientationType aType,
    766                                               float aAngle) {
    767    Transaction txn;
    768    txn.SetCurrentOrientationType(aType);
    769    txn.SetCurrentOrientationAngle(aAngle);
    770    return txn.Commit(this);
    771  }
    772 
    773  bool HasOrientationOverride() const {
    774    return Top()->GetHasOrientationOverride();
    775  }
    776 
    777  [[nodiscard]] nsresult SetOrientationOverride(OrientationType aType,
    778                                                float aAngle) {
    779    if (GetHasOrientationOverride() && GetCurrentOrientationType() == aType &&
    780        GetCurrentOrientationAngle() == aAngle) {
    781      return NS_OK;
    782    }
    783 
    784    Transaction txn;
    785    txn.SetCurrentOrientationType(aType);
    786    txn.SetCurrentOrientationAngle(aAngle);
    787    txn.SetHasOrientationOverride(true);
    788    return txn.Commit(this);
    789  }
    790 
    791  void SetOrientationOverride(OrientationType aType, float aAngle,
    792                              ErrorResult& aRv) {
    793    MOZ_ASSERT(IsTop());
    794 
    795    if (NS_FAILED(SetOrientationOverride(aType, aAngle))) {
    796      aRv.ThrowInvalidStateError("Browsing context is discarded");
    797    }
    798  }
    799 
    800  void ResetOrientationOverride() {
    801    MOZ_ASSERT(IsTop());
    802 
    803    (void)SetHasOrientationOverride(false);
    804  }
    805 
    806  void SetRDMPaneMaxTouchPoints(uint8_t aMaxTouchPoints, ErrorResult& aRv) {
    807    if (InRDMPane()) {
    808      SetMaxTouchPointsOverride(aMaxTouchPoints, aRv);
    809    }
    810  }
    811 
    812  // Find a browsing context in this context's list of
    813  // children. Doesn't consider the special names, '_self', '_parent',
    814  // '_top', or '_blank'. Performs access control checks with regard to
    815  // 'this'.
    816  BrowsingContext* FindChildWithName(const nsAString& aName,
    817                                     WindowGlobalChild& aRequestingWindow);
    818 
    819  // Find a browsing context in the subtree rooted at 'this' Doesn't
    820  // consider the special names, '_self', '_parent', '_top', or
    821  // '_blank'.
    822  //
    823  // If passed, performs access control checks with regard to
    824  // 'aRequestingContext', otherwise performs no access checks.
    825  BrowsingContext* FindWithNameInSubtree(const nsAString& aName,
    826                                         WindowGlobalChild* aRequestingWindow);
    827 
    828  // Find the special browsing context if aName is '_self', '_parent',
    829  // '_top', but not '_blank'. The latter is handled in FindWithName
    830  BrowsingContext* FindWithSpecialName(const nsAString& aName,
    831                                       WindowGlobalChild& aRequestingWindow);
    832 
    833  nsISupports* GetParentObject() const;
    834  JSObject* WrapObject(JSContext* aCx,
    835                       JS::Handle<JSObject*> aGivenProto) override;
    836 
    837  // Return the window proxy object that corresponds to this browsing context.
    838  inline JSObject* GetWindowProxy() const { return mWindowProxy; }
    839  inline JSObject* GetUnbarrieredWindowProxy() const {
    840    return mWindowProxy.unbarrieredGet();
    841  }
    842 
    843  // Set the window proxy object that corresponds to this browsing context.
    844  void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) {
    845    mWindowProxy = aWindowProxy;
    846  }
    847 
    848  Nullable<WindowProxyHolder> GetWindow();
    849 
    850  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    851  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(BrowsingContext)
    852  NS_DECL_NSILOADCONTEXT
    853 
    854  // Window APIs that are cross-origin-accessible (from the HTML spec).
    855  WindowProxyHolder Window();
    856  BrowsingContext* GetBrowsingContext() { return this; };
    857  BrowsingContext* Self() { return this; }
    858  void Location(JSContext* aCx, JS::MutableHandle<JSObject*> aLocation,
    859                ErrorResult& aError);
    860  void Close(CallerType aCallerType, ErrorResult& aError);
    861  bool GetClosed(ErrorResult&) { return GetClosed(); }
    862  void Focus(CallerType aCallerType, ErrorResult& aError);
    863  void Blur(CallerType aCallerType, ErrorResult& aError);
    864  WindowProxyHolder GetFrames(ErrorResult& aError);
    865  int32_t Length() const { return Children().Length(); }
    866  Nullable<WindowProxyHolder> GetTop(ErrorResult& aError);
    867  void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aOpener,
    868                 ErrorResult& aError) const;
    869  Nullable<WindowProxyHolder> GetParent(ErrorResult& aError);
    870  void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
    871                      const nsAString& aTargetOrigin,
    872                      const Sequence<JSObject*>& aTransfer,
    873                      nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
    874  void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
    875                      const WindowPostMessageOptions& aOptions,
    876                      nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
    877 
    878  void GetCustomUserAgent(nsAString& aUserAgent) {
    879    aUserAgent = Top()->GetUserAgentOverride();
    880  }
    881  nsresult SetCustomUserAgent(const nsAString& aUserAgent);
    882  void SetCustomUserAgent(const nsAString& aUserAgent, ErrorResult& aRv);
    883 
    884  void GetCustomPlatform(nsAString& aPlatform) {
    885    aPlatform = Top()->GetPlatformOverride();
    886  }
    887  void SetCustomPlatform(const nsAString& aPlatform, ErrorResult& aRv);
    888 
    889  JSObject* WrapObject(JSContext* aCx);
    890 
    891  static JSObject* ReadStructuredClone(JSContext* aCx,
    892                                       JSStructuredCloneReader* aReader,
    893                                       StructuredCloneHolder* aHolder);
    894  bool WriteStructuredClone(JSContext* aCx, JSStructuredCloneWriter* aWriter,
    895                            StructuredCloneHolder* aHolder);
    896 
    897  void StartDelayedAutoplayMediaComponents();
    898 
    899  [[nodiscard]] nsresult ResetGVAutoplayRequestStatus();
    900 
    901  /**
    902   * Information required to initialize a BrowsingContext in another process.
    903   * This object may be serialized over IPC.
    904   */
    905  struct IPCInitializer {
    906    uint64_t mId = 0;
    907 
    908    // IDs are used for Parent and Opener to allow for this object to be
    909    // deserialized before other BrowsingContext in the BrowsingContextGroup
    910    // have been initialized.
    911    uint64_t mParentId = 0;
    912    already_AddRefed<WindowContext> GetParent();
    913    already_AddRefed<BrowsingContext> GetOpener();
    914 
    915    uint64_t GetOpenerId() const { return mFields.Get<IDX_OpenerId>(); }
    916 
    917    bool mWindowless = false;
    918    bool mUseRemoteTabs = false;
    919    bool mUseRemoteSubframes = false;
    920    bool mCreatedDynamically = false;
    921    int32_t mChildOffset = 0;
    922    int32_t mSessionHistoryIndex = -1;
    923    int32_t mSessionHistoryCount = 0;
    924    OriginAttributes mOriginAttributes;
    925    uint64_t mRequestContextId = 0;
    926 
    927    FieldValues mFields;
    928  };
    929 
    930  // Create an IPCInitializer object for this BrowsingContext.
    931  IPCInitializer GetIPCInitializer();
    932 
    933  // Create a BrowsingContext object from over IPC.
    934  static mozilla::ipc::IPCResult CreateFromIPC(IPCInitializer&& aInitializer,
    935                                               BrowsingContextGroup* aGroup,
    936                                               ContentParent* aOriginProcess);
    937 
    938  bool IsSandboxedFrom(BrowsingContext* aTarget);
    939 
    940  // The runnable will be called once there is idle time, or the top level
    941  // page has been loaded or if a timeout has fired.
    942  // Must be called only on the top level BrowsingContext.
    943  void AddDeprioritizedLoadRunner(nsIRunnable* aRunner);
    944 
    945  RefPtr<SessionStorageManager> GetSessionStorageManager();
    946 
    947  // Set PendingInitialization on this BrowsingContext before the context has
    948  // been attached.
    949  void InitPendingInitialization(bool aPendingInitialization) {
    950    MOZ_ASSERT(!EverAttached());
    951    mFields.SetWithoutSyncing<IDX_PendingInitialization>(
    952        aPendingInitialization);
    953  }
    954 
    955  bool CreatedDynamically() const { return mCreatedDynamically; }
    956 
    957  // Returns true if this browsing context, or any ancestor to this browsing
    958  // context was created dynamically. See also `CreatedDynamically`.
    959  bool IsDynamic() const;
    960 
    961  int32_t ChildOffset() const { return mChildOffset; }
    962 
    963  bool GetOffsetPath(nsTArray<uint32_t>& aPath) const;
    964 
    965  const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
    966  nsresult SetOriginAttributes(const OriginAttributes& aAttrs);
    967 
    968  void GetHistoryID(JSContext* aCx, JS::MutableHandle<JS::Value> aVal,
    969                    ErrorResult& aError);
    970 
    971  // This should only be called on the top browsing context.
    972  void InitSessionHistory();
    973 
    974  // This will only ever return a non-null value if called on the top browsing
    975  // context.
    976  ChildSHistory* GetChildSessionHistory();
    977 
    978  bool CrossOriginIsolated();
    979 
    980  // Check if it is allowed to open a popup from the current browsing
    981  // context or any of its ancestors.
    982  bool IsPopupAllowed();
    983 
    984  // aCurrentURI is only required to be non-null if the load type contains the
    985  // nsIWebNavigation::LOAD_FLAGS_IS_REFRESH flag and aInfo is for a refresh to
    986  // the current URI.
    987  void SessionHistoryCommit(const LoadingSessionHistoryInfo& aInfo,
    988                            uint32_t aLoadType, nsIURI* aCurrentURI,
    989                            SessionHistoryInfo* aPreviousActiveEntry,
    990                            bool aCloneEntryChildren, bool aChannelExpired,
    991                            uint32_t aCacheKey);
    992 
    993  // Set a new active entry on this browsing context. This is used for
    994  // implementing history.pushState/replaceState and same document navigations.
    995  // The new active entry will be linked to the current active entry through
    996  // its shared state.
    997  // aPreviousScrollPos is the scroll position that needs to be saved on the
    998  // previous active entry.
    999  // aPreviousActiveEntry should be the best available approximation of the
   1000  // current active entry in the parent, which the child process cannot access.
   1001  // aUpdatedCacheKey is the cache key to set on the new active entry. If
   1002  // aUpdatedCacheKey is 0 then it will be ignored.
   1003  void SetActiveSessionHistoryEntry(const Maybe<nsPoint>& aPreviousScrollPos,
   1004                                    SessionHistoryInfo* aInfo,
   1005                                    SessionHistoryInfo* aPreviousActiveEntry,
   1006                                    uint32_t aLoadType,
   1007                                    uint32_t aUpdatedCacheKey,
   1008                                    bool aUpdateLength = true);
   1009 
   1010  // Replace the active entry for this browsing context. This is used for
   1011  // implementing history.replaceState and same document navigations.
   1012  void ReplaceActiveSessionHistoryEntry(SessionHistoryInfo* aInfo);
   1013 
   1014  // Removes dynamic child entries of the active entry.
   1015  void RemoveDynEntriesFromActiveSessionHistoryEntry();
   1016 
   1017  // Removes entries corresponding to this BrowsingContext from session history.
   1018  void RemoveFromSessionHistory(const nsID& aChangeID);
   1019 
   1020  void SetTriggeringAndInheritPrincipals(nsIPrincipal* aTriggeringPrincipal,
   1021                                         nsIPrincipal* aPrincipalToInherit,
   1022                                         uint64_t aLoadIdentifier);
   1023 
   1024  // Return mTriggeringPrincipal and mPrincipalToInherit if the load id
   1025  // saved with the principal matches the current load identifier of this BC.
   1026  std::tuple<nsCOMPtr<nsIPrincipal>, nsCOMPtr<nsIPrincipal>>
   1027  GetTriggeringAndInheritPrincipalsForCurrentLoad();
   1028 
   1029  // HistoryGo is a content process entry point for #apply-the-history-step
   1030  MOZ_CAN_RUN_SCRIPT
   1031  void HistoryGo(int32_t aOffset, uint64_t aHistoryEpoch,
   1032                 bool aRequireUserInteraction, bool aUserActivation,
   1033                 std::function<void(Maybe<int32_t>&&)>&& aResolver);
   1034 
   1035  // NavigationTraverse is a content process entry point for
   1036  // #apply-the-history-step. It differs mainly in that it's using a
   1037  // navigation entry key for navigation, and that it's possible to
   1038  // pass `aCheckForCancelation`, which controls if we should run
   1039  // the onbeforeunload and traversable onnavigate checks.
   1040  MOZ_CAN_RUN_SCRIPT
   1041  void NavigationTraverse(const nsID& aKey, uint64_t aHistoryEpoch,
   1042                          bool aUserActivation, bool aCheckForCancelation,
   1043                          std::function<void(nsresult)>&& aResolver);
   1044 
   1045  bool ShouldUpdateSessionHistory(uint32_t aLoadType);
   1046 
   1047  // Checks if we reached the rate limit for calls to Location and History API.
   1048  // The rate limit is controlled by the
   1049  // "dom.navigation.navigationRateLimit" prefs.
   1050  // Rate limit applies per BrowsingContext.
   1051  // Returns NS_OK if we are below the rate limit and increments the counter.
   1052  // Returns NS_ERROR_DOM_SECURITY_ERR if limit is reached.
   1053  nsresult CheckNavigationRateLimit(CallerType aCallerType);
   1054 
   1055  void ResetNavigationRateLimit();
   1056 
   1057  mozilla::dom::DisplayMode DisplayMode() { return Top()->GetDisplayMode(); }
   1058 
   1059  // Returns canFocus, isActive
   1060  std::tuple<bool, bool> CanFocusCheck(CallerType aCallerType);
   1061 
   1062  bool CanBlurCheck(CallerType aCallerType);
   1063 
   1064  // Examine the current document state to see if we're in a way that is
   1065  // typically abused by web designers. The window.open code uses this
   1066  // routine to determine whether to allow the new window.
   1067  // Returns a value from the PopupControlState enum.
   1068  PopupBlocker::PopupControlState RevisePopupAbuseLevel(
   1069      PopupBlocker::PopupControlState aControl);
   1070 
   1071  // Get the modifiers associated with the user activation for relevant
   1072  // documents. The window.open code uses this routine to determine where the
   1073  // new window should be located.
   1074  void GetUserActivationModifiersForPopup(
   1075      UserActivation::Modifiers* aModifiers);
   1076 
   1077  void IncrementHistoryEntryCountForBrowsingContext();
   1078 
   1079  bool ServiceWorkersTestingEnabled() const {
   1080    return GetServiceWorkersTestingEnabled();
   1081  }
   1082 
   1083  void GetMediumOverride(nsAString& aOverride) const {
   1084    aOverride = GetMediumOverride();
   1085  }
   1086 
   1087  void GetLanguageOverride(nsACString& aLanguageOverride) const {
   1088    aLanguageOverride = GetLanguageOverride();
   1089  }
   1090 
   1091  void GetTimezoneOverride(nsAString& aTimezoneOverride) const {
   1092    aTimezoneOverride = GetTimezoneOverride();
   1093  }
   1094 
   1095  dom::PrefersColorSchemeOverride PrefersColorSchemeOverride() const {
   1096    return GetPrefersColorSchemeOverride();
   1097  }
   1098 
   1099  dom::ForcedColorsOverride ForcedColorsOverride() const {
   1100    return GetForcedColorsOverride();
   1101  }
   1102 
   1103  bool IsInBFCache() const;
   1104 
   1105  bool AllowJavascript() const { return GetAllowJavascript(); }
   1106  bool CanExecuteScripts() const { return mCanExecuteScripts; }
   1107 
   1108  uint32_t DefaultLoadFlags() const { return GetDefaultLoadFlags(); }
   1109 
   1110  // When request for page awake, it would increase a count that is used to
   1111  // prevent whole browsing context tree from being suspended. The request can
   1112  // be called multiple times. When calling the revoke, it would decrease the
   1113  // count and once the count reaches to zero, the browsing context tree could
   1114  // be suspended when the tree is inactive.
   1115  void RequestForPageAwake();
   1116  void RevokeForPageAwake();
   1117 
   1118  void AddDiscardListener(std::function<void(uint64_t)>&& aListener);
   1119 
   1120  bool IsAppTab() { return GetIsAppTab(); }
   1121  bool HasSiblings() { return GetHasSiblings(); }
   1122 
   1123  bool IsUnderHiddenEmbedderElement() const {
   1124    return GetIsUnderHiddenEmbedderElement();
   1125  }
   1126 
   1127  void LocationCreated(dom::Location* aLocation);
   1128  void ClearCachedValuesOfLocations();
   1129 
   1130  void ConsumeHistoryActivation();
   1131  void SynchronizeNavigationAPIState(nsIStructuredCloneContainer* aState);
   1132 
   1133 protected:
   1134  virtual ~BrowsingContext();
   1135  BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
   1136                  uint64_t aBrowsingContextId, Type aType, FieldValues&& aInit);
   1137 
   1138  void SetChildSHistory(ChildSHistory* aChildSHistory);
   1139  already_AddRefed<ChildSHistory> ForgetChildSHistory() {
   1140    // FIXME Do we need to unset mHasSessionHistory?
   1141    return mChildSessionHistory.forget();
   1142  }
   1143 
   1144  static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI,
   1145                                       const SessionHistoryInfo& aInfo);
   1146  static bool ShouldAddEntryForRefresh(nsIURI* aCurrentURI, nsIURI* aNewURI,
   1147                                       bool aHasPostData);
   1148 
   1149 private:
   1150  // Check whether it's OK to load the given url with the given subject
   1151  // principal, and if so construct the right nsDocShellLoadInfo for the load
   1152  // and return it.
   1153  already_AddRefed<nsDocShellLoadState> CheckURLAndCreateLoadState(
   1154      nsIURI* aURI, nsIPrincipal& aSubjectPrincipal, Document* aSourceDocument,
   1155      ErrorResult& aRv);
   1156 
   1157  bool AddSHEntryWouldIncreaseLength(SessionHistoryInfo* aCurrentEntry) const;
   1158 
   1159  // Assert that this BrowsingContext is coherent relative to related
   1160  // BrowsingContexts. This will be run before the BrowsingContext is attached.
   1161  //
   1162  // A non-null string return value indicates that there was a coherency check
   1163  // failure, which will be handled with either a crash or IPC failure.
   1164  //
   1165  // If provided, `aOriginProcess` is the process which is responsible for the
   1166  // creation of this BrowsingContext.
   1167  [[nodiscard]] const char* BrowsingContextCoherencyChecks(
   1168      ContentParent* aOriginProcess);
   1169 
   1170  void Attach(bool aFromIPC, ContentParent* aOriginProcess);
   1171 
   1172  // Recomputes whether we can execute scripts in this BrowsingContext based on
   1173  // the value of AllowJavascript() and whether scripts are allowed in the
   1174  // parent WindowContext. Called whenever the AllowJavascript() flag or the
   1175  // parent WC changes.
   1176  void RecomputeCanExecuteScripts();
   1177 
   1178  // Is it early enough in the BrowsingContext's lifecycle that it is still
   1179  // OK to set OriginAttributes?
   1180  bool CanSetOriginAttributes();
   1181 
   1182  void AssertOriginAttributesMatchPrivateBrowsing();
   1183 
   1184  friend class ::nsOuterWindowProxy;
   1185  friend class ::nsGlobalWindowOuter;
   1186  friend class WindowContext;
   1187 
   1188  // Update the window proxy object that corresponds to this browsing context.
   1189  // This should be called from the window proxy object's objectMoved hook, if
   1190  // the object mWindowProxy points to was moved by the JS GC.
   1191  void UpdateWindowProxy(JSObject* obj, JSObject* old) {
   1192    if (mWindowProxy) {
   1193      MOZ_ASSERT(mWindowProxy == old);
   1194      mWindowProxy = obj;
   1195    }
   1196  }
   1197  // Clear the window proxy object that corresponds to this browsing context.
   1198  // This should be called if the window proxy object is finalized, or it can't
   1199  // reach its browsing context anymore.
   1200  void ClearWindowProxy() { mWindowProxy = nullptr; }
   1201 
   1202  friend class Location;
   1203  friend class RemoteLocationProxy;
   1204  /**
   1205   * LocationProxy is the class for the native object stored as a private in a
   1206   * RemoteLocationProxy proxy representing a Location object in a different
   1207   * process. It forwards all operations to its BrowsingContext and aggregates
   1208   * its refcount to that BrowsingContext.
   1209   */
   1210  class LocationProxy final : public LocationBase {
   1211   public:
   1212    MozExternalRefCountType AddRef() { return GetBrowsingContext()->AddRef(); }
   1213    MozExternalRefCountType Release() {
   1214      return GetBrowsingContext()->Release();
   1215    }
   1216 
   1217   protected:
   1218    friend class RemoteLocationProxy;
   1219    BrowsingContext* GetBrowsingContext() override {
   1220      return reinterpret_cast<BrowsingContext*>(
   1221          uintptr_t(this) - offsetof(BrowsingContext, mLocation));
   1222    }
   1223 
   1224    nsIDocShell* GetDocShell() override { return nullptr; }
   1225  };
   1226 
   1227  // Send a given `BaseTransaction` object to the correct remote.
   1228  void SendCommitTransaction(ContentParent* aParent,
   1229                             const BaseTransaction& aTxn, uint64_t aEpoch);
   1230  void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
   1231                             uint64_t aEpoch);
   1232 
   1233  bool CanSet(FieldIndex<IDX_SessionStoreEpoch>, uint32_t aEpoch,
   1234              ContentParent* aSource) {
   1235    return IsTop() && !aSource;
   1236  }
   1237 
   1238  void DidSet(FieldIndex<IDX_SessionStoreEpoch>, uint32_t aOldValue);
   1239 
   1240  using CanSetResult = syncedcontext::CanSetResult;
   1241 
   1242  // Ensure that opener is in the same BrowsingContextGroup.
   1243  bool CanSet(FieldIndex<IDX_OpenerId>, const uint64_t& aValue,
   1244              ContentParent* aSource) {
   1245    if (aValue != 0) {
   1246      RefPtr<BrowsingContext> opener = Get(aValue);
   1247      return opener && opener->Group() == Group();
   1248    }
   1249    return true;
   1250  }
   1251 
   1252  bool CanSet(FieldIndex<IDX_OpenerPolicy>,
   1253              nsILoadInfo::CrossOriginOpenerPolicy, ContentParent*);
   1254 
   1255  bool CanSet(FieldIndex<IDX_ServiceWorkersTestingEnabled>, bool,
   1256              ContentParent*) {
   1257    return IsTop();
   1258  }
   1259 
   1260  bool CanSet(FieldIndex<IDX_LanguageOverride>, const nsCString&,
   1261              ContentParent*) {
   1262    return IsTop();
   1263  }
   1264 
   1265  bool CanSet(FieldIndex<IDX_TimezoneOverride>, const nsString&,
   1266              ContentParent*) {
   1267    return IsTop();
   1268  }
   1269 
   1270  bool CanSet(FieldIndex<IDX_MediumOverride>, const nsString&, ContentParent*) {
   1271    return IsTop();
   1272  }
   1273 
   1274  bool CanSet(FieldIndex<IDX_EmbedderColorSchemes>, const EmbedderColorSchemes&,
   1275              ContentParent* aSource) {
   1276    return CheckOnlyEmbedderCanSet(aSource);
   1277  }
   1278 
   1279  bool CanSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
   1280              dom::PrefersColorSchemeOverride, ContentParent*) {
   1281    return IsTop();
   1282  }
   1283 
   1284  bool CanSet(FieldIndex<IDX_ForcedColorsOverride>, dom::ForcedColorsOverride,
   1285              ContentParent*) {
   1286    return IsTop();
   1287  }
   1288 
   1289  void DidSet(FieldIndex<IDX_InRDMPane>, bool aOldValue);
   1290  void DidSet(FieldIndex<IDX_HasOrientationOverride>, bool aOldValue);
   1291  MOZ_CAN_RUN_SCRIPT_BOUNDARY void DidSet(FieldIndex<IDX_ForceDesktopViewport>,
   1292                                          bool aOldValue);
   1293 
   1294  void DidSet(FieldIndex<IDX_EmbedderColorSchemes>,
   1295              EmbedderColorSchemes&& aOldValue);
   1296 
   1297  void DidSet(FieldIndex<IDX_PrefersColorSchemeOverride>,
   1298              dom::PrefersColorSchemeOverride aOldValue);
   1299 
   1300  void DidSet(FieldIndex<IDX_ForcedColorsOverride>,
   1301              dom::ForcedColorsOverride aOldValue);
   1302 
   1303  template <typename Callback>
   1304  void WalkPresContexts(Callback&&);
   1305  void PresContextAffectingFieldChanged();
   1306 
   1307  void DidSet(FieldIndex<IDX_LanguageOverride>, nsCString&& aOldValue);
   1308 
   1309  void DidSet(FieldIndex<IDX_TimezoneOverride>, nsString&& aOldValue);
   1310 
   1311  void DidSet(FieldIndex<IDX_MediumOverride>, nsString&& aOldValue);
   1312 
   1313  bool CanSet(FieldIndex<IDX_SuspendMediaWhenInactive>, bool, ContentParent*) {
   1314    return IsTop();
   1315  }
   1316 
   1317  bool CanSet(FieldIndex<IDX_TouchEventsOverrideInternal>,
   1318              dom::TouchEventsOverride aTouchEventsOverride,
   1319              ContentParent* aSource);
   1320  void DidSet(FieldIndex<IDX_TouchEventsOverrideInternal>,
   1321              dom::TouchEventsOverride&& aOldValue);
   1322 
   1323  bool CanSet(FieldIndex<IDX_DisplayMode>, const enum DisplayMode& aDisplayMode,
   1324              ContentParent* aSource) {
   1325    return IsTop();
   1326  }
   1327 
   1328  void DidSet(FieldIndex<IDX_DisplayMode>, enum DisplayMode aOldValue);
   1329 
   1330  bool CanSet(FieldIndex<IDX_ExplicitActive>, const ExplicitActiveStatus&,
   1331              ContentParent* aSource);
   1332  void DidSet(FieldIndex<IDX_ExplicitActive>, ExplicitActiveStatus aOldValue);
   1333 
   1334  bool CanSet(FieldIndex<IDX_IsActiveBrowserWindowInternal>, const bool& aValue,
   1335              ContentParent* aSource);
   1336  void DidSet(FieldIndex<IDX_IsActiveBrowserWindowInternal>, bool aOldValue);
   1337 
   1338  // Ensure that we only set the flag on the top level browsingContext.
   1339  // And then, we do a pre-order walk in the tree to refresh the
   1340  // volume of all media elements.
   1341  void DidSet(FieldIndex<IDX_Muted>);
   1342 
   1343  bool CanSet(FieldIndex<IDX_IsAppTab>, const bool& aValue,
   1344              ContentParent* aSource);
   1345 
   1346  bool CanSet(FieldIndex<IDX_IsCaptivePortalTab>, const bool& aValue,
   1347              ContentParent* aSource) {
   1348    return true;
   1349  }
   1350 
   1351  bool CanSet(FieldIndex<IDX_HasSiblings>, const bool& aValue,
   1352              ContentParent* aSource);
   1353 
   1354  bool CanSet(FieldIndex<IDX_ShouldDelayMediaFromStart>, const bool& aValue,
   1355              ContentParent* aSource);
   1356  void DidSet(FieldIndex<IDX_ShouldDelayMediaFromStart>, bool aOldValue);
   1357 
   1358  bool CanSet(FieldIndex<IDX_OverrideDPPX>, const float& aValue,
   1359              ContentParent* aSource);
   1360  void DidSet(FieldIndex<IDX_OverrideDPPX>, float aOldValue);
   1361 
   1362  bool CanSet(FieldIndex<IDX_EmbedderInnerWindowId>, const uint64_t& aValue,
   1363              ContentParent* aSource);
   1364 
   1365  CanSetResult CanSet(FieldIndex<IDX_CurrentInnerWindowId>,
   1366                      const uint64_t& aValue, ContentParent* aSource);
   1367 
   1368  void DidSet(FieldIndex<IDX_CurrentInnerWindowId>);
   1369 
   1370  bool CanSet(FieldIndex<IDX_ParentInitiatedNavigationEpoch>,
   1371              const uint64_t& aValue, ContentParent* aSource);
   1372 
   1373  bool CanSet(FieldIndex<IDX_IsPopupSpam>, const bool& aValue,
   1374              ContentParent* aSource);
   1375 
   1376  void DidSet(FieldIndex<IDX_IsPopupSpam>);
   1377 
   1378  void DidSet(FieldIndex<IDX_GVAudibleAutoplayRequestStatus>);
   1379  void DidSet(FieldIndex<IDX_GVInaudibleAutoplayRequestStatus>);
   1380 
   1381  void DidSet(FieldIndex<IDX_Loading>);
   1382 
   1383  void DidSet(FieldIndex<IDX_AncestorLoading>);
   1384 
   1385  void DidSet(FieldIndex<IDX_PlatformOverride>);
   1386  CanSetResult CanSet(FieldIndex<IDX_PlatformOverride>,
   1387                      const nsString& aPlatformOverride,
   1388                      ContentParent* aSource);
   1389 
   1390  void DidSet(FieldIndex<IDX_UserAgentOverride>);
   1391  CanSetResult CanSet(FieldIndex<IDX_UserAgentOverride>,
   1392                      const nsString& aUserAgent, ContentParent* aSource);
   1393  bool CanSet(FieldIndex<IDX_OrientationLock>,
   1394              const mozilla::hal::ScreenOrientation& aOrientationLock,
   1395              ContentParent* aSource);
   1396 
   1397  bool CanSet(FieldIndex<IDX_EmbedderElementType>,
   1398              const Maybe<nsString>& aInitiatorType, ContentParent* aSource);
   1399 
   1400  bool CanSet(FieldIndex<IDX_MessageManagerGroup>,
   1401              const nsString& aMessageManagerGroup, ContentParent* aSource);
   1402 
   1403  CanSetResult CanSet(FieldIndex<IDX_AllowContentRetargeting>,
   1404                      const bool& aAllowContentRetargeting,
   1405                      ContentParent* aSource);
   1406  CanSetResult CanSet(FieldIndex<IDX_AllowContentRetargetingOnChildren>,
   1407                      const bool& aAllowContentRetargetingOnChildren,
   1408                      ContentParent* aSource);
   1409  bool CanSet(FieldIndex<IDX_FullscreenAllowedByOwner>, const bool&,
   1410              ContentParent*);
   1411  bool CanSet(FieldIndex<IDX_WatchedByDevToolsInternal>,
   1412              const bool& aWatchedByDevToolsInternal, ContentParent* aSource);
   1413 
   1414  CanSetResult CanSet(FieldIndex<IDX_DefaultLoadFlags>,
   1415                      const uint32_t& aDefaultLoadFlags,
   1416                      ContentParent* aSource);
   1417  void DidSet(FieldIndex<IDX_DefaultLoadFlags>);
   1418 
   1419  bool CanSet(FieldIndex<IDX_UseGlobalHistory>, const bool& aUseGlobalHistory,
   1420              ContentParent* aSource);
   1421 
   1422  bool CanSet(FieldIndex<IDX_TargetTopLevelLinkClicksToBlankInternal>,
   1423              const bool& aTargetTopLevelLinkClicksToBlankInternal,
   1424              ContentParent* aSource);
   1425 
   1426  void DidSet(FieldIndex<IDX_HasSessionHistory>, bool aOldValue);
   1427 
   1428  bool CanSet(FieldIndex<IDX_BrowserId>, const uint32_t& aValue,
   1429              ContentParent* aSource);
   1430 
   1431  bool CanSet(FieldIndex<IDX_UseErrorPages>, const bool& aUseErrorPages,
   1432              ContentParent* aSource);
   1433 
   1434  bool CanSet(FieldIndex<IDX_PendingInitialization>, bool aNewValue,
   1435              ContentParent* aSource);
   1436 
   1437  bool CanSet(FieldIndex<IDX_TopLevelCreatedByWebContent>,
   1438              const bool& aNewValue, ContentParent* aSource);
   1439 
   1440  bool CanSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aNewValue,
   1441              ContentParent* aSource);
   1442  void DidSet(FieldIndex<IDX_PageAwakeRequestCount>, uint32_t aOldValue);
   1443 
   1444  CanSetResult CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
   1445                      ContentParent* aSource);
   1446  void DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue);
   1447 
   1448  bool CanSet(FieldIndex<IDX_ForceDesktopViewport>, bool aValue,
   1449              ContentParent* aSource) {
   1450    return IsTop() && XRE_IsParentProcess();
   1451  }
   1452 
   1453  // TODO(emilio): Maybe handle the flag being set dynamically without
   1454  // navigating? The previous code didn't do it tho, and a reload is probably
   1455  // worth it regardless.
   1456  // void DidSet(FieldIndex<IDX_ForceDesktopViewport>, bool aOldValue);
   1457 
   1458  bool CanSet(FieldIndex<IDX_HasRestoreData>, bool aNewValue,
   1459              ContentParent* aSource);
   1460 
   1461  bool CanSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>,
   1462              const bool& aIsUnderHiddenEmbedderElement,
   1463              ContentParent* aSource);
   1464 
   1465  bool CanSet(FieldIndex<IDX_ForceOffline>, bool aNewValue,
   1466              ContentParent* aSource);
   1467 
   1468  bool CanSet(FieldIndex<IDX_TopInnerSizeForRFP>, bool, ContentParent*) {
   1469    return IsTop();
   1470  }
   1471 
   1472  bool CanSet(FieldIndex<IDX_EmbeddedInContentDocument>, bool,
   1473              ContentParent* aSource) {
   1474    return CheckOnlyEmbedderCanSet(aSource);
   1475  }
   1476 
   1477  template <size_t I, typename T>
   1478  bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
   1479    return true;
   1480  }
   1481 
   1482  bool CanSet(FieldIndex<IDX_IPAddressSpace>, nsILoadInfo::IPAddressSpace,
   1483              ContentParent*) {
   1484    return XRE_IsParentProcess();
   1485  }
   1486 
   1487  bool CanSet(FieldIndex<IDX_ParentalControlsEnabled>, bool, ContentParent*) {
   1488    return XRE_IsParentProcess();
   1489  }
   1490 
   1491  bool CanSet(FieldIndex<IDX_IsDocumentPiP>, bool, ContentParent*) {
   1492    return IsTop();
   1493  }
   1494 
   1495  // Overload `DidSet` to get notifications for a particular field being set.
   1496  //
   1497  // You can also overload the variant that gets the old value if you need it.
   1498  template <size_t I>
   1499  void DidSet(FieldIndex<I>) {}
   1500  template <size_t I, typename T>
   1501  void DidSet(FieldIndex<I>, T&& aOldValue) {}
   1502 
   1503  void DidSet(FieldIndex<IDX_FullZoom>, float aOldValue);
   1504  void DidSet(FieldIndex<IDX_TextZoom>, float aOldValue);
   1505  void DidSet(FieldIndex<IDX_AuthorStyleDisabledDefault>);
   1506 
   1507  bool CanSet(FieldIndex<IDX_IsInBFCache>, bool, ContentParent* aSource);
   1508  void DidSet(FieldIndex<IDX_IsInBFCache>);
   1509 
   1510  void DidSet(FieldIndex<IDX_IsSyntheticDocumentContainer>);
   1511 
   1512  void DidSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>, bool aOldValue);
   1513 
   1514  void DidSet(FieldIndex<IDX_ForceOffline>, bool aOldValue);
   1515 
   1516  void DidSet(FieldIndex<IDX_IsDocumentPiP>, bool aWasPiP) {
   1517    if (GetIsDocumentPiP() && !aWasPiP) {
   1518      SetDisplayMode(DisplayMode::Picture_in_picture, IgnoreErrors());
   1519    } else if (!GetIsDocumentPiP() && aWasPiP) {
   1520      MOZ_ASSERT_UNREACHABLE("BrowsingContext should never leave PiP mode");
   1521    }
   1522  }
   1523 
   1524  // Allow if the process attemping to set field is the same as the owning
   1525  // process. Deprecated. New code that might use this should generally be moved
   1526  // to WindowContext or be settable only by the parent process.
   1527  CanSetResult LegacyRevertIfNotOwningOrParentProcess(ContentParent* aSource);
   1528 
   1529  // True if the process attempting to set field is the same as the embedder's
   1530  // process.
   1531  bool CheckOnlyEmbedderCanSet(ContentParent* aSource);
   1532 
   1533  void CreateChildSHistory();
   1534 
   1535  using PrincipalWithLoadIdentifierTuple =
   1536      std::tuple<nsCOMPtr<nsIPrincipal>, uint64_t>;
   1537 
   1538  nsIPrincipal* GetSavedPrincipal(
   1539      Maybe<PrincipalWithLoadIdentifierTuple> aPrincipalTuple);
   1540 
   1541  // Type of BrowsingContent
   1542  const Type mType;
   1543 
   1544  // Unique id identifying BrowsingContext
   1545  const uint64_t mBrowsingContextId;
   1546 
   1547  RefPtr<BrowsingContextGroup> mGroup;
   1548  RefPtr<WindowContext> mParentWindow;
   1549  nsCOMPtr<nsIDocShell> mDocShell;
   1550 
   1551  RefPtr<Element> mEmbedderElement;
   1552 
   1553  nsTArray<RefPtr<WindowContext>> mWindowContexts;
   1554  RefPtr<WindowContext> mCurrentWindowContext;
   1555 
   1556  RefPtr<nsGeolocationService> mGeolocationServiceOverride;
   1557 
   1558  JS::UniqueChars mDefaultLocale;
   1559 
   1560  // This is not a strong reference, but using a JS::Heap for that should be
   1561  // fine. The JSObject stored in here should be a proxy with a
   1562  // nsOuterWindowProxy handler, which will update the pointer from its
   1563  // objectMoved hook and clear it from its finalize hook.
   1564  JS::Heap<JSObject*> mWindowProxy;
   1565  LocationProxy mLocation;
   1566 
   1567  // OriginAttributes for this BrowsingContext. May not be changed after this
   1568  // BrowsingContext is attached.
   1569  OriginAttributes mOriginAttributes;
   1570 
   1571  // The network request context id, representing the nsIRequestContext
   1572  // associated with this BrowsingContext, and LoadGroups created for it.
   1573  uint64_t mRequestContextId = 0;
   1574 
   1575  // Determines if private browsing should be used. May not be changed after
   1576  // this BrowsingContext is attached. This field matches mOriginAttributes in
   1577  // content Browsing Contexts. Currently treated as a binary value: 1 - in
   1578  // private mode, 0 - not private mode.
   1579  uint32_t mPrivateBrowsingId;
   1580 
   1581  // True if Attach() has been called on this BrowsingContext already.
   1582  bool mEverAttached : 1;
   1583 
   1584  // Is the most recent Document in this BrowsingContext loaded within this
   1585  // process? This may be true with a null mDocShell after the Window has been
   1586  // closed.
   1587  bool mIsInProcess : 1;
   1588 
   1589  // Has this browsing context been discarded? BrowsingContexts should
   1590  // only be discarded once.
   1591  bool mIsDiscarded : 1;
   1592 
   1593  // True if this BrowsingContext has no associated visible window, and is owned
   1594  // by whichever process created it, even if top-level.
   1595  bool mWindowless : 1;
   1596 
   1597  // This is true if the BrowsingContext was out of process, but is now in
   1598  // process, and might have remote window proxies that need to be cleaned up.
   1599  bool mDanglingRemoteOuterProxies : 1;
   1600 
   1601  // True if this BrowsingContext has been embedded in a element in this
   1602  // process.
   1603  bool mEmbeddedByThisProcess : 1;
   1604 
   1605  // Determines if remote (out-of-process) tabs should be used. May not be
   1606  // changed after this BrowsingContext is attached.
   1607  bool mUseRemoteTabs : 1;
   1608 
   1609  // Determines if out-of-process iframes should be used. May not be changed
   1610  // after this BrowsingContext is attached.
   1611  bool mUseRemoteSubframes : 1;
   1612 
   1613  // True if this BrowsingContext is for a frame that was added dynamically.
   1614  bool mCreatedDynamically : 1;
   1615 
   1616  // Set to true if the browsing context is in the bfcache and pagehide has been
   1617  // dispatched. When coming out from the bfcache, the value is set to false
   1618  // before dispatching pageshow.
   1619  bool mIsInBFCache : 1;
   1620 
   1621  // Determines if we can execute scripts in this BrowsingContext. True if
   1622  // AllowJavascript() is true and script execution is allowed in the parent
   1623  // WindowContext.
   1624  bool mCanExecuteScripts : 1;
   1625 
   1626  // The original offset of this context in its container. This property is -1
   1627  // if this BrowsingContext is for a frame that was added dynamically.
   1628  int32_t mChildOffset;
   1629 
   1630  // The start time of user gesture, this is only available if the browsing
   1631  // context is in process.
   1632  TimeStamp mUserGestureStart;
   1633 
   1634  // Triggering principal and principal to inherit need to point to original
   1635  // principal instances if the document is loaded in the same process as the
   1636  // process that initiated the load. When the load starts we save the
   1637  // principals along with the current load id.
   1638  // These principals correspond to the most recent load that took place within
   1639  // the process of this browsing context.
   1640  Maybe<PrincipalWithLoadIdentifierTuple> mTriggeringPrincipal;
   1641  Maybe<PrincipalWithLoadIdentifierTuple> mPrincipalToInherit;
   1642 
   1643  class DeprioritizedLoadRunner
   1644      : public mozilla::Runnable,
   1645        public mozilla::LinkedListElement<DeprioritizedLoadRunner> {
   1646   public:
   1647    explicit DeprioritizedLoadRunner(nsIRunnable* aInner)
   1648        : Runnable("DeprioritizedLoadRunner"), mInner(aInner) {}
   1649 
   1650    NS_IMETHOD Run() override {
   1651      if (mInner) {
   1652        RefPtr<nsIRunnable> inner = std::move(mInner);
   1653        inner->Run();
   1654      }
   1655 
   1656      return NS_OK;
   1657    }
   1658 
   1659   private:
   1660    RefPtr<nsIRunnable> mInner;
   1661  };
   1662 
   1663  mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
   1664 
   1665  RefPtr<SessionStorageManager> mSessionStorageManager;
   1666  RefPtr<ChildSHistory> mChildSessionHistory;
   1667 
   1668  nsTArray<std::function<void(uint64_t)>> mDiscardListeners;
   1669 
   1670  // Counter and time span for rate limiting Location and History API calls.
   1671  // Used by CheckNavigationRateLimit. Do not apply cross-process.
   1672  uint32_t mNavigationRateLimitCount;
   1673  mozilla::TimeStamp mNavigationRateLimitSpanStart;
   1674 
   1675  mozilla::LinkedList<dom::Location> mLocations;
   1676 };
   1677 
   1678 /**
   1679 * Gets a WindowProxy object for a BrowsingContext that lives in a different
   1680 * process (creating the object if it doesn't already exist). The WindowProxy
   1681 * object will be in the compartment that aCx is currently in. This should only
   1682 * be called if aContext doesn't hold a docshell, otherwise the BrowsingContext
   1683 * lives in this process, and a same-process WindowProxy should be used (see
   1684 * nsGlobalWindowOuter). This should only be called by bindings code, ToJSValue
   1685 * is the right API to get a WindowProxy for a BrowsingContext.
   1686 *
   1687 * If aTransplantTo is non-null, then the WindowProxy object will eventually be
   1688 * transplanted onto it. Therefore it should be used as the value in the remote
   1689 * proxy map. We assume that in this case the failure is unrecoverable, so we
   1690 * crash immediately rather than return false.
   1691 */
   1692 extern bool GetRemoteOuterWindowProxy(JSContext* aCx, BrowsingContext* aContext,
   1693                                      JS::Handle<JSObject*> aTransplantTo,
   1694                                      JS::MutableHandle<JSObject*> aRetVal);
   1695 
   1696 using BrowsingContextTransaction = BrowsingContext::BaseTransaction;
   1697 using BrowsingContextInitializer = BrowsingContext::IPCInitializer;
   1698 using MaybeDiscardedBrowsingContext = MaybeDiscarded<BrowsingContext>;
   1699 
   1700 // Specialize the transaction object for every translation unit it's used in.
   1701 extern template class syncedcontext::Transaction<BrowsingContext>;
   1702 
   1703 }  // namespace dom
   1704 }  // namespace mozilla
   1705 
   1706 // Allow sending BrowsingContext objects over IPC.
   1707 namespace IPC {
   1708 template <>
   1709 struct ParamTraits<
   1710    mozilla::dom::MaybeDiscarded<mozilla::dom::BrowsingContext>> {
   1711  using paramType = mozilla::dom::MaybeDiscarded<mozilla::dom::BrowsingContext>;
   1712  static void Write(IPC::MessageWriter* aWriter, const paramType& aParam);
   1713  static bool Read(IPC::MessageReader* aReader, paramType* aResult);
   1714 };
   1715 
   1716 template <>
   1717 struct ParamTraits<mozilla::dom::BrowsingContext::IPCInitializer> {
   1718  using paramType = mozilla::dom::BrowsingContext::IPCInitializer;
   1719  static void Write(IPC::MessageWriter* aWriter, const paramType& aInitializer);
   1720  static bool Read(IPC::MessageReader* aReader, paramType* aInitializer);
   1721 };
   1722 }  // namespace IPC
   1723 
   1724 #endif  // !defined(mozilla_dom_BrowsingContext_h)