Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / base / nsPIDOMWindow.h
bloba75741697eecc5be6e082ce0f8cd22813d5332ec
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsPIDOMWindow_h__
8 #define nsPIDOMWindow_h__
10 #include "nsIDOMWindow.h"
11 #include "mozIDOMWindow.h"
13 #include "nsCOMPtr.h"
14 #include "nsTArray.h"
15 #include "Units.h"
16 #include "mozilla/dom/EventTarget.h"
17 #include "mozilla/EventForwards.h"
18 #include "mozilla/Maybe.h"
19 #include "js/TypeDecls.h"
20 #include "nsRefPtrHashtable.h"
21 #include "nsILoadInfo.h"
22 #include "mozilla/MozPromise.h"
24 class nsGlobalWindowInner;
25 class nsGlobalWindowOuter;
26 class nsIArray;
27 class nsIBaseWindow;
28 class nsIChannel;
29 class nsIContent;
30 class nsIContentSecurityPolicy;
31 class nsICSSDeclaration;
32 class nsIDocShell;
33 class nsIDocShellTreeOwner;
34 class nsDocShellLoadState;
35 class nsIPrincipal;
36 class nsIRunnable;
37 class nsIScriptTimeoutHandler;
38 class nsISerialEventTarget;
39 class nsIURI;
40 class nsIWebBrowserChrome;
41 class nsPIDOMWindowInner;
42 class nsPIDOMWindowOuter;
43 class nsPIWindowRoot;
45 using SuspendTypes = uint32_t;
47 namespace mozilla::dom {
48 class AudioContext;
49 class BrowsingContext;
50 class BrowsingContextGroup;
51 class ClientInfo;
52 class ClientState;
53 class ContentFrameMessageManager;
54 class CloseWatcherManager;
55 class DocGroup;
56 class Document;
57 class Element;
58 class Location;
59 class MediaDevices;
60 class MediaKeys;
61 class Navigator;
62 class Performance;
63 class Selection;
64 class ServiceWorker;
65 class ServiceWorkerDescriptor;
66 class Timeout;
67 class TimeoutManager;
68 class WindowContext;
69 class WindowGlobalChild;
70 class CustomElementRegistry;
71 enum class CallerType : uint32_t;
72 } // namespace mozilla::dom
74 enum class FullscreenReason {
75 // Toggling the fullscreen mode requires trusted context.
76 ForFullscreenMode,
77 // Fullscreen API is the API provided to untrusted content.
78 ForFullscreenAPI,
79 // This reason can only be used with exiting fullscreen.
80 // It is otherwise identical to eForFullscreenAPI except it would
81 // suppress the fullscreen transition.
82 ForForceExitFullscreen
85 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
86 #define NS_PIDOMWINDOWINNER_IID \
87 {0x775dabc9, 0x8f43, 0x4277, {0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb}}
89 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
90 #define NS_PIDOMWINDOWOUTER_IID \
91 {0x769693d4, 0xb009, 0x4fe2, {0xaf, 0x18, 0x7d, 0xc8, 0xdf, 0x74, 0x96, 0xdf}}
93 class nsPIDOMWindowInner : public mozIDOMWindow {
94 protected:
95 using Document = mozilla::dom::Document;
96 friend nsGlobalWindowInner;
97 friend nsGlobalWindowOuter;
99 nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
100 mozilla::dom::WindowGlobalChild* aActor);
102 ~nsPIDOMWindowInner();
104 public:
105 NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOWINNER_IID)
107 nsIGlobalObject* AsGlobal();
108 const nsIGlobalObject* AsGlobal() const;
110 nsPIDOMWindowOuter* GetOuterWindow() const { return mOuterWindow; }
112 static nsPIDOMWindowInner* From(mozIDOMWindow* aFrom) {
113 return static_cast<nsPIDOMWindowInner*>(aFrom);
116 NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(nsPIDOMWindowInner,
117 GetAsInnerWindow())
119 // Returns true if this object is the currently-active inner window for its
120 // BrowsingContext.
121 bool IsCurrentInnerWindow() const;
123 // Returns true if the document of this window is the active document. This
124 // is identical to IsCurrentInnerWindow() now that document.open() no longer
125 // creates new inner windows for the document it is called on.
126 inline bool HasActiveDocument() const;
128 // Return true if this object is the currently-active inner window for its
129 // BrowsingContext and any container document is also fully active.
130 // For https://html.spec.whatwg.org/multipage/browsers.html#fully-active
131 bool IsFullyActive() const;
133 // Returns true if this window is the same as mTopInnerWindow
134 inline bool IsTopInnerWindow() const;
136 // Returns true if this was the current window for its BrowsingContext when it
137 // was discarded.
138 virtual bool WasCurrentInnerWindow() const = 0;
140 // Check whether a document is currently loading (really checks if the
141 // load event has completed). May not be reset to false on errors.
142 inline bool IsLoading() const;
143 inline bool IsHandlingResizeEvent() const;
145 // Note: not related to IsLoading. Set to false if there's an error, etc.
146 virtual void SetActiveLoadingState(bool aIsActiveLoading) = 0;
148 bool AddAudioContext(mozilla::dom::AudioContext* aAudioContext);
149 void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext);
150 void MuteAudioContexts();
151 void UnmuteAudioContexts();
153 void SetAudioCapture(bool aCapture);
156 * Associate this inner window with a MediaKeys instance.
158 void AddMediaKeysInstance(mozilla::dom::MediaKeys* aMediaKeysInstance);
161 * Remove an association between this inner window and a MediaKeys instance.
163 void RemoveMediaKeysInstance(mozilla::dom::MediaKeys* aMediaKeysInstance);
166 * Return if any MediaKeys instances are associated with this window.
168 bool HasActiveMediaKeysInstance();
170 mozilla::dom::Performance* GetPerformance();
172 void QueuePerformanceNavigationTiming();
174 bool HasMutationListeners(uint32_t aMutationEventType) const {
175 if (!mOuterWindow) {
176 NS_ERROR("HasMutationListeners() called on orphan inner window!");
178 return false;
181 return (mMutationBits & aMutationEventType) != 0;
184 void SetMutationListeners(uint32_t aType) {
185 if (!mOuterWindow) {
186 NS_ERROR("HasMutationListeners() called on orphan inner window!");
188 return;
191 mMutationBits |= aType;
195 * Call this to check whether some node (this window, its document,
196 * or content in that document) has a mouseenter/leave event listener.
198 bool HasMouseEnterLeaveEventListeners() const {
199 return mMayHaveMouseEnterLeaveEventListener;
203 * Call this to indicate that some node (this window, its document,
204 * or content in that document) has a mouseenter/leave event listener.
206 void SetHasMouseEnterLeaveEventListeners() {
207 mMayHaveMouseEnterLeaveEventListener = true;
211 * Call this to check whether some node (this window, its document,
212 * or content in that document) has a Pointerenter/leave event listener.
214 bool HasPointerEnterLeaveEventListeners() const {
215 return mMayHavePointerEnterLeaveEventListener;
219 * Call this to indicate that some node (this window, its document,
220 * or content in that document) has a Pointerenter/leave event listener.
222 void SetHasPointerEnterLeaveEventListeners() {
223 mMayHavePointerEnterLeaveEventListener = true;
227 * Call this to check whether some node (this window, its document,
228 * or content in that document) has a transition* event listeners.
230 bool HasTransitionEventListeners() { return mMayHaveTransitionEventListener; }
233 * Call this to indicate that some node (this window, its document,
234 * or content in that document) has a transition* event listener.
236 void SetHasTransitionEventListeners() {
237 mMayHaveTransitionEventListener = true;
241 * Call this to check whether some node (this window, its document,
242 * or content in that document) has a SMILTime* event listeners.
244 bool HasSMILTimeEventListeners() { return mMayHaveSMILTimeEventListener; }
247 * Call this to indicate that some node (this window, its document,
248 * or content in that document) has a SMILTime* event listener.
250 void SetHasSMILTimeEventListeners() { mMayHaveSMILTimeEventListener = true; }
253 * Call this to check whether some node (this window, its document,
254 * or content in that document) has a beforeinput event listener.
255 * Returing false may be wrong if some nodes have come from another document
256 * with `Document.adoptNode`.
258 bool HasBeforeInputEventListenersForTelemetry() const {
259 return mMayHaveBeforeInputEventListenerForTelemetry;
263 * Call this to indicate that some node (this window, its document,
264 * or content in that document) has a beforeinput event listener.
266 void SetHasBeforeInputEventListenersForTelemetry() {
267 mMayHaveBeforeInputEventListenerForTelemetry = true;
271 * Call this to check whether some node (The document, or content in the
272 * document) has been observed by web apps with a mutation observer.
273 * (i.e., `MutationObserver.observe()` called by chrome script and addon's
274 * script does not make this returns true).
275 * Returing false may be wrong if some nodes have come from another document
276 * with `Document.adoptNode`.
278 bool MutationObserverHasObservedNodeForTelemetry() const {
279 return mMutationObserverHasObservedNodeForTelemetry;
283 * Call this to indicate that some node (The document, or content in the
284 * document) is observed by web apps with a mutation observer.
286 void SetMutationObserverHasObservedNodeForTelemetry() {
287 mMutationObserverHasObservedNodeForTelemetry = true;
290 // Sets the event for window.event. Does NOT take ownership, so
291 // the caller is responsible for clearing the event before the
292 // event gets deallocated. Pass nullptr to set window.event to
293 // undefined. Returns the previous value.
294 mozilla::dom::Event* SetEvent(mozilla::dom::Event* aEvent) {
295 mozilla::dom::Event* old = mEvent;
296 mEvent = aEvent;
297 return old;
301 * Check whether this window is a secure context.
303 bool IsSecureContext() const;
304 bool IsSecureContextIfOpenerIgnored() const;
306 // Calling suspend should prevent any asynchronous tasks from
307 // executing javascript for this window. This means setTimeout,
308 // requestAnimationFrame, and events should not be fired. Suspending
309 // a window maybe also suspends its children. Workers may
310 // continue to perform computations in the background. A window
311 // can have Suspend() called multiple times and will only resume after
312 // a matching number of Resume() calls.
313 void Suspend(bool aIncludeSubWindows = true);
314 void Resume(bool aIncludeSubWindows = true);
316 // Whether or not this window was suspended by the BrowserContextGroup
317 bool GetWasSuspendedByGroup() const { return mWasSuspendedByGroup; }
318 void SetWasSuspendedByGroup(bool aSuspended) {
319 mWasSuspendedByGroup = aSuspended;
322 // Apply the parent window's suspend, freeze, and modal state to the current
323 // window.
324 void SyncStateFromParentWindow();
327 * Increment active peer connection count.
329 void AddPeerConnection();
332 * Decrement active peer connection count.
334 void RemovePeerConnection();
336 bool IsDocumentLoaded() const;
338 // To cache top inner-window if available after constructed for tab-wised
339 // indexedDB counters.
340 void TryToCacheTopInnerWindow();
342 // Increase/Decrease the number of active IndexedDB databases for the
343 // decision making of timeout-throttling.
344 void UpdateActiveIndexedDBDatabaseCount(int32_t aDelta);
346 // Increase/Decrease the number of open WebSockets.
347 void UpdateWebSocketCount(int32_t aDelta);
349 mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const;
350 mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
351 mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
353 void SetCsp(nsIContentSecurityPolicy* aCsp);
354 void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp);
355 nsIContentSecurityPolicy* GetCsp();
357 void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
359 void NoteDOMContentLoaded();
361 virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0;
363 // XXX: This is called on inner windows
364 virtual nsPIDOMWindowOuter* GetInProcessScriptableTop() = 0;
365 virtual nsPIDOMWindowOuter* GetInProcessScriptableParent() = 0;
366 virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
368 mozilla::dom::EventTarget* GetChromeEventHandler() const {
369 return mChromeEventHandler;
372 mozilla::dom::EventTarget* GetParentTarget() {
373 if (!mParentTarget) {
374 UpdateParentTarget();
376 return mParentTarget;
379 virtual void MaybeUpdateTouchState() {}
381 Document* GetExtantDoc() const { return mDoc; }
382 nsIURI* GetDocumentURI() const;
383 nsIURI* GetDocBaseURI() const;
385 Document* GetDoc() {
386 if (!mDoc) {
387 MaybeCreateDoc();
389 return mDoc;
392 mozilla::dom::WindowContext* GetWindowContext() const;
393 mozilla::dom::WindowGlobalChild* GetWindowGlobalChild() const {
394 return mWindowGlobalChild;
397 // Removes this inner window from the BFCache, if it is cached, and returns
398 // true if it was.
399 bool RemoveFromBFCacheSync();
401 // Fire any DOM notification events related to things that happened while
402 // the window was frozen.
403 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) = 0;
406 * Get the docshell in this window.
408 inline nsIDocShell* GetDocShell() const;
411 * Get the browsing context in this window.
413 inline mozilla::dom::BrowsingContext* GetBrowsingContext() const;
416 * Get the browsing context group this window belongs to.
418 mozilla::dom::BrowsingContextGroup* GetBrowsingContextGroup() const;
421 * Call this to indicate that some node (this window, its document,
422 * or content in that document) has a DOMActivate event listener.
424 void SetHasDOMActivateEventListeners() {
425 mMayHaveDOMActivateEventListeners = true;
429 * Call this to check whether some node (this window, its document,
430 * or content in that document) has a DOMActivate event listener.
432 bool HasDOMActivateEventListeners() const {
433 return mMayHaveDOMActivateEventListeners;
437 * Call this to indicate that some node (this window, its document,
438 * or content in that document) has a paint event listener.
440 void SetHasPaintEventListeners() { mMayHavePaintEventListener = true; }
443 * Call this to check whether some node (this window, its document,
444 * or content in that document) has a paint event listener.
446 bool HasPaintEventListeners() { return mMayHavePaintEventListener; }
449 * Call this to indicate that some node (this window, its document,
450 * or content in that document) has a touch event listener.
452 void SetHasTouchEventListeners() {
453 if (!mMayHaveTouchEventListener) {
454 mMayHaveTouchEventListener = true;
455 MaybeUpdateTouchState();
460 * Call this to indicate that some node (this window, its document,
461 * or content in that document) has a selectionchange event listener.
463 void SetHasSelectionChangeEventListeners() {
464 mMayHaveSelectionChangeEventListener = true;
468 * Call this to check whether some node (this window, its document,
469 * or content in that document) has a selectionchange event listener.
471 bool HasSelectionChangeEventListeners() const {
472 return mMayHaveSelectionChangeEventListener;
476 * Call this to indicate that some node (this window, its document,
477 * or content in that document) has a select event listener of form controls.
479 void SetHasFormSelectEventListeners() {
480 mMayHaveFormSelectEventListener = true;
484 * Call this to check whether some node (this window, its document,
485 * or content in that document) has a select event listener of form controls.
487 bool HasFormSelectEventListeners() const {
488 return mMayHaveFormSelectEventListener;
492 * Get and set the currently focused element within the document. If
493 * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
494 * document focus event is needed.
496 * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
497 * INSTEAD.
499 mozilla::dom::Element* GetFocusedElement() const {
500 return mFocusedElement.get();
503 virtual void SetFocusedElement(mozilla::dom::Element* aElement,
504 uint32_t aFocusMethod = 0,
505 bool aNeedsFocus = false) = 0;
507 bool UnknownFocusMethodShouldShowOutline() const {
508 return mUnknownFocusMethodShouldShowOutline;
512 * Retrieves the method that was used to focus the current node.
514 virtual uint32_t GetFocusMethod() = 0;
517 * Tells the window that it now has focus or has lost focus, based on the
518 * state of aFocus. If this method returns true, then the document loaded
519 * in the window has never received a focus event and expects to receive
520 * one. If false is returned, the document has received a focus event before
521 * and should only receive one if the window is being focused.
523 * aFocusMethod may be set to one of the focus method constants in
524 * nsIFocusManager to indicate how focus was set.
526 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0;
529 * Indicates that the window may now accept a document focus event. This
530 * should be called once a document has been loaded into the window.
532 virtual void SetReadyForFocus() = 0;
535 * Whether the focused content within the window should show a focus ring.
537 virtual bool ShouldShowFocusRing() = 0;
540 * Indicates that the page in the window has been hidden. This is used to
541 * reset the focus state.
543 virtual void PageHidden(bool aIsEnteringBFCacheInParent) = 0;
546 * Instructs this window to asynchronously dispatch a hashchange event. This
547 * method must be called on an inner window.
549 virtual nsresult DispatchAsyncHashchange(nsIURI* aOldURI,
550 nsIURI* aNewURI) = 0;
553 * Instructs this window to synchronously dispatch a popState event.
555 virtual nsresult DispatchSyncPopState() = 0;
558 * Tell this window that it should listen for sensor changes of the given
559 * type.
561 virtual void EnableDeviceSensor(uint32_t aType) = 0;
564 * Tell this window that it should remove itself from sensor change
565 * notifications.
567 virtual void DisableDeviceSensor(uint32_t aType) = 0;
569 #if defined(MOZ_WIDGET_ANDROID)
570 virtual void EnableOrientationChangeListener() = 0;
571 virtual void DisableOrientationChangeListener() = 0;
572 #endif
575 * Tell this window that there is an observer for gamepad input
577 * Inner windows only.
579 virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0;
582 * Return the window id of this window
584 uint64_t WindowID() const { return mWindowID; }
586 // WebIDL-ish APIs
587 void MarkUncollectableForCCGeneration(uint32_t aGeneration) {
588 mMarkedCCGeneration = aGeneration;
591 uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; }
593 mozilla::dom::Navigator* Navigator();
594 mozilla::dom::MediaDevices* GetExtantMediaDevices() const;
595 virtual mozilla::dom::Location* Location() = 0;
597 virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
599 virtual nsresult GetInnerWidth(double* aWidth) = 0;
600 virtual nsresult GetInnerHeight(double* aHeight) = 0;
602 virtual already_AddRefed<nsICSSDeclaration> GetComputedStyle(
603 mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
604 mozilla::ErrorResult& aError) = 0;
606 virtual bool GetFullScreen() = 0;
608 virtual nsresult Focus(mozilla::dom::CallerType aCallerType) = 0;
609 virtual nsresult Close() = 0;
611 mozilla::dom::DocGroup* GetDocGroup() const;
613 RefPtr<mozilla::GenericPromise> SaveStorageAccessPermissionGranted();
614 RefPtr<mozilla::GenericPromise> SaveStorageAccessPermissionRevoked();
616 bool UsingStorageAccess();
618 uint32_t UpdateLockCount(bool aIncrement) {
619 MOZ_ASSERT_IF(!aIncrement, mLockCount > 0);
620 mLockCount += aIncrement ? 1 : -1;
621 return mLockCount;
623 bool HasActiveLocks() { return mLockCount > 0; }
625 uint32_t UpdateWebTransportCount(bool aIncrement) {
626 MOZ_ASSERT_IF(!aIncrement, mWebTransportCount > 0);
627 mWebTransportCount += aIncrement ? 1 : -1;
628 return mWebTransportCount;
630 bool HasActiveWebTransports() { return mWebTransportCount > 0; }
632 mozilla::dom::CloseWatcherManager* EnsureCloseWatcherManager();
634 protected:
635 void CreatePerformanceObjectIfNeeded();
637 // Lazily instantiate an about:blank document if necessary, and if
638 // we have what it takes to do so.
639 void MaybeCreateDoc();
641 void SetChromeEventHandlerInternal(
642 mozilla::dom::EventTarget* aChromeEventHandler) {
643 mChromeEventHandler = aChromeEventHandler;
644 // mParentTarget will be set when the next event is dispatched.
645 mParentTarget = nullptr;
648 virtual void UpdateParentTarget() = 0;
650 // These two variables are special in that they're set to the same
651 // value on both the outer window and the current inner window. Make
652 // sure you keep them in sync!
653 nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong
654 RefPtr<Document> mDoc;
655 // Cache the URI when mDoc is cleared.
656 nsCOMPtr<nsIURI> mDocumentURI; // strong
657 nsCOMPtr<nsIURI> mDocBaseURI; // strong
659 nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong
661 RefPtr<mozilla::dom::Performance> mPerformance;
662 mozilla::UniquePtr<mozilla::dom::TimeoutManager> mTimeoutManager;
664 RefPtr<mozilla::dom::Navigator> mNavigator;
666 // These variables are only used on inner windows.
667 uint32_t mMutationBits;
669 uint32_t mActivePeerConnections = 0;
671 bool mIsDocumentLoaded;
672 bool mIsHandlingResizeEvent;
673 bool mMayHaveDOMActivateEventListeners;
674 bool mMayHavePaintEventListener;
675 bool mMayHaveTouchEventListener;
676 bool mMayHaveSelectionChangeEventListener;
677 bool mMayHaveFormSelectEventListener;
678 bool mMayHaveMouseEnterLeaveEventListener;
679 bool mMayHavePointerEnterLeaveEventListener;
680 bool mMayHaveTransitionEventListener;
681 bool mMayHaveSMILTimeEventListener;
682 // Only used for telemetry probes. This may be wrong if some nodes have
683 // come from another document with `Document.adoptNode`.
684 bool mMayHaveBeforeInputEventListenerForTelemetry;
685 bool mMutationObserverHasObservedNodeForTelemetry;
687 // Our inner window's outer window.
688 nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
690 // The element within the document that is currently focused when this
691 // window is active.
692 RefPtr<mozilla::dom::Element> mFocusedElement;
694 // The AudioContexts created for the current document, if any.
695 nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak
697 // Instances of MediaKeys created in this inner window. Storing these allows
698 // us to shutdown MediaKeys when an inner windows is destroyed. We can also
699 // use the presence of MediaKeys to assess if a window has EME activity.
700 nsTArray<mozilla::dom::MediaKeys*> mMediaKeysInstances; // Weak
702 RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
704 // A unique (as long as our 64-bit counter doesn't roll over) id for
705 // this window.
706 uint64_t mWindowID;
708 // Set to true once we've sent the (chrome|content)-document-global-created
709 // notification.
710 bool mHasNotifiedGlobalCreated;
712 // Whether when focused via an "unknown" focus method, we should show outlines
713 // by default or not. The initial value of this is true (so as to show
714 // outlines for stuff like html autofocus, or initial programmatic focus
715 // without any other user interaction).
716 bool mUnknownFocusMethodShouldShowOutline = true;
718 uint32_t mMarkedCCGeneration;
720 // mTopInnerWindow is used for tab-wise check by timeout throttling. It could
721 // be null.
722 nsCOMPtr<nsPIDOMWindowInner> mTopInnerWindow;
724 // The evidence that we have tried to cache mTopInnerWindow only once from
725 // SetNewDocument(). Note: We need this extra flag because mTopInnerWindow
726 // could be null and we don't want it to be set multiple times.
727 bool mHasTriedToCacheTopInnerWindow;
729 // The number of active IndexedDB databases.
730 uint32_t mNumOfIndexedDBDatabases;
732 // The number of open WebSockets.
733 uint32_t mNumOfOpenWebSockets;
735 // The event dispatch code sets and unsets this while keeping
736 // the event object alive.
737 mozilla::dom::Event* mEvent;
739 // The WindowGlobalChild actor for this window.
741 // This will be non-null during the full lifetime of the window, initialized
742 // during SetNewDocument, and cleared during FreeInnerObjects.
743 RefPtr<mozilla::dom::WindowGlobalChild> mWindowGlobalChild;
745 bool mWasSuspendedByGroup;
748 * Count of the number of active LockRequest objects, including ones from
749 * workers.
751 uint32_t mLockCount = 0;
753 * Count of the number of active WebTransport objects, including ones from
754 * workers.
756 uint32_t mWebTransportCount = 0;
758 // The CloseWatcherManager for this window.
759 RefPtr<mozilla::dom::CloseWatcherManager> mCloseWatcherManager;
762 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
764 class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
765 protected:
766 using Document = mozilla::dom::Document;
768 explicit nsPIDOMWindowOuter(uint64_t aWindowID);
770 ~nsPIDOMWindowOuter();
772 void NotifyResumingDelayedMedia();
774 public:
775 NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOWOUTER_IID)
777 NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(nsPIDOMWindowOuter,
778 GetAsOuterWindow())
780 static nsPIDOMWindowOuter* From(mozIDOMWindowProxy* aFrom) {
781 return static_cast<nsPIDOMWindowOuter*>(aFrom);
784 // Given an inner window, return its outer if the inner is the current inner.
785 // Otherwise (argument null or not an inner or not current) return null.
786 static nsPIDOMWindowOuter* GetFromCurrentInner(nsPIDOMWindowInner* aInner);
788 // Check whether a document is currently loading
789 inline bool IsLoading() const;
790 inline bool IsHandlingResizeEvent() const;
792 nsPIDOMWindowInner* GetCurrentInnerWindow() const { return mInnerWindow; }
794 nsPIDOMWindowInner* EnsureInnerWindow() {
795 // GetDoc forces inner window creation if there isn't one already
796 GetDoc();
797 return GetCurrentInnerWindow();
800 bool IsRootOuterWindow() { return mIsRootOuterWindow; }
802 // Internal getter/setter for the frame element, this version of the
803 // getter crosses chrome boundaries whereas the public scriptable
804 // one doesn't for security reasons.
805 mozilla::dom::Element* GetFrameElementInternal() const;
806 void SetFrameElementInternal(mozilla::dom::Element* aFrameElement);
808 bool IsBackground() { return mIsBackground; }
810 // Audio API
811 bool GetAudioMuted() const;
813 // No longer to delay media from starting for this window.
814 void ActivateMediaComponents();
815 bool ShouldDelayMediaFromStart() const;
817 void RefreshMediaElementsVolume();
819 virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
822 * |top| gets the root of the window hierarchy.
824 * This function does not cross chrome-content boundaries, so if this
825 * window's parent is of a different type, |top| will return this window.
827 * When script reads the top property, we run GetInProcessScriptableTop,
828 * which will not cross an <iframe mozbrowser> boundary.
830 * In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
831 * ignores <iframe mozbrowser> boundaries.
834 virtual already_AddRefed<nsPIDOMWindowOuter>
835 GetInProcessTop() = 0; // Outer only
836 virtual already_AddRefed<nsPIDOMWindowOuter> GetInProcessParent() = 0;
837 virtual nsPIDOMWindowOuter* GetInProcessScriptableTop() = 0;
838 virtual nsPIDOMWindowOuter* GetInProcessScriptableParent() = 0;
839 virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
842 * Behaves identically to GetInProcessScriptableParent except that it
843 * returns null if GetInProcessScriptableParent would return this window.
845 virtual nsPIDOMWindowOuter* GetInProcessScriptableParentOrNull() = 0;
847 virtual void SetIsBackground(bool aIsBackground) = 0;
849 mozilla::dom::EventTarget* GetChromeEventHandler() const {
850 return mChromeEventHandler;
853 virtual void SetChromeEventHandler(
854 mozilla::dom::EventTarget* aChromeEventHandler) = 0;
856 mozilla::dom::EventTarget* GetParentTarget() {
857 if (!mParentTarget) {
858 UpdateParentTarget();
860 return mParentTarget;
863 mozilla::dom::ContentFrameMessageManager* GetMessageManager() {
864 // We maintain our mMessageManager state alongside mParentTarget.
865 if (!mParentTarget) {
866 UpdateParentTarget();
868 return mMessageManager;
871 Document* GetExtantDoc() const { return mDoc; }
872 nsIURI* GetDocumentURI() const;
874 Document* GetDoc() {
875 if (!mDoc) {
876 MaybeCreateDoc();
878 return mDoc;
881 // Set the window up with an about:blank document with the given principal and
882 // potentially a CSP and a COEP.
883 virtual void SetInitialPrincipal(
884 nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP,
885 const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep) = 0;
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;
891 // Restore the window state from aState.
892 virtual nsresult RestoreWindowState(nsISupports* aState) = 0;
894 // Fire any DOM notification events related to things that happened while
895 // the window was frozen.
896 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) = 0;
899 * Get the docshell in this window.
901 inline nsIDocShell* GetDocShell() const;
904 * Get the browsing context in this window.
906 inline mozilla::dom::BrowsingContext* GetBrowsingContext() const;
909 * Get the browsing context group this window belongs to.
911 mozilla::dom::BrowsingContextGroup* GetBrowsingContextGroup() const;
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.
919 * aDocument must not be null.
921 virtual nsresult SetNewDocument(
922 Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
923 mozilla::dom::WindowGlobalChild* aActor = nullptr) = 0;
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.).
930 virtual void EnsureSizeAndPositionUpToDate() = 0;
933 * Suppresses/unsuppresses user initiated event handling in window's document
934 * and all in-process descendant documents.
936 virtual void SuppressEventHandling() = 0;
937 virtual void UnsuppressEventHandling() = 0;
940 * Callback for notifying a window about a modal dialog being
941 * opened/closed with the window as a parent.
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().
947 virtual nsPIDOMWindowOuter* EnterModalState() = 0;
948 virtual void LeaveModalState() = 0;
950 virtual bool CanClose() = 0;
951 virtual void ForceClose() = 0;
954 * Moves the top-level window into fullscreen mode if aIsFullScreen is true,
955 * otherwise exits fullscreen.
957 virtual nsresult SetFullscreenInternal(FullscreenReason aReason,
958 bool aIsFullscreen) = 0;
959 virtual void FullscreenWillChange(bool aIsFullscreen) = 0;
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.
966 * @param aIsFullscreen indicates whether the widget is in fullscreen.
968 virtual void FinishFullscreenChange(bool aIsFullscreen) = 0;
970 virtual void ForceFullScreenInWidget() = 0;
972 virtual void MacFullscreenMenubarOverlapChanged(
973 mozilla::DesktopCoord aOverlapAmount) = 0;
975 // XXX: These focus methods all forward to the inner, could we change
976 // consumers to call these on the inner directly?
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.
983 * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
984 * INSTEAD.
986 inline mozilla::dom::Element* GetFocusedElement() const;
988 virtual void SetFocusedElement(mozilla::dom::Element* aElement,
989 uint32_t aFocusMethod = 0,
990 bool aNeedsFocus = false) = 0;
992 * Get whether a focused element focused by unknown reasons (like script
993 * focus) should match the :focus-visible pseudo-class.
995 bool UnknownFocusMethodShouldShowOutline() const;
998 * Retrieves the method that was used to focus the current node.
1000 virtual uint32_t GetFocusMethod() = 0;
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.
1009 * aFocusMethod may be set to one of the focus method constants in
1010 * nsIFocusManager to indicate how focus was set.
1012 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0;
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.
1018 virtual void SetReadyForFocus() = 0;
1021 * Whether the focused content within the window should show a focus ring.
1023 virtual bool ShouldShowFocusRing() = 0;
1026 * Indicates that the page in the window has been hidden. This is used to
1027 * reset the focus state.
1029 virtual void PageHidden(bool aIsEnteringBFCacheInParent) = 0;
1032 * Return the window id of this window
1034 uint64_t WindowID() const { return mWindowID; }
1037 * Dispatch a custom event with name aEventName targeted at this window.
1038 * Returns whether the default action should be performed.
1040 * Outer windows only.
1042 virtual bool DispatchCustomEvent(
1043 const nsAString& aEventName,
1044 mozilla::ChromeOnlyDispatch aChromeOnlyDispatch =
1045 mozilla::ChromeOnlyDispatch::eNo) = 0;
1048 * Like nsIDOMWindow::Open, except that we don't navigate to the given URL.
1050 * Outer windows only.
1052 virtual nsresult OpenNoNavigate(const nsACString& aUrl,
1053 const nsAString& aName,
1054 const nsAString& aOptions,
1055 mozilla::dom::BrowsingContext** _retval) = 0;
1058 * Fire a popup blocked event on the document.
1060 virtual void FirePopupBlockedEvent(Document* aDoc, nsIURI* aPopupURI,
1061 const nsAString& aPopupWindowName,
1062 const nsAString& aPopupWindowFeatures) = 0;
1064 // WebIDL-ish APIs
1065 void MarkUncollectableForCCGeneration(uint32_t aGeneration) {
1066 mMarkedCCGeneration = aGeneration;
1069 uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; }
1071 // XXX(nika): These feel like they should be inner window only, but they're
1072 // called on the outer window.
1073 virtual mozilla::dom::Navigator* GetNavigator() = 0;
1074 virtual mozilla::dom::Location* GetLocation() = 0;
1076 virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0;
1077 virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
1078 virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
1079 virtual mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
1080 GetOpener() = 0;
1082 // aLoadState will be passed on through to the windowwatcher.
1083 // aForceNoOpener will act just like a "noopener" feature in aOptions except
1084 // will not affect any other window features.
1085 virtual nsresult Open(const nsACString& aUrl, const nsAString& aName,
1086 const nsAString& aOptions,
1087 nsDocShellLoadState* aLoadState, bool aForceNoOpener,
1088 mozilla::dom::BrowsingContext** _retval) = 0;
1089 virtual nsresult OpenDialog(const nsACString& aUrl, const nsAString& aName,
1090 const nsAString& aOptions, nsIArray* aArguments,
1091 mozilla::dom::BrowsingContext** _retval) = 0;
1093 virtual nsresult GetInnerWidth(double* aWidth) = 0;
1094 virtual nsresult GetInnerHeight(double* aHeight) = 0;
1096 virtual mozilla::dom::Element* GetFrameElement() = 0;
1098 virtual bool Closed() = 0;
1099 virtual bool GetFullScreen() = 0;
1100 virtual nsresult SetFullScreen(bool aFullscreen) = 0;
1102 virtual nsresult Focus(mozilla::dom::CallerType aCallerType) = 0;
1103 virtual nsresult Close() = 0;
1105 virtual nsresult MoveBy(int32_t aXDif, int32_t aYDif) = 0;
1107 virtual void UpdateCommands(const nsAString& anAction) = 0;
1109 mozilla::dom::DocGroup* GetDocGroup() const;
1111 already_AddRefed<nsIDocShellTreeOwner> GetTreeOwner();
1112 already_AddRefed<nsIBaseWindow> GetTreeOwnerWindow();
1113 already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
1115 protected:
1116 // Lazily instantiate an about:blank document if necessary, and if
1117 // we have what it takes to do so.
1118 void MaybeCreateDoc();
1120 void SetChromeEventHandlerInternal(
1121 mozilla::dom::EventTarget* aChromeEventHandler);
1123 virtual void UpdateParentTarget() = 0;
1125 // These two variables are special in that they're set to the same
1126 // value on both the outer window and the current inner window. Make
1127 // sure you keep them in sync!
1128 nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong
1129 RefPtr<Document> mDoc;
1130 // Cache the URI when mDoc is cleared.
1131 nsCOMPtr<nsIURI> mDocumentURI; // strong
1133 nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong
1134 RefPtr<mozilla::dom::ContentFrameMessageManager> mMessageManager; // strong
1136 nsCOMPtr<mozilla::dom::Element> mFrameElement;
1138 // These references are used by nsGlobalWindow.
1139 nsCOMPtr<nsIDocShell> mDocShell;
1140 RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
1142 uint32_t mModalStateDepth;
1144 uint32_t mSuppressEventHandlingDepth;
1146 // Tracks whether our docshell is active. If it is, mIsBackground
1147 // is false. Too bad we have so many different concepts of
1148 // "active".
1149 bool mIsBackground;
1151 bool mIsRootOuterWindow;
1153 // And these are the references between inner and outer windows.
1154 nsPIDOMWindowInner* MOZ_NON_OWNING_REF mInnerWindow;
1156 // A unique (as long as our 64-bit counter doesn't roll over) id for
1157 // this window.
1158 uint64_t mWindowID;
1160 uint32_t mMarkedCCGeneration;
1163 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowOuter, NS_PIDOMWINDOWOUTER_IID)
1165 #include "nsPIDOMWindowInlines.h"
1167 #endif // nsPIDOMWindow_h__