tor-browser

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

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__