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)