nsPIDOMWindow.h (39380B)
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 nsPIDOMWindow_h__ 8 #define nsPIDOMWindow_h__ 9 10 #include "Units.h" 11 #include "js/TypeDecls.h" 12 #include "mozIDOMWindow.h" 13 #include "mozilla/EventForwards.h" 14 #include "mozilla/Maybe.h" 15 #include "mozilla/MozPromise.h" 16 #include "mozilla/dom/EventTarget.h" 17 #include "nsCOMPtr.h" 18 #include "nsIDOMWindow.h" 19 #include "nsILoadInfo.h" 20 #include "nsRefPtrHashtable.h" 21 #include "nsTArray.h" 22 23 class nsDOMCSSDeclaration; 24 class nsGlobalWindowInner; 25 class nsGlobalWindowOuter; 26 class nsIArray; 27 class nsIBaseWindow; 28 class nsIChannel; 29 class nsIContent; 30 class nsIContentSecurityPolicy; 31 class nsIDocShell; 32 class nsIDocShellTreeOwner; 33 class nsDocShellLoadState; 34 class nsIPolicyContainer; 35 class nsIPrincipal; 36 class nsIRunnable; 37 class nsIScriptTimeoutHandler; 38 class nsISerialEventTarget; 39 class nsIURI; 40 class nsIPrompt; 41 class nsIControllers; 42 class nsIWebBrowserChrome; 43 class nsPIDOMWindowInner; 44 class nsPIDOMWindowOuter; 45 class nsPIWindowRoot; 46 47 using SuspendTypes = uint32_t; 48 49 namespace mozilla::dom { 50 class AudioContext; 51 class BrowsingContext; 52 class BrowsingContextGroup; 53 class ClientInfo; 54 class ClientState; 55 class ContentFrameMessageManager; 56 class CloseWatcherManager; 57 class DocGroup; 58 class Document; 59 class Element; 60 class Location; 61 class MediaDevices; 62 class MediaKeys; 63 class Navigation; 64 class Navigator; 65 class Performance; 66 class Selection; 67 class ServiceWorker; 68 class ServiceWorkerDescriptor; 69 class Timeout; 70 class TimeoutManager; 71 class WebIdentityHandler; 72 class WindowContext; 73 class WindowGlobalChild; 74 class CustomElementRegistry; 75 class DocumentPictureInPicture; 76 enum class CallerType : uint32_t; 77 } // namespace mozilla::dom 78 79 enum class FullscreenReason { 80 // Toggling the fullscreen mode requires trusted context. 81 ForFullscreenMode, 82 // Fullscreen API is the API provided to untrusted content. 83 ForFullscreenAPI, 84 // This reason can only be used with exiting fullscreen. 85 // It is otherwise identical to eForFullscreenAPI except it would 86 // suppress the fullscreen transition. 87 ForForceExitFullscreen 88 }; 89 90 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs 91 #define NS_PIDOMWINDOWINNER_IID \ 92 {0x775dabc9, 0x8f43, 0x4277, {0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb}} 93 94 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs 95 #define NS_PIDOMWINDOWOUTER_IID \ 96 {0x769693d4, 0xb009, 0x4fe2, {0xaf, 0x18, 0x7d, 0xc8, 0xdf, 0x74, 0x96, 0xdf}} 97 98 class nsPIDOMWindowInner : public mozIDOMWindow { 99 protected: 100 using Document = mozilla::dom::Document; 101 friend nsGlobalWindowInner; 102 friend nsGlobalWindowOuter; 103 104 nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow, 105 mozilla::dom::WindowGlobalChild* aActor); 106 107 ~nsPIDOMWindowInner(); 108 109 public: 110 NS_INLINE_DECL_STATIC_IID(NS_PIDOMWINDOWINNER_IID) 111 112 nsIGlobalObject* AsGlobal(); 113 const nsIGlobalObject* AsGlobal() const; 114 115 nsPIDOMWindowOuter* GetOuterWindow() const { return mOuterWindow; } 116 117 static nsPIDOMWindowInner* From(mozIDOMWindow* aFrom) { 118 return static_cast<nsPIDOMWindowInner*>(aFrom); 119 } 120 121 NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(nsPIDOMWindowInner, 122 GetAsInnerWindow()) 123 124 // Returns true if this object is the currently-active inner window for its 125 // BrowsingContext. 126 bool IsCurrentInnerWindow() const; 127 128 // Returns true if the document of this window is the active document. This 129 // is identical to IsCurrentInnerWindow() now that document.open() no longer 130 // creates new inner windows for the document it is called on. 131 inline bool HasActiveDocument() const; 132 133 // Return true if this object is the currently-active inner window for its 134 // BrowsingContext and any container document is also fully active. 135 // For https://html.spec.whatwg.org/multipage/browsers.html#fully-active 136 bool IsFullyActive() const; 137 138 // Returns true if this window is the same as mTopInnerWindow 139 inline bool IsTopInnerWindow() const; 140 141 // Returns true if this was the current window for its BrowsingContext when it 142 // was discarded. 143 virtual bool WasCurrentInnerWindow() const = 0; 144 145 // Check whether a document is currently loading (really checks if the 146 // load event has completed). May not be reset to false on errors. 147 inline bool IsLoading() const; 148 inline bool IsHandlingResizeEvent() const; 149 150 // Note: not related to IsLoading. Set to false if there's an error, etc. 151 virtual void SetActiveLoadingState(bool aIsActiveLoading) = 0; 152 153 bool AddAudioContext(mozilla::dom::AudioContext* aAudioContext); 154 void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext); 155 void MuteAudioContexts(); 156 void UnmuteAudioContexts(); 157 158 void SetAudioCapture(bool aCapture); 159 160 /** 161 * Associate this inner window with a MediaKeys instance. 162 */ 163 void AddMediaKeysInstance(mozilla::dom::MediaKeys* aMediaKeysInstance); 164 165 /** 166 * Remove an association between this inner window and a MediaKeys instance. 167 */ 168 void RemoveMediaKeysInstance(mozilla::dom::MediaKeys* aMediaKeysInstance); 169 170 /** 171 * Return if any MediaKeys instances are associated with this window. 172 */ 173 bool HasActiveMediaKeysInstance(); 174 175 mozilla::dom::Performance* GetPerformance(); 176 177 void QueuePerformanceNavigationTiming(); 178 179 /** 180 * Call this to check whether some node (this window, its document, 181 * or content in that document) has a mouseenter/leave event listener. 182 */ 183 bool HasMouseEnterLeaveEventListeners() const { 184 return mMayHaveMouseEnterLeaveEventListener; 185 } 186 187 /** 188 * Call this to indicate that some node (this window, its document, 189 * or content in that document) has a mouseenter/leave event listener. 190 */ 191 void SetHasMouseEnterLeaveEventListeners() { 192 mMayHaveMouseEnterLeaveEventListener = true; 193 } 194 195 /** 196 * Call this to check whether some node (this window, its document, 197 * or content in that document) has a Pointerenter/leave event listener. 198 */ 199 bool HasPointerEnterLeaveEventListeners() const { 200 return mMayHavePointerEnterLeaveEventListener; 201 } 202 203 /** 204 * Call this to indicate that some node (this window, its document, 205 * or content in that document) has a Pointerenter/leave event listener. 206 */ 207 void SetHasPointerEnterLeaveEventListeners() { 208 mMayHavePointerEnterLeaveEventListener = true; 209 } 210 211 /** 212 * Call this to check whether some node (this window, its document, 213 * or content in that document) has a pointerrawupdate event listener. 214 */ 215 bool HasPointerRawUpdateEventListeners() const { 216 return mMayHavePointerRawUpdateEventListener; 217 } 218 219 /** 220 * Call this to indicate that some node (this window, its document, 221 * or content in that document) has a pointerrawupdate event listener. 222 * This may not accept that if the event is not available in this window. 223 */ 224 void MaybeSetHasPointerRawUpdateEventListeners(); 225 226 protected: 227 /** 228 * Call this to clear whether some nodes has a pointerrawupdate event 229 * listener. 230 */ 231 void ClearHasPointerRawUpdateEventListeners(); 232 233 public: 234 /** 235 * Call this to check whether some node (this window, its document, 236 * or content in that document) has a transition* event listeners. 237 */ 238 bool HasTransitionEventListeners() { return mMayHaveTransitionEventListener; } 239 240 /** 241 * Call this to indicate that some node (this window, its document, 242 * or content in that document) has a transition* event listener. 243 */ 244 void SetHasTransitionEventListeners() { 245 mMayHaveTransitionEventListener = true; 246 } 247 248 /** 249 * Call this to check whether some node (this window, its document, 250 * or content in that document) has a SMILTime* event listeners. 251 */ 252 bool HasSMILTimeEventListeners() { return mMayHaveSMILTimeEventListener; } 253 254 /** 255 * Call this to indicate that some node (this window, its document, 256 * or content in that document) has a SMILTime* event listener. 257 */ 258 void SetHasSMILTimeEventListeners() { mMayHaveSMILTimeEventListener = true; } 259 260 /** 261 * Call this to check whether some node (this window, its document, 262 * or content in that document) has a beforeinput event listener. 263 * Returing false may be wrong if some nodes have come from another document 264 * with `Document.adoptNode`. 265 */ 266 bool HasBeforeInputEventListenersForTelemetry() const { 267 return mMayHaveBeforeInputEventListenerForTelemetry; 268 } 269 270 /** 271 * Call this to indicate that some node (this window, its document, 272 * or content in that document) has a beforeinput event listener. 273 */ 274 void SetHasBeforeInputEventListenersForTelemetry() { 275 mMayHaveBeforeInputEventListenerForTelemetry = true; 276 } 277 278 /** 279 * Call this to check whether some node (The document, or content in the 280 * document) has been observed by web apps with a mutation observer. 281 * (i.e., `MutationObserver.observe()` called by chrome script and addon's 282 * script does not make this returns true). 283 * Returing false may be wrong if some nodes have come from another document 284 * with `Document.adoptNode`. 285 */ 286 bool MutationObserverHasObservedNodeForTelemetry() const { 287 return mMutationObserverHasObservedNodeForTelemetry; 288 } 289 290 /** 291 * Call this to indicate that some node (The document, or content in the 292 * document) is observed by web apps with a mutation observer. 293 */ 294 void SetMutationObserverHasObservedNodeForTelemetry() { 295 mMutationObserverHasObservedNodeForTelemetry = true; 296 } 297 298 // Sets the event for window.event. Does NOT take ownership, so 299 // the caller is responsible for clearing the event before the 300 // event gets deallocated. Pass nullptr to set window.event to 301 // undefined. Returns the previous value. 302 mozilla::dom::Event* SetEvent(mozilla::dom::Event* aEvent) { 303 mozilla::dom::Event* old = mEvent; 304 mEvent = aEvent; 305 return old; 306 } 307 308 /** 309 * Check whether this window is a secure context. 310 */ 311 bool IsSecureContext() const; 312 bool IsSecureContextIfOpenerIgnored() const; 313 314 // Calling suspend should prevent any asynchronous tasks from 315 // executing javascript for this window. This means setTimeout, 316 // requestAnimationFrame, and events should not be fired. Suspending 317 // a window maybe also suspends its children. Workers may 318 // continue to perform computations in the background. A window 319 // can have Suspend() called multiple times and will only resume after 320 // a matching number of Resume() calls. 321 void Suspend(bool aIncludeSubWindows = true); 322 void Resume(bool aIncludeSubWindows = true); 323 324 // Whether or not this window was suspended by the BrowserContextGroup 325 bool GetWasSuspendedByGroup() const { return mWasSuspendedByGroup; } 326 void SetWasSuspendedByGroup(bool aSuspended) { 327 mWasSuspendedByGroup = aSuspended; 328 } 329 330 // Apply the parent window's suspend, freeze, and modal state to the current 331 // window. 332 void SyncStateFromParentWindow(); 333 334 /** 335 * Increment active peer connection count. 336 */ 337 void AddPeerConnection(); 338 339 /** 340 * Decrement active peer connection count. 341 */ 342 void RemovePeerConnection(); 343 344 bool IsDocumentLoaded() const; 345 346 // To cache top inner-window if available after constructed for tab-wised 347 // indexedDB counters. 348 void TryToCacheTopInnerWindow(); 349 350 mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const; 351 mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const; 352 mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const; 353 354 void SetPolicyContainer(nsIPolicyContainer* aPolicyContainer); 355 nsIPolicyContainer* GetPolicyContainer(); 356 357 void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp); 358 359 void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope); 360 361 void NoteDOMContentLoaded(); 362 363 virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0; 364 365 // XXX: This is called on inner windows 366 virtual nsPIDOMWindowOuter* GetInProcessScriptableTop() = 0; 367 virtual nsPIDOMWindowOuter* GetInProcessScriptableParent() = 0; 368 virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0; 369 370 mozilla::dom::EventTarget* GetChromeEventHandler() const { 371 return mChromeEventHandler; 372 } 373 374 mozilla::dom::EventTarget* GetParentTarget() { 375 if (!mParentTarget) { 376 UpdateParentTarget(); 377 } 378 return mParentTarget; 379 } 380 381 virtual void MaybeUpdateTouchState() {} 382 383 Document* GetExtantDoc() const { return mDoc; } 384 nsIURI* GetDocumentURI() const; 385 nsIURI* GetDocBaseURI() const; 386 387 Document* GetDoc() { 388 if (!mDoc) { 389 MaybeCreateDoc(); 390 } 391 return mDoc; 392 } 393 394 mozilla::dom::WindowContext* GetWindowContext() const; 395 mozilla::dom::WindowGlobalChild* GetWindowGlobalChild() const { 396 return mWindowGlobalChild; 397 } 398 399 // Removes this inner window from the BFCache, if it is cached, and returns 400 // true if it was. 401 bool RemoveFromBFCacheSync(); 402 403 // Fire any DOM notification events related to things that happened while 404 // the window was frozen. 405 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) = 0; 406 407 /** 408 * Get the docshell in this window. 409 */ 410 inline nsIDocShell* GetDocShell() const; 411 412 /** 413 * Get the browsing context in this window. 414 */ 415 inline mozilla::dom::BrowsingContext* GetBrowsingContext() const; 416 417 /** 418 * Get the browsing context group this window belongs to. 419 */ 420 mozilla::dom::BrowsingContextGroup* GetBrowsingContextGroup() const; 421 422 /** 423 * Call this to indicate that some node (this window, its document, 424 * or content in that document) has a DOMActivate event listener. 425 */ 426 void SetHasDOMActivateEventListeners() { 427 mMayHaveDOMActivateEventListeners = true; 428 } 429 430 /** 431 * Call this to check whether some node (this window, its document, 432 * or content in that document) has a DOMActivate event listener. 433 */ 434 bool HasDOMActivateEventListeners() const { 435 return mMayHaveDOMActivateEventListeners; 436 } 437 438 /** 439 * Call this to indicate that some node (this window, its document, 440 * or content in that document) has a touch event listener. 441 */ 442 void SetHasTouchEventListeners() { 443 if (!mMayHaveTouchEventListener) { 444 mMayHaveTouchEventListener = true; 445 MaybeUpdateTouchState(); 446 } 447 } 448 449 /** 450 * Call this to indicate that some node (this window, its document, 451 * or content in that document) has a selectionchange event listener. 452 */ 453 void SetHasSelectionChangeEventListeners() { 454 mMayHaveSelectionChangeEventListener = true; 455 } 456 457 /** 458 * Call this to check whether some node (this window, its document, 459 * or content in that document) has a selectionchange event listener. 460 */ 461 bool HasSelectionChangeEventListeners() const { 462 return mMayHaveSelectionChangeEventListener; 463 } 464 465 /** 466 * Call this to indicate that some node (this window, its document, 467 * or content in that document) has a select event listener of form controls. 468 */ 469 void SetHasFormSelectEventListeners() { 470 mMayHaveFormSelectEventListener = true; 471 } 472 473 /** 474 * Call this to check whether some node (this window, its document, 475 * or content in that document) has a select event listener of form controls. 476 */ 477 bool HasFormSelectEventListeners() const { 478 return mMayHaveFormSelectEventListener; 479 } 480 481 /* 482 * Get and set the currently focused element within the document. If 483 * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a 484 * document focus event is needed. 485 * 486 * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER 487 * INSTEAD. 488 */ 489 mozilla::dom::Element* GetFocusedElement() const { 490 return mFocusedElement.get(); 491 } 492 493 virtual void SetFocusedElement(mozilla::dom::Element* aElement, 494 uint32_t aFocusMethod = 0, 495 bool aNeedsFocus = false) = 0; 496 497 bool UnknownFocusMethodShouldShowOutline() const { 498 return mUnknownFocusMethodShouldShowOutline; 499 } 500 501 /** 502 * Retrieves the method that was used to focus the current node. 503 */ 504 virtual uint32_t GetFocusMethod() = 0; 505 506 /* 507 * Tells the window that it now has focus or has lost focus, based on the 508 * state of aFocus. If this method returns true, then the document loaded 509 * in the window has never received a focus event and expects to receive 510 * one. If false is returned, the document has received a focus event before 511 * and should only receive one if the window is being focused. 512 * 513 * aFocusMethod may be set to one of the focus method constants in 514 * nsIFocusManager to indicate how focus was set. 515 */ 516 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0; 517 518 /** 519 * Indicates that the window may now accept a document focus event. This 520 * should be called once a document has been loaded into the window. 521 */ 522 virtual void SetReadyForFocus() = 0; 523 524 /** 525 * Whether the focused content within the window should show a focus ring. 526 */ 527 virtual bool ShouldShowFocusRing() = 0; 528 529 /** 530 * Indicates that the page in the window has been hidden. This is used to 531 * reset the focus state. 532 */ 533 virtual void PageHidden(bool aIsEnteringBFCacheInParent) = 0; 534 535 /** 536 * Instructs this window to asynchronously dispatch a hashchange event. This 537 * method must be called on an inner window. 538 */ 539 virtual nsresult DispatchAsyncHashchange(nsIURI* aOldURI, 540 nsIURI* aNewURI) = 0; 541 542 /** 543 * Instructs this window to synchronously dispatch a popState event. 544 */ 545 virtual nsresult DispatchSyncPopState() = 0; 546 547 /** 548 * Tell this window that it should listen for sensor changes of the given 549 * type. 550 */ 551 virtual void EnableDeviceSensor(uint32_t aType) = 0; 552 553 /** 554 * Tell this window that it should remove itself from sensor change 555 * notifications. 556 */ 557 virtual void DisableDeviceSensor(uint32_t aType) = 0; 558 559 #if defined(MOZ_WIDGET_ANDROID) 560 virtual void EnableOrientationChangeListener() = 0; 561 virtual void DisableOrientationChangeListener() = 0; 562 #endif 563 564 /** 565 * Tell this window that there is an observer for gamepad input 566 * 567 * Inner windows only. 568 */ 569 virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0; 570 571 /** 572 * Return the window id of this window 573 */ 574 uint64_t WindowID() const { return mWindowID; } 575 576 // WebIDL-ish APIs 577 void MarkUncollectableForCCGeneration(uint32_t aGeneration) { 578 mMarkedCCGeneration = aGeneration; 579 } 580 581 uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; } 582 583 mozilla::dom::Navigation* Navigation(); 584 mozilla::dom::Navigator* Navigator(); 585 mozilla::dom::MediaDevices* GetExtantMediaDevices() const; 586 virtual mozilla::dom::Location* Location() = 0; 587 588 virtual nsresult GetControllers(nsIControllers** aControllers) = 0; 589 590 MOZ_CAN_RUN_SCRIPT virtual nsresult GetInnerWidth(double* aWidth) = 0; 591 MOZ_CAN_RUN_SCRIPT virtual nsresult GetInnerHeight(double* aHeight) = 0; 592 593 virtual already_AddRefed<nsDOMCSSDeclaration> GetComputedStyle( 594 mozilla::dom::Element& aElt, const nsAString& aPseudoElt, 595 mozilla::ErrorResult& aError) = 0; 596 597 virtual bool GetFullScreen() = 0; 598 599 virtual nsresult Focus(mozilla::dom::CallerType aCallerType) = 0; 600 virtual nsresult Close() = 0; 601 602 mozilla::dom::DocGroup* GetDocGroup() const; 603 604 RefPtr<mozilla::GenericPromise> SaveStorageAccessPermissionGranted(); 605 RefPtr<mozilla::GenericPromise> SaveStorageAccessPermissionRevoked(); 606 607 bool UsingStorageAccess(); 608 609 mozilla::dom::WebIdentityHandler* GetOrCreateWebIdentityHandler(); 610 611 uint32_t UpdateLockCount(bool aIncrement) { 612 MOZ_ASSERT_IF(!aIncrement, mLockCount > 0); 613 mLockCount += aIncrement ? 1 : -1; 614 return mLockCount; 615 }; 616 bool HasActiveLocks() { return mLockCount > 0; } 617 618 uint32_t UpdateWebTransportCount(bool aIncrement) { 619 MOZ_ASSERT_IF(!aIncrement, mWebTransportCount > 0); 620 mWebTransportCount += aIncrement ? 1 : -1; 621 return mWebTransportCount; 622 }; 623 bool HasActiveWebTransports() { return mWebTransportCount > 0; } 624 625 mozilla::dom::CloseWatcherManager* EnsureCloseWatcherManager(); 626 627 // Called when a CloseWatcher is added to the manager 628 void NotifyCloseWatcherAdded(); 629 630 // Called when a CloseWatcher is removed from the manager 631 void NotifyCloseWatcherRemoved(); 632 633 virtual mozilla::dom::DocumentPictureInPicture* 634 GetExtantDocumentPictureInPicture() = 0; 635 636 protected: 637 void CreatePerformanceObjectIfNeeded(); 638 639 // Lazily instantiate an about:blank document if necessary, and if 640 // we have what it takes to do so. 641 void MaybeCreateDoc(); 642 643 void SetChromeEventHandlerInternal( 644 mozilla::dom::EventTarget* aChromeEventHandler) { 645 mChromeEventHandler = aChromeEventHandler; 646 // mParentTarget will be set when the next event is dispatched. 647 mParentTarget = nullptr; 648 } 649 650 virtual void UpdateParentTarget() = 0; 651 652 // These two variables are special in that they're set to the same 653 // value on both the outer window and the current inner window. Make 654 // sure you keep them in sync! 655 nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong 656 RefPtr<Document> mDoc; 657 // Cache the URI when mDoc is cleared. 658 nsCOMPtr<nsIURI> mDocumentURI; // strong 659 nsCOMPtr<nsIURI> mDocBaseURI; // strong 660 661 nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong 662 663 RefPtr<mozilla::dom::Performance> mPerformance; 664 mozilla::UniquePtr<mozilla::dom::TimeoutManager> mTimeoutManager; 665 RefPtr<mozilla::dom::WebIdentityHandler> mWebIdentityHandler; 666 667 RefPtr<mozilla::dom::Navigation> mNavigation; 668 669 RefPtr<mozilla::dom::Navigator> mNavigator; 670 671 // These variables are only used on inner windows. 672 uint32_t mActivePeerConnections = 0; 673 674 bool mIsDocumentLoaded = false; 675 bool mIsHandlingResizeEvent = false; 676 bool mMayHaveDOMActivateEventListeners = false; 677 bool mMayHaveTouchEventListener = false; 678 bool mMayHaveSelectionChangeEventListener = false; 679 bool mMayHaveFormSelectEventListener = false; 680 bool mMayHaveMouseEnterLeaveEventListener = false; 681 bool mMayHavePointerEnterLeaveEventListener = false; 682 bool mMayHavePointerRawUpdateEventListener = false; 683 bool mMayHaveTransitionEventListener = false; 684 bool mMayHaveSMILTimeEventListener = false; 685 // Only used for telemetry probes. This may be wrong if some nodes have 686 // come from another document with `Document.adoptNode`. 687 bool mMayHaveBeforeInputEventListenerForTelemetry = false; 688 bool mMutationObserverHasObservedNodeForTelemetry = false; 689 690 // Our inner window's outer window. 691 nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow; 692 693 // The element within the document that is currently focused when this 694 // window is active. 695 RefPtr<mozilla::dom::Element> mFocusedElement; 696 697 // The AudioContexts created for the current document, if any. 698 nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak 699 700 // Instances of MediaKeys created in this inner window. Storing these allows 701 // us to shutdown MediaKeys when an inner windows is destroyed. We can also 702 // use the presence of MediaKeys to assess if a window has EME activity. 703 nsTArray<mozilla::dom::MediaKeys*> mMediaKeysInstances; // Weak 704 705 RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext; 706 707 // A unique (as long as our 64-bit counter doesn't roll over) id for 708 // this window. 709 uint64_t mWindowID = 0; 710 711 // Set to true once we've sent the (chrome|content)-document-global-created 712 // notification. 713 bool mHasNotifiedGlobalCreated = false; 714 715 // Whether when focused via an "unknown" focus method, we should show outlines 716 // by default or not. The initial value of this is true (so as to show 717 // outlines for stuff like html autofocus, or initial programmatic focus 718 // without any other user interaction). 719 bool mUnknownFocusMethodShouldShowOutline = true; 720 721 uint32_t mMarkedCCGeneration = 0; 722 723 // mTopInnerWindow is used for tab-wise check by timeout throttling. It could 724 // be null. 725 nsCOMPtr<nsPIDOMWindowInner> mTopInnerWindow; 726 727 // The evidence that we have tried to cache mTopInnerWindow only once from 728 // SetNewDocument(). Note: We need this extra flag because mTopInnerWindow 729 // could be null and we don't want it to be set multiple times. 730 bool mHasTriedToCacheTopInnerWindow = false; 731 732 // The number of active IndexedDB databases. 733 uint32_t mNumOfIndexedDBDatabases = 0; 734 735 // The number of open WebSockets. 736 uint32_t mNumOfOpenWebSockets = 0; 737 738 // The event dispatch code sets and unsets this while keeping 739 // the event object alive. 740 mozilla::dom::Event* mEvent = nullptr; 741 742 // The WindowGlobalChild actor for this window. 743 // 744 // This will be non-null during the full lifetime of the window, initialized 745 // during SetNewDocument, and cleared during FreeInnerObjects. 746 RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild; 747 748 bool mWasSuspendedByGroup = false; 749 750 /** 751 * Count of the number of active LockRequest objects, including ones from 752 * workers. 753 */ 754 uint32_t mLockCount = 0; 755 /** 756 * Count of the number of active WebTransport objects, including ones from 757 * workers. 758 */ 759 uint32_t mWebTransportCount = 0; 760 761 // The CloseWatcherManager for this window. 762 RefPtr<mozilla::dom::CloseWatcherManager> mCloseWatcherManager; 763 }; 764 765 class nsPIDOMWindowOuter : public mozIDOMWindowProxy { 766 protected: 767 using Document = mozilla::dom::Document; 768 769 explicit nsPIDOMWindowOuter(uint64_t aWindowID); 770 771 ~nsPIDOMWindowOuter(); 772 773 void NotifyResumingDelayedMedia(); 774 775 public: 776 NS_INLINE_DECL_STATIC_IID(NS_PIDOMWINDOWOUTER_IID) 777 778 NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(nsPIDOMWindowOuter, 779 GetAsOuterWindow()) 780 781 static nsPIDOMWindowOuter* From(mozIDOMWindowProxy* aFrom) { 782 return static_cast<nsPIDOMWindowOuter*>(aFrom); 783 } 784 785 // Given an inner window, return its outer if the inner is the current inner. 786 // Otherwise (argument null or not an inner or not current) return null. 787 static nsPIDOMWindowOuter* GetFromCurrentInner(nsPIDOMWindowInner* aInner); 788 789 // Check whether a document is currently loading 790 inline bool IsLoading() const; 791 inline bool IsHandlingResizeEvent() const; 792 793 nsPIDOMWindowInner* GetCurrentInnerWindow() const { return mInnerWindow; } 794 795 nsPIDOMWindowInner* EnsureInnerWindow() { 796 // GetDoc forces inner window creation if there isn't one already 797 GetDoc(); 798 return GetCurrentInnerWindow(); 799 } 800 801 bool IsRootOuterWindow() { return mIsRootOuterWindow; } 802 803 // Internal getter/setter for the frame element, this version of the 804 // getter crosses chrome boundaries whereas the public scriptable 805 // one doesn't for security reasons. 806 mozilla::dom::Element* GetFrameElementInternal() const; 807 void SetFrameElementInternal(mozilla::dom::Element* aFrameElement); 808 809 bool IsBackground() { return mIsBackground; } 810 811 // Audio API 812 bool GetAudioMuted() const; 813 814 // No longer to delay media from starting for this window. 815 void ActivateMediaComponents(); 816 bool ShouldDelayMediaFromStart() const; 817 818 void RefreshMediaElementsVolume(); 819 820 virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0; 821 822 /** 823 * |top| gets the root of the window hierarchy. 824 * 825 * This function does not cross chrome-content boundaries, so if this 826 * window's parent is of a different type, |top| will return this window. 827 * 828 * When script reads the top property, we run GetInProcessScriptableTop, 829 * which will not cross an <iframe mozbrowser> boundary. 830 * 831 * In contrast, C++ calls to GetTop are forwarded to GetRealTop, which 832 * ignores <iframe mozbrowser> boundaries. 833 */ 834 835 virtual already_AddRefed<nsPIDOMWindowOuter> 836 GetInProcessTop() = 0; // Outer only 837 virtual already_AddRefed<nsPIDOMWindowOuter> GetInProcessParent() = 0; 838 virtual nsPIDOMWindowOuter* GetInProcessScriptableTop() = 0; 839 virtual nsPIDOMWindowOuter* GetInProcessScriptableParent() = 0; 840 virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0; 841 842 /** 843 * Behaves identically to GetInProcessScriptableParent except that it 844 * returns null if GetInProcessScriptableParent would return this window. 845 */ 846 virtual nsPIDOMWindowOuter* GetInProcessScriptableParentOrNull() = 0; 847 848 virtual void SetIsBackground(bool aIsBackground) = 0; 849 850 mozilla::dom::EventTarget* GetChromeEventHandler() const { 851 return mChromeEventHandler; 852 } 853 854 virtual void SetChromeEventHandler( 855 mozilla::dom::EventTarget* aChromeEventHandler) = 0; 856 857 mozilla::dom::EventTarget* GetParentTarget() { 858 if (!mParentTarget) { 859 UpdateParentTarget(); 860 } 861 return mParentTarget; 862 } 863 864 mozilla::dom::ContentFrameMessageManager* GetMessageManager() { 865 // We maintain our mMessageManager state alongside mParentTarget. 866 if (!mParentTarget) { 867 UpdateParentTarget(); 868 } 869 return mMessageManager; 870 } 871 872 Document* GetExtantDoc() const { return mDoc; } 873 nsIURI* GetDocumentURI() const; 874 875 Document* GetDoc() { 876 if (!mDoc) { 877 MaybeCreateDoc(); 878 } 879 return mDoc; 880 } 881 882 // Set the window up with an about:blank document with the given principal. 883 // Base URI, COEP and PolicyContainer of the current document will be 884 // retained. 885 virtual void SetInitialPrincipal(nsIPrincipal* aNewWindowPrincipal) = 0; 886 887 // Returns an object containing the window's state. This also suspends 888 // all running timeouts in the window. 889 virtual already_AddRefed<nsISupports> SaveWindowState() = 0; 890 891 // Restore the window state from aState. 892 virtual nsresult RestoreWindowState(nsISupports* aState) = 0; 893 894 // Fire any DOM notification events related to things that happened while 895 // the window was frozen. 896 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) = 0; 897 898 /** 899 * Get the docshell in this window. 900 */ 901 inline nsIDocShell* GetDocShell() const; 902 903 /** 904 * Get the browsing context in this window. 905 */ 906 inline mozilla::dom::BrowsingContext* GetBrowsingContext() const; 907 908 /** 909 * Get the browsing context group this window belongs to. 910 */ 911 mozilla::dom::BrowsingContextGroup* GetBrowsingContextGroup() const; 912 913 /** 914 * Set a new document in the window. Calling this method will in most cases 915 * create a new inner window. This may be called with a pointer to the current 916 * document, in that case the document remains unchanged, but a new inner 917 * window will be created. 918 * 919 * aDocument must not be null. 920 */ 921 virtual nsresult SetNewDocument( 922 Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow, 923 mozilla::dom::WindowGlobalChild* aActor = nullptr) = 0; 924 925 /** 926 * Ensure the size and position of this window are up-to-date by doing 927 * a layout flush in the parent (which will in turn, do a layout flush 928 * in its parent, etc.). 929 */ 930 virtual void EnsureSizeAndPositionUpToDate() = 0; 931 932 /** 933 * Suppresses/unsuppresses user initiated event handling in window's document 934 * and all in-process descendant documents. 935 */ 936 virtual void SuppressEventHandling() = 0; 937 virtual void UnsuppressEventHandling() = 0; 938 939 /** 940 * Callback for notifying a window about a modal dialog being 941 * opened/closed with the window as a parent. 942 * 943 * If any script can run between the enter and leave modal states, and the 944 * window isn't top, the LeaveModalState() should be called on the window 945 * returned by EnterModalState(). 946 */ 947 virtual nsPIDOMWindowOuter* EnterModalState() = 0; 948 virtual void LeaveModalState() = 0; 949 950 virtual bool CanClose() = 0; 951 virtual void ForceClose() = 0; 952 953 /** 954 * Moves the top-level window into fullscreen mode if aIsFullScreen is true, 955 * otherwise exits fullscreen. 956 */ 957 virtual nsresult SetFullscreenInternal(FullscreenReason aReason, 958 bool aIsFullscreen) = 0; 959 virtual void FullscreenWillChange(bool aIsFullscreen) = 0; 960 /** 961 * This function should be called when the fullscreen state is flipped. 962 * If no widget is involved the fullscreen change, this method is called 963 * by SetFullscreenInternal, otherwise, it is called when the widget 964 * finishes its change to or from fullscreen. 965 * 966 * @param aIsFullscreen indicates whether the widget is in fullscreen. 967 */ 968 virtual void FinishFullscreenChange(bool aIsFullscreen) = 0; 969 970 virtual void ForceFullScreenInWidget() = 0; 971 972 virtual void MacFullscreenMenubarOverlapChanged( 973 mozilla::DesktopCoord aOverlapAmount) = 0; 974 975 // XXX: These focus methods all forward to the inner, could we change 976 // consumers to call these on the inner directly? 977 978 /* 979 * Get and set the currently focused element within the document. If 980 * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a 981 * document focus event is needed. 982 * 983 * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER 984 * INSTEAD. 985 */ 986 inline mozilla::dom::Element* GetFocusedElement() const; 987 988 virtual void SetFocusedElement(mozilla::dom::Element* aElement, 989 uint32_t aFocusMethod = 0, 990 bool aNeedsFocus = false) = 0; 991 /** 992 * Get whether a focused element focused by unknown reasons (like script 993 * focus) should match the :focus-visible pseudo-class. 994 */ 995 bool UnknownFocusMethodShouldShowOutline() const; 996 997 /** 998 * Retrieves the method that was used to focus the current node. 999 */ 1000 virtual uint32_t GetFocusMethod() = 0; 1001 1002 /* 1003 * Tells the window that it now has focus or has lost focus, based on the 1004 * state of aFocus. If this method returns true, then the document loaded 1005 * in the window has never received a focus event and expects to receive 1006 * one. If false is returned, the document has received a focus event before 1007 * and should only receive one if the window is being focused. 1008 * 1009 * aFocusMethod may be set to one of the focus method constants in 1010 * nsIFocusManager to indicate how focus was set. 1011 */ 1012 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0; 1013 1014 /** 1015 * Indicates that the window may now accept a document focus event. This 1016 * should be called once a document has been loaded into the window. 1017 */ 1018 virtual void SetReadyForFocus() = 0; 1019 1020 /** 1021 * Whether the focused content within the window should show a focus ring. 1022 */ 1023 virtual bool ShouldShowFocusRing() = 0; 1024 1025 /** 1026 * Indicates that the page in the window has been hidden. This is used to 1027 * reset the focus state. 1028 */ 1029 virtual void PageHidden(bool aIsEnteringBFCacheInParent) = 0; 1030 1031 /** 1032 * Return the window id of this window 1033 */ 1034 uint64_t WindowID() const { return mWindowID; } 1035 1036 /** 1037 * Dispatch a custom event with name aEventName targeted at this window. 1038 * Returns whether the default action should be performed. 1039 * 1040 * Outer windows only. 1041 */ 1042 virtual bool DispatchCustomEvent( 1043 const nsAString& aEventName, 1044 mozilla::ChromeOnlyDispatch aChromeOnlyDispatch = 1045 mozilla::ChromeOnlyDispatch::eNo) = 0; 1046 1047 /** 1048 * Like nsIDOMWindow::Open, except that we don't navigate to the given URL. 1049 * 1050 * Outer windows only. 1051 */ 1052 virtual nsresult OpenNoNavigate(const nsACString& aUrl, 1053 const nsAString& aName, 1054 const nsAString& aOptions, 1055 mozilla::dom::BrowsingContext** _retval) = 0; 1056 1057 /** 1058 * Fire a popup blocked event. 1059 */ 1060 virtual void FirePopupBlockedEvent(nsIURI* aPopupURI, 1061 const nsAString& aPopupWindowName, 1062 const nsAString& aPopupWindowFeatures) = 0; 1063 1064 /** 1065 * Fire a redirect blocked event. 1066 */ 1067 virtual void FireRedirectBlockedEvent(nsIURI* aRedirectURI) = 0; 1068 1069 // WebIDL-ish APIs 1070 void MarkUncollectableForCCGeneration(uint32_t aGeneration) { 1071 mMarkedCCGeneration = aGeneration; 1072 } 1073 1074 uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; } 1075 1076 // XXX(nika): These feel like they should be inner window only, but they're 1077 // called on the outer window. 1078 virtual mozilla::dom::Navigator* GetNavigator() = 0; 1079 virtual mozilla::dom::Location* GetLocation() = 0; 1080 1081 virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0; 1082 virtual nsresult GetControllers(nsIControllers** aControllers) = 0; 1083 virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0; 1084 virtual mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> 1085 GetOpener() = 0; 1086 1087 // aLoadState will be passed on through to the windowwatcher. 1088 // aForceNoOpener will act just like a "noopener" feature in aOptions except 1089 // will not affect any other window features. 1090 virtual nsresult Open(const nsACString& aUrl, const nsAString& aName, 1091 const nsAString& aOptions, 1092 nsDocShellLoadState* aLoadState, bool aForceNoOpener, 1093 mozilla::dom::BrowsingContext** _retval) = 0; 1094 virtual nsresult OpenDialog(const nsACString& aUrl, const nsAString& aName, 1095 const nsAString& aOptions, nsIArray* aArguments, 1096 mozilla::dom::BrowsingContext** _retval) = 0; 1097 1098 MOZ_CAN_RUN_SCRIPT virtual nsresult GetInnerWidth(double* aWidth) = 0; 1099 MOZ_CAN_RUN_SCRIPT virtual nsresult GetInnerHeight(double* aHeight) = 0; 1100 1101 virtual mozilla::dom::Element* GetFrameElement() = 0; 1102 1103 virtual bool Closed() = 0; 1104 virtual bool GetFullScreen() = 0; 1105 virtual nsresult SetFullScreen(bool aFullscreen) = 0; 1106 1107 virtual nsresult Focus(mozilla::dom::CallerType aCallerType) = 0; 1108 virtual nsresult Close() = 0; 1109 1110 virtual nsresult MoveBy(int32_t aXDif, int32_t aYDif) = 0; 1111 1112 virtual void UpdateCommands(const nsAString& anAction) = 0; 1113 1114 mozilla::dom::DocGroup* GetDocGroup() const; 1115 1116 already_AddRefed<nsIDocShellTreeOwner> GetTreeOwner(); 1117 already_AddRefed<nsIBaseWindow> GetTreeOwnerWindow(); 1118 already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome(); 1119 1120 virtual void UpdateParentTarget() = 0; 1121 1122 protected: 1123 // Lazily instantiate an about:blank document if necessary, and if 1124 // we have what it takes to do so. 1125 void MaybeCreateDoc(); 1126 1127 void SetChromeEventHandlerInternal( 1128 mozilla::dom::EventTarget* aChromeEventHandler); 1129 1130 // These two variables are special in that they're set to the same 1131 // value on both the outer window and the current inner window. Make 1132 // sure you keep them in sync! 1133 nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong 1134 RefPtr<Document> mDoc; 1135 // Cache the URI when mDoc is cleared. 1136 nsCOMPtr<nsIURI> mDocumentURI; // strong 1137 1138 nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong 1139 RefPtr<mozilla::dom::ContentFrameMessageManager> mMessageManager; // strong 1140 1141 nsCOMPtr<mozilla::dom::Element> mFrameElement; 1142 1143 // These references are used by nsGlobalWindow. 1144 nsCOMPtr<nsIDocShell> mDocShell; 1145 RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext; 1146 1147 uint32_t mModalStateDepth; 1148 1149 uint32_t mSuppressEventHandlingDepth; 1150 1151 // Tracks whether our docshell is active. If it is, mIsBackground 1152 // is false. Too bad we have so many different concepts of 1153 // "active". 1154 bool mIsBackground; 1155 1156 bool mIsRootOuterWindow; 1157 1158 // And these are the references between inner and outer windows. 1159 nsPIDOMWindowInner* MOZ_NON_OWNING_REF mInnerWindow; 1160 1161 // A unique (as long as our 64-bit counter doesn't roll over) id for 1162 // this window. 1163 uint64_t mWindowID; 1164 1165 uint32_t mMarkedCCGeneration; 1166 }; 1167 1168 #include "nsPIDOMWindowInlines.h" 1169 1170 #endif // nsPIDOMWindow_h__