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 nsGlobalWindowInner_h___
8 #define nsGlobalWindowInner_h___
9 
10 #include "nsPIDOMWindow.h"
11 
12 #include "nsHashKeys.h"
13 #include "nsRefPtrHashtable.h"
14 #include "nsInterfaceHashtable.h"
15 
16 // Local Includes
17 // Helper Classes
18 #include "nsCOMPtr.h"
19 #include "nsAutoPtr.h"
20 #include "nsWeakReference.h"
21 #include "nsDataHashtable.h"
22 #include "nsJSThingHashtable.h"
23 #include "nsCycleCollectionParticipant.h"
24 
25 // Interfaces Needed
26 #include "nsIBrowserDOMWindow.h"
27 #include "nsIDOMEventTarget.h"
28 #include "nsIInterfaceRequestor.h"
29 #include "nsIDOMChromeWindow.h"
30 #include "nsIScriptGlobalObject.h"
31 #include "nsIScriptObjectPrincipal.h"
32 #include "nsITimer.h"
33 #include "mozilla/EventListenerManager.h"
34 #include "nsIPrincipal.h"
35 #include "nsSize.h"
36 #include "mozilla/FlushType.h"
37 #include "prclist.h"
38 #include "mozilla/dom/DOMPrefs.h"
39 #include "mozilla/dom/BindingDeclarations.h"
40 #include "mozilla/dom/StorageEvent.h"
41 #include "mozilla/dom/StorageEventBinding.h"
42 #include "mozilla/dom/UnionTypes.h"
43 #include "mozilla/ErrorResult.h"
44 #include "nsFrameMessageManager.h"
45 #include "mozilla/Attributes.h"
46 #include "mozilla/GuardObjects.h"
47 #include "mozilla/LinkedList.h"
48 #include "mozilla/TimeStamp.h"
49 #include "nsWrapperCacheInlines.h"
50 #include "nsIIdleObserver.h"
51 #include "nsIDocument.h"
52 #include "mozilla/dom/EventTarget.h"
53 #include "mozilla/dom/WindowBinding.h"
54 #include "Units.h"
55 #include "nsComponentManagerUtils.h"
56 #include "nsSize.h"
57 #include "nsCheapSets.h"
58 #include "mozilla/dom/ImageBitmapSource.h"
59 #include "mozilla/UniquePtr.h"
60 #include "nsRefreshDriver.h"
61 
62 class nsIArray;
63 class nsIBaseWindow;
64 class nsIContent;
65 class nsICSSDeclaration;
66 class nsIDocShellTreeOwner;
67 class nsIDOMOfflineResourceList;
68 class nsIScrollableFrame;
69 class nsIControllers;
70 class nsIJSID;
71 class nsIScriptContext;
72 class nsIScriptTimeoutHandler;
73 class nsITabChild;
74 class nsITimeoutHandler;
75 class nsIWebBrowserChrome;
76 class mozIDOMWindowProxy;
77 
78 class nsDOMWindowList;
79 class nsScreen;
80 class nsHistory;
81 class nsGlobalWindowObserver;
82 class nsGlobalWindowOuter;
83 class nsDOMWindowUtils;
84 class nsIIdleService;
85 struct nsRect;
86 
87 class nsWindowSizes;
88 
89 class IdleRequestExecutor;
90 
91 class DialogValueHolder;
92 
93 class PromiseDocumentFlushedResolver;
94 
95 namespace mozilla {
96 class AbstractThread;
97 class ThrottledEventQueue;
98 namespace dom {
99 class BarProp;
100 struct ChannelPixelLayout;
101 class ClientSource;
102 class Console;
103 class Crypto;
104 class CustomElementRegistry;
105 class DocGroup;
106 class External;
107 class Function;
108 class Gamepad;
109 enum class ImageBitmapFormat : uint8_t;
110 class IdleRequest;
111 class IdleRequestCallback;
112 class IncrementalRunnable;
113 class IntlUtils;
114 class Location;
115 class MediaQueryList;
116 class OwningExternalOrWindowProxy;
117 class Promise;
118 class PostMessageEvent;
119 struct RequestInit;
120 class RequestOrUSVString;
121 class Selection;
122 class SpeechSynthesis;
123 class TabGroup;
124 class Timeout;
125 class U2F;
126 class VRDisplay;
127 enum class VRDisplayEventReason : uint8_t;
128 class VREventObserver;
129 class WakeLock;
130 #if defined(MOZ_WIDGET_ANDROID)
131 class WindowOrientationObserver;
132 #endif
133 class Worklet;
134 namespace cache {
135 class CacheStorage;
136 }  // namespace cache
137 class IDBFactory;
138 }  // namespace dom
139 }  // namespace mozilla
140 
141 extern already_AddRefed<nsIScriptTimeoutHandler> NS_CreateJSTimeoutHandler(
142     JSContext* aCx, nsGlobalWindowInner* aWindow,
143     mozilla::dom::Function& aFunction,
144     const mozilla::dom::Sequence<JS::Value>& aArguments,
145     mozilla::ErrorResult& aError);
146 
147 extern already_AddRefed<nsIScriptTimeoutHandler> NS_CreateJSTimeoutHandler(
148     JSContext* aCx, nsGlobalWindowInner* aWindow, const nsAString& aExpression,
149     mozilla::ErrorResult& aError);
150 
151 extern const js::Class OuterWindowProxyClass;
152 
153 struct IdleObserverHolder {
154   nsCOMPtr<nsIIdleObserver> mIdleObserver;
155   uint32_t mTimeInS;
156   bool mPrevNotificationIdle;
157 
IdleObserverHolderIdleObserverHolder158   IdleObserverHolder() : mTimeInS(0), mPrevNotificationIdle(false) {
159     MOZ_COUNT_CTOR(IdleObserverHolder);
160   }
161 
IdleObserverHolderIdleObserverHolder162   IdleObserverHolder(const IdleObserverHolder& aOther)
163       : mIdleObserver(aOther.mIdleObserver),
164         mTimeInS(aOther.mTimeInS),
165         mPrevNotificationIdle(aOther.mPrevNotificationIdle) {
166     MOZ_COUNT_CTOR(IdleObserverHolder);
167   }
168 
169   bool operator==(const IdleObserverHolder& aOther) const {
170     return mIdleObserver == aOther.mIdleObserver && mTimeInS == aOther.mTimeInS;
171   }
172 
~IdleObserverHolderIdleObserverHolder173   ~IdleObserverHolder() { MOZ_COUNT_DTOR(IdleObserverHolder); }
174 };
175 
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback & aCallback,IdleObserverHolder & aField,const char * aName,unsigned aFlags)176 inline void ImplCycleCollectionTraverse(
177     nsCycleCollectionTraversalCallback& aCallback, IdleObserverHolder& aField,
178     const char* aName, unsigned aFlags) {
179   CycleCollectionNoteChild(aCallback, aField.mIdleObserver.get(), aName,
180                            aFlags);
181 }
182 
183 //*****************************************************************************
184 // nsGlobalWindowInner: Global Object for Scripting
185 //*****************************************************************************
186 
187 // nsGlobalWindowInner inherits PRCList for maintaining a list of all inner
188 // windows still in memory for any given outer window. This list is needed to
189 // ensure that mOuterWindow doesn't end up dangling. The nature of PRCList means
190 // that the window itself is always in the list, and an outer window's list will
191 // also contain all inner window objects that are still in memory (and in
192 // reality all inner window object's lists also contain its outer and all other
193 // inner windows belonging to the same outer window, but that's an unimportant
194 // side effect of inheriting PRCList).
195 
196 class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
197                                   public nsPIDOMWindowInner,
198                                   private nsIDOMWindow
199     // NOTE: This interface is private, as it's only
200     // implemented on chrome windows.
201     ,
202                                   private nsIDOMChromeWindow,
203                                   public nsIScriptGlobalObject,
204                                   public nsIScriptObjectPrincipal,
205                                   public nsSupportsWeakReference,
206                                   public nsIInterfaceRequestor,
207                                   public PRCListStr,
208                                   public nsAPostRefreshObserver {
209  public:
210   typedef mozilla::TimeStamp TimeStamp;
211   typedef mozilla::TimeDuration TimeDuration;
212 
213   typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindowInner*>
214       InnerWindowByIdTable;
215 
216   static void AssertIsOnMainThread()
217 #ifdef DEBUG
218       ;
219 #else
220   {
221   }
222 #endif
223 
Cast(nsPIDOMWindowInner * aPIWin)224   static nsGlobalWindowInner* Cast(nsPIDOMWindowInner* aPIWin) {
225     return static_cast<nsGlobalWindowInner*>(aPIWin);
226   }
Cast(const nsPIDOMWindowInner * aPIWin)227   static const nsGlobalWindowInner* Cast(const nsPIDOMWindowInner* aPIWin) {
228     return static_cast<const nsGlobalWindowInner*>(aPIWin);
229   }
Cast(mozIDOMWindow * aWin)230   static nsGlobalWindowInner* Cast(mozIDOMWindow* aWin) {
231     return Cast(nsPIDOMWindowInner::From(aWin));
232   }
233 
GetInnerWindowWithId(uint64_t aInnerWindowID)234   static nsGlobalWindowInner* GetInnerWindowWithId(uint64_t aInnerWindowID) {
235     AssertIsOnMainThread();
236 
237     if (!sInnerWindowsById) {
238       return nullptr;
239     }
240 
241     nsGlobalWindowInner* innerWindow = sInnerWindowsById->Get(aInnerWindowID);
242     return innerWindow;
243   }
244 
GetWindowsTable()245   static InnerWindowByIdTable* GetWindowsTable() {
246     AssertIsOnMainThread();
247 
248     return sInnerWindowsById;
249   }
250 
FromSupports(nsISupports * supports)251   static nsGlobalWindowInner* FromSupports(nsISupports* supports) {
252     // Make sure this matches the casts we do in QueryInterface().
253     return (nsGlobalWindowInner*)(mozilla::dom::EventTarget*)supports;
254   }
255 
256   static already_AddRefed<nsGlobalWindowInner> Create(
257       nsGlobalWindowOuter* aOuter, bool aIsChrome);
258 
259   // callback for close event
260   void ReallyCloseWindow();
261 
262   // nsISupports
263   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
264 
265   // nsWrapperCache
WrapObject(JSContext * cx,JS::Handle<JSObject * > aGivenProto)266   virtual JSObject* WrapObject(JSContext* cx,
267                                JS::Handle<JSObject*> aGivenProto) override {
268     return GetWrapper();
269   }
270 
271   // nsIGlobalJSObjectHolder
272   virtual JSObject* GetGlobalJSObject() override;
273 
274   // nsIScriptGlobalObject
FastGetGlobalJSObject()275   JSObject* FastGetGlobalJSObject() const { return GetWrapperPreserveColor(); }
276 
277   void TraceGlobalJSObject(JSTracer* aTrc);
278 
279   virtual nsresult EnsureScriptEnvironment() override;
280 
281   virtual nsIScriptContext* GetScriptContext() override;
282 
283   virtual bool IsBlackForCC(bool aTracingNeeded = true) override;
284 
285   // nsIScriptObjectPrincipal
286   virtual nsIPrincipal* GetPrincipal() override;
287 
288   // nsIDOMWindow
289   NS_DECL_NSIDOMWINDOW
290 
291   // nsIDOMChromeWindow (only implemented on chrome windows)
292   NS_DECL_NSIDOMCHROMEWINDOW
293 
294   void CaptureEvents();
295   void ReleaseEvents();
296   void Dump(const nsAString& aStr);
297   void SetResizable(bool aResizable) const;
298 
299   // nsIDOMEventTarget
300   NS_DECL_NSIDOMEVENTTARGET
301 
302   virtual mozilla::EventListenerManager* GetExistingListenerManager()
303       const override;
304 
305   virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
306 
307   using mozilla::dom::EventTarget::RemoveEventListener;
308   virtual void AddEventListener(
309       const nsAString& aType, mozilla::dom::EventListener* aListener,
310       const mozilla::dom::AddEventListenerOptionsOrBoolean& aOptions,
311       const mozilla::dom::Nullable<bool>& aWantsUntrusted,
312       mozilla::ErrorResult& aRv) override;
313   virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override;
314 
315   virtual nsIGlobalObject* GetOwnerGlobal() const override;
316 
317   // nsPIDOMWindow
318   virtual nsPIDOMWindowOuter* GetPrivateRoot() override;
319 
320   // Outer windows only.
321   virtual bool IsTopLevelWindowActive() override;
322 
323   virtual PopupControlState GetPopupControlState() const override;
324 
325   void Suspend();
326   void Resume();
327   virtual bool IsSuspended() const override;
328   void Freeze();
329   void Thaw();
330   virtual bool IsFrozen() const override;
331   void SyncStateFromParentWindow();
332 
333   mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const override;
334   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
335   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController()
336       const override;
337 
338   virtual RefPtr<mozilla::dom::ServiceWorker> GetOrCreateServiceWorker(
339       const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
340 
341   RefPtr<mozilla::dom::ServiceWorkerRegistration>
342   GetOrCreateServiceWorkerRegistration(
343       const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor)
344       override;
345 
346   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
347 
348   virtual nsresult FireDelayedDOMEvents() override;
349 
350   virtual nsresult SetNewDocument(nsIDocument* aDocument, nsISupports* aState,
351                                   bool aForceReuseInnerWindow) override;
352 
353   virtual void SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
354                                bool aOriginalOpener) override;
355 
356   virtual void MaybeUpdateTouchState() override;
357 
358   // Inner windows only.
359   void RefreshCompartmentPrincipal();
360 
361   // For accessing protected field mFullScreen
362   friend class FullscreenTransitionTask;
363 
364   // Inner windows only.
365   virtual void SetHasGamepadEventListener(bool aHasGamepad = true) override;
366   void NotifyVREventListenerAdded();
367   bool HasUsedVR() const;
368   bool IsVRContentDetected() const;
369   bool IsVRContentPresenting() const;
370 
371   using EventTarget::EventListenerAdded;
372   virtual void EventListenerAdded(nsAtom* aType) override;
373   using EventTarget::EventListenerRemoved;
374   virtual void EventListenerRemoved(nsAtom* aType) override;
375 
376   // nsIInterfaceRequestor
377   NS_DECL_NSIINTERFACEREQUESTOR
378 
379   // WebIDL interface.
380   already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex);
381 
382   static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj);
383 
384   static bool OfflineCacheAllowedForContext(JSContext* /* unused */,
385                                             JSObject* aObj);
386 
387   static bool IsRequestIdleCallbackEnabled(JSContext* aCx,
388                                            JSObject* /* unused */);
389 
390   static bool IsWindowPrintEnabled(JSContext* /* unused */,
391                                    JSObject* /* unused */);
392 
393   static bool RegisterProtocolHandlerAllowedForContext(JSContext* /* unused */,
394                                                        JSObject* aObj);
395 
396   static bool DeviceSensorsEnabled(JSContext* /* unused */, JSObject* aObj);
397 
398   bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
399                  JS::Handle<jsid> aId,
400                  JS::MutableHandle<JS::PropertyDescriptor> aDesc);
401   // The return value is whether DoResolve might end up resolving the given id.
402   // If in doubt, return true.
403   static bool MayResolve(jsid aId);
404 
405   void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& aNames,
406                            bool aEnumerableOnly, mozilla::ErrorResult& aRv);
407 
408   nsPIDOMWindowOuter* GetScriptableTop() override;
409   inline nsGlobalWindowOuter* GetTopInternal();
410 
411   inline nsGlobalWindowOuter* GetScriptableTopInternal();
412 
413   nsPIDOMWindowOuter* GetChildWindow(const nsAString& aName);
414 
415   // These return true if we've reached the state in this top level window
416   // where we ask the user if further dialogs should be blocked.
417   //
418   // DialogsAreBeingAbused must be called on the scriptable top inner window.
419   //
420   // nsGlobalWindowOuter::ShouldPromptToBlockDialogs is implemented in terms of
421   // nsGlobalWindowInner::DialogsAreBeingAbused, and will get the scriptable top
422   // inner window automatically. Inner windows only.
423   bool DialogsAreBeingAbused();
424 
425   // These functions are used for controlling and determining whether dialogs
426   // (alert, prompt, confirm) are currently allowed in this window.  If you want
427   // to temporarily disable dialogs, please use TemporarilyDisableDialogs, not
428   // EnableDialogs/DisableDialogs, because correctly determining whether to
429   // re-enable dialogs is actually quite difficult.
430   void EnableDialogs();
431   void DisableDialogs();
432 
433   nsIScriptContext* GetContextInternal();
434 
435   nsGlobalWindowOuter* GetOuterWindowInternal() const;
436 
IsChromeWindow()437   bool IsChromeWindow() const { return mIsChrome; }
438 
439   // GetScrollFrame does not flush.  Callers should do it themselves as needed,
440   // depending on which info they actually want off the scrollable frame.
441   nsIScrollableFrame* GetScrollFrame();
442 
443   nsresult Observe(nsISupports* aSubject, const char* aTopic,
444                    const char16_t* aData);
445 
446   void ObserveStorageNotification(mozilla::dom::StorageEvent* aEvent,
447                                   const char16_t* aStorageType,
448                                   bool aPrivateBrowsing);
449 
450   static void Init();
451   static void ShutDown();
452   static bool IsCallerChrome();
453 
454   void CleanupCachedXBLHandlers();
455 
456   friend class WindowStateHolder;
457 
458   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
459       nsGlobalWindowInner, nsIDOMEventTarget)
460 
461 #ifdef DEBUG
462   // Call Unlink on this window. This may cause bad things to happen, so use
463   // with caution.
464   void RiskyUnlink();
465 #endif
466 
467   virtual JSObject* GetCachedXBLPrototypeHandler(
468       nsXBLPrototypeHandler* aKey) override;
469 
470   virtual void CacheXBLPrototypeHandler(
471       nsXBLPrototypeHandler* aKey, JS::Handle<JSObject*> aHandler) override;
472 
473   virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
474   virtual void SetReadyForFocus() override;
475   virtual void PageHidden() override;
476   virtual nsresult DispatchAsyncHashchange(nsIURI* aOldURI,
477                                            nsIURI* aNewURI) override;
478   virtual nsresult DispatchSyncPopState() override;
479 
480   // Inner windows only.
481   virtual void EnableDeviceSensor(uint32_t aType) override;
482   virtual void DisableDeviceSensor(uint32_t aType) override;
483 
484 #if defined(MOZ_WIDGET_ANDROID)
485   virtual void EnableOrientationChangeListener() override;
486   virtual void DisableOrientationChangeListener() override;
487 #endif
488 
IsClosedOrClosing()489   bool IsClosedOrClosing() { return mCleanedUp; }
490 
IsCleanedUp()491   bool IsCleanedUp() const { return mCleanedUp; }
492 
GetSerial()493   virtual uint32_t GetSerial() override { return mSerial; }
494 
495   void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
496 
497   void NotifyIdleObserver(IdleObserverHolder* aIdleObserverHolder,
498                           bool aCallOnidle);
499   nsresult HandleIdleActiveEvent();
500   bool ContainsIdleObserver(nsIIdleObserver* aIdleObserver, uint32_t timeInS);
501   void HandleIdleObserverCallback();
502 
503   enum SlowScriptResponse {
504     ContinueSlowScript = 0,
505     ContinueSlowScriptAndKeepNotifying,
506     AlwaysContinueSlowScript,
507     KillSlowScript,
508     KillScriptGlobal
509   };
510   SlowScriptResponse ShowSlowScriptDialog(const nsString& aAddonId);
511 
512   // Inner windows only.
513   void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);
514   void RemoveGamepad(uint32_t aIndex);
515   void GetGamepads(nsTArray<RefPtr<mozilla::dom::Gamepad>>& aGamepads);
516   already_AddRefed<mozilla::dom::Gamepad> GetGamepad(uint32_t aIndex);
517   void SetHasSeenGamepadInput(bool aHasSeen);
518   bool HasSeenGamepadInput();
519   void SyncGamepadState();
520   void StopGamepadHaptics();
521 
522   // Inner windows only.
523   // Enable/disable updates for gamepad input.
524   void EnableGamepadUpdates();
525   void DisableGamepadUpdates();
526 
527   // Inner windows only.
528   // Enable/disable updates for VR
529   void EnableVRUpdates();
530   void DisableVRUpdates();
531   // Reset telemetry data when switching windows.
532   // aUpdate, true for accumulating the result to the histogram.
533   // false for only resetting the timestamp.
534   void ResetVRTelemetry(bool aUpdate);
535 
536   // Update the VR displays for this window
537   bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
538 
539   // Inner windows only.
540   // Called to inform that the set of active VR displays has changed.
541   void NotifyActiveVRDisplaysChanged();
542 
543   void DispatchVRDisplayActivate(uint32_t aDisplayID,
544                                  mozilla::dom::VRDisplayEventReason aReason);
545   void DispatchVRDisplayDeactivate(uint32_t aDisplayID,
546                                    mozilla::dom::VRDisplayEventReason aReason);
547   void DispatchVRDisplayConnect(uint32_t aDisplayID);
548   void DispatchVRDisplayDisconnect(uint32_t aDisplayID);
549   void DispatchVRDisplayPresentChange(uint32_t aDisplayID);
550 
551 #define EVENT(name_, id_, type_, struct_)                                  \
552   mozilla::dom::EventHandlerNonNull* GetOn##name_() {                      \
553     mozilla::EventListenerManager* elm = GetExistingListenerManager();     \
554     return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \
555                : nullptr;                                                  \
556   }                                                                        \
557   void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) {          \
558     mozilla::EventListenerManager* elm = GetOrCreateListenerManager();     \
559     if (elm) {                                                             \
560       elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler);  \
561     }                                                                      \
562   }
563 #define ERROR_EVENT(name_, id_, type_, struct_)                          \
564   mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_() {             \
565     mozilla::EventListenerManager* elm = GetExistingListenerManager();   \
566     return elm ? elm->GetOnErrorEventHandler() : nullptr;                \
567   }                                                                      \
568   void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler) { \
569     mozilla::EventListenerManager* elm = GetOrCreateListenerManager();   \
570     if (elm) {                                                           \
571       elm->SetEventHandler(handler);                                     \
572     }                                                                    \
573   }
574 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                 \
575   mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_() {    \
576     mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
577     return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr;       \
578   }                                                                    \
579   void SetOn##name_(                                                   \
580       mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) {      \
581     mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
582     if (elm) {                                                         \
583       elm->SetEventHandler(handler);                                   \
584     }                                                                  \
585   }
586 #define WINDOW_ONLY_EVENT EVENT
587 #define TOUCH_EVENT EVENT
588 #include "mozilla/EventNameList.h"
589 #undef TOUCH_EVENT
590 #undef WINDOW_ONLY_EVENT
591 #undef BEFOREUNLOAD_EVENT
592 #undef ERROR_EVENT
593 #undef EVENT
594 
GetParentObject()595   nsISupports* GetParentObject() { return nullptr; }
596 
597   static JSObject* CreateNamedPropertiesObject(JSContext* aCx,
598                                                JS::Handle<JSObject*> aProto);
599 
600   nsGlobalWindowInner* Window();
601   nsGlobalWindowInner* Self();
GetDocument()602   nsIDocument* GetDocument() { return GetDoc(); }
603   void GetName(nsAString& aName, mozilla::ErrorResult& aError);
604   void SetName(const nsAString& aName, mozilla::ErrorResult& aError);
605   mozilla::dom::Location* GetLocation() override;
606   nsHistory* GetHistory(mozilla::ErrorResult& aError);
607   mozilla::dom::CustomElementRegistry* CustomElements() override;
608   mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);
609   mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError);
610   mozilla::dom::BarProp* GetPersonalbar(mozilla::ErrorResult& aError);
611   mozilla::dom::BarProp* GetScrollbars(mozilla::ErrorResult& aError);
612   mozilla::dom::BarProp* GetStatusbar(mozilla::ErrorResult& aError);
613   mozilla::dom::BarProp* GetToolbar(mozilla::ErrorResult& aError);
614   void GetStatus(nsAString& aStatus, mozilla::ErrorResult& aError);
615   void SetStatus(const nsAString& aStatus, mozilla::ErrorResult& aError);
616   void Close(mozilla::ErrorResult& aError);
617   nsresult Close() override;
618   bool GetClosed(mozilla::ErrorResult& aError);
619   void Stop(mozilla::ErrorResult& aError);
620   void Focus(mozilla::ErrorResult& aError);
621   nsresult Focus() override;
622   void Blur(mozilla::ErrorResult& aError);
623   already_AddRefed<nsIDOMWindowCollection> GetFrames() override;
624   already_AddRefed<nsPIDOMWindowOuter> GetFrames(mozilla::ErrorResult& aError);
625   uint32_t Length();
626   already_AddRefed<nsPIDOMWindowOuter> GetTop(mozilla::ErrorResult& aError);
627 
628  protected:
629   explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow);
630   // Initializes the mWasOffline member variable
631   void InitWasOffline();
632 
633  public:
634   nsPIDOMWindowOuter* GetOpenerWindow(mozilla::ErrorResult& aError);
635   void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
636                  mozilla::ErrorResult& aError);
637   void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
638                  mozilla::ErrorResult& aError);
639   already_AddRefed<nsPIDOMWindowOuter> GetParent(mozilla::ErrorResult& aError);
640   nsPIDOMWindowOuter* GetScriptableParent() override;
641   nsPIDOMWindowOuter* GetScriptableParentOrNull() override;
642   mozilla::dom::Element* GetFrameElement(nsIPrincipal& aSubjectPrincipal,
643                                          mozilla::ErrorResult& aError);
644   already_AddRefed<nsIDOMElement> GetFrameElement() override;
645   already_AddRefed<nsPIDOMWindowOuter> Open(const nsAString& aUrl,
646                                             const nsAString& aName,
647                                             const nsAString& aOptions,
648                                             mozilla::ErrorResult& aError);
649   nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);
650   already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() override;
651 
652 #if defined(MOZ_WIDGET_ANDROID)
653   int16_t Orientation(mozilla::dom::CallerType aCallerType) const;
654 #endif
655 
656   already_AddRefed<mozilla::dom::Console> GetConsole(JSContext* aCx,
657                                                      mozilla::ErrorResult& aRv);
658 
659   // https://w3c.github.io/webappsec-secure-contexts/#dom-window-issecurecontext
660   bool IsSecureContext() const;
661 
662   void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult,
663                   mozilla::ErrorResult& aRv);
664   already_AddRefed<mozilla::dom::External> GetExternal(
665       mozilla::ErrorResult& aRv);
666 
667   // Exposed only for testing
668   static bool TokenizeDialogOptions(nsAString& aToken,
669                                     nsAString::const_iterator& aIter,
670                                     nsAString::const_iterator aEnd);
671   static void ConvertDialogOptions(const nsAString& aOptions,
672                                    nsAString& aResult);
673 
674   mozilla::dom::Worklet* GetAudioWorklet(mozilla::ErrorResult& aRv);
675 
676   mozilla::dom::Worklet* GetPaintWorklet(mozilla::ErrorResult& aRv);
677 
678   void GetRegionalPrefsLocales(nsTArray<nsString>& aLocales);
679 
680   mozilla::dom::IntlUtils* GetIntlUtils(mozilla::ErrorResult& aRv);
681 
682  public:
683   void Alert(nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aError);
684   void Alert(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
685              mozilla::ErrorResult& aError);
686   bool Confirm(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
687                mozilla::ErrorResult& aError);
688   void Prompt(const nsAString& aMessage, const nsAString& aInitial,
689               nsAString& aReturn, nsIPrincipal& aSubjectPrincipal,
690               mozilla::ErrorResult& aError);
691   already_AddRefed<mozilla::dom::cache::CacheStorage> GetCaches(
692       mozilla::ErrorResult& aRv);
693   already_AddRefed<mozilla::dom::Promise> Fetch(
694       const mozilla::dom::RequestOrUSVString& aInput,
695       const mozilla::dom::RequestInit& aInit,
696       mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
697   void Print(mozilla::ErrorResult& aError);
698   void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
699                       const nsAString& aTargetOrigin,
700                       const mozilla::dom::Sequence<JSObject*>& aTransfer,
701                       nsIPrincipal& aSubjectPrincipal,
702                       mozilla::ErrorResult& aError);
703   int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
704                      int32_t aTimeout,
705                      const mozilla::dom::Sequence<JS::Value>& aArguments,
706                      mozilla::ErrorResult& aError);
707   int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
708                      int32_t aTimeout,
709                      const mozilla::dom::Sequence<JS::Value>& /* unused */,
710                      mozilla::ErrorResult& aError);
711   void ClearTimeout(int32_t aHandle);
712   int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
713                       const mozilla::dom::Optional<int32_t>& aTimeout,
714                       const mozilla::dom::Sequence<JS::Value>& aArguments,
715                       mozilla::ErrorResult& aError);
716   int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
717                       const mozilla::dom::Optional<int32_t>& aTimeout,
718                       const mozilla::dom::Sequence<JS::Value>& /* unused */,
719                       mozilla::ErrorResult& aError);
720   void ClearInterval(int32_t aHandle);
721   void GetOrigin(nsAString& aOrigin);
722   void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData,
723             mozilla::ErrorResult& aError);
724   void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
725             mozilla::ErrorResult& aError);
726   mozilla::dom::Storage* GetSessionStorage(mozilla::ErrorResult& aError);
727   mozilla::dom::Storage* GetLocalStorage(mozilla::ErrorResult& aError);
728   mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
729   mozilla::dom::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
730   already_AddRefed<nsICSSDeclaration> GetComputedStyle(
731       mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
732       mozilla::ErrorResult& aError) override;
733   already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(
734       const nsAString& aQuery, mozilla::dom::CallerType aCallerType,
735       mozilla::ErrorResult& aError);
736   nsScreen* GetScreen(mozilla::ErrorResult& aError);
737   nsIDOMScreen* GetScreen() override;
738   void MoveTo(int32_t aXPos, int32_t aYPos,
739               mozilla::dom::CallerType aCallerType,
740               mozilla::ErrorResult& aError);
741   void MoveBy(int32_t aXDif, int32_t aYDif,
742               mozilla::dom::CallerType aCallerType,
743               mozilla::ErrorResult& aError);
744   void ResizeTo(int32_t aWidth, int32_t aHeight,
745                 mozilla::dom::CallerType aCallerType,
746                 mozilla::ErrorResult& aError);
747   void ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
748                 mozilla::dom::CallerType aCallerType,
749                 mozilla::ErrorResult& aError);
750   void Scroll(double aXScroll, double aYScroll);
751   void Scroll(const mozilla::dom::ScrollToOptions& aOptions);
752   void ScrollTo(double aXScroll, double aYScroll);
753   void ScrollTo(const mozilla::dom::ScrollToOptions& aOptions);
754   void ScrollBy(double aXScrollDif, double aYScrollDif);
755   void ScrollBy(const mozilla::dom::ScrollToOptions& aOptions);
756   void ScrollByLines(int32_t numLines,
757                      const mozilla::dom::ScrollOptions& aOptions);
758   void ScrollByPages(int32_t numPages,
759                      const mozilla::dom::ScrollOptions& aOptions);
760   void MozScrollSnap();
761   void GetInnerWidth(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
762                      mozilla::dom::CallerType aCallerType,
763                      mozilla::ErrorResult& aError);
764   void SetInnerWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
765                      mozilla::dom::CallerType aCallerType,
766                      mozilla::ErrorResult& aError);
767   void GetInnerHeight(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
768                       mozilla::dom::CallerType aCallerType,
769                       mozilla::ErrorResult& aError);
770   void SetInnerHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
771                       mozilla::dom::CallerType aCallerType,
772                       mozilla::ErrorResult& aError);
773   double GetScrollX(mozilla::ErrorResult& aError);
GetPageXOffset(mozilla::ErrorResult & aError)774   double GetPageXOffset(mozilla::ErrorResult& aError) {
775     return GetScrollX(aError);
776   }
777   double GetScrollY(mozilla::ErrorResult& aError);
GetPageYOffset(mozilla::ErrorResult & aError)778   double GetPageYOffset(mozilla::ErrorResult& aError) {
779     return GetScrollY(aError);
780   }
781   void GetScreenX(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
782                   mozilla::dom::CallerType aCallerType,
783                   mozilla::ErrorResult& aError);
784   void SetScreenX(JSContext* aCx, JS::Handle<JS::Value> aValue,
785                   mozilla::dom::CallerType aCallerType,
786                   mozilla::ErrorResult& aError);
787   void GetScreenY(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
788                   mozilla::dom::CallerType aCallerType,
789                   mozilla::ErrorResult& aError);
790   void SetScreenY(JSContext* aCx, JS::Handle<JS::Value> aValue,
791                   mozilla::dom::CallerType aCallerType,
792                   mozilla::ErrorResult& aError);
793   void GetOuterWidth(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
794                      mozilla::dom::CallerType aCallerType,
795                      mozilla::ErrorResult& aError);
796   void SetOuterWidth(JSContext* aCx, JS::Handle<JS::Value> aValue,
797                      mozilla::dom::CallerType aCallerType,
798                      mozilla::ErrorResult& aError);
799   void GetOuterHeight(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
800                       mozilla::dom::CallerType aCallerType,
801                       mozilla::ErrorResult& aError);
802   void SetOuterHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
803                       mozilla::dom::CallerType aCallerType,
804                       mozilla::ErrorResult& aError);
805   int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
806                                 mozilla::ErrorResult& aError);
807   void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
808 
809   uint32_t RequestIdleCallback(JSContext* aCx,
810                                mozilla::dom::IdleRequestCallback& aCallback,
811                                const mozilla::dom::IdleRequestOptions& aOptions,
812                                mozilla::ErrorResult& aError);
813   void CancelIdleCallback(uint32_t aHandle);
814 
815 #ifdef MOZ_WEBSPEECH
816   mozilla::dom::SpeechSynthesis* GetSpeechSynthesis(
817       mozilla::ErrorResult& aError);
818   bool HasActiveSpeechSynthesis();
819 #endif
820   already_AddRefed<nsICSSDeclaration> GetDefaultComputedStyle(
821       mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
822       mozilla::ErrorResult& aError);
823   void SizeToContent(mozilla::dom::CallerType aCallerType,
824                      mozilla::ErrorResult& aError);
825   mozilla::dom::Crypto* GetCrypto(mozilla::ErrorResult& aError);
826   mozilla::dom::U2F* GetU2f(mozilla::ErrorResult& aError);
827   nsIControllers* GetControllers(mozilla::ErrorResult& aError);
828   nsresult GetControllers(nsIControllers** aControllers) override;
829   mozilla::dom::Element* GetRealFrameElement(mozilla::ErrorResult& aError);
830   float GetMozInnerScreenX(mozilla::dom::CallerType aCallerType,
831                            mozilla::ErrorResult& aError);
832   float GetMozInnerScreenY(mozilla::dom::CallerType aCallerType,
833                            mozilla::ErrorResult& aError);
834   double GetDevicePixelRatio(mozilla::dom::CallerType aCallerType,
835                              mozilla::ErrorResult& aError);
836   int32_t GetScrollMinX(mozilla::ErrorResult& aError);
837   int32_t GetScrollMinY(mozilla::ErrorResult& aError);
838   int32_t GetScrollMaxX(mozilla::ErrorResult& aError);
839   int32_t GetScrollMaxY(mozilla::ErrorResult& aError);
840   bool GetFullScreen(mozilla::ErrorResult& aError);
841   bool GetFullScreen() override;
842   void SetFullScreen(bool aFullScreen, mozilla::ErrorResult& aError);
843   void Back(mozilla::ErrorResult& aError);
844   void Forward(mozilla::ErrorResult& aError);
845   void Home(nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& aError);
846   bool Find(const nsAString& aString, bool aCaseSensitive, bool aBackwards,
847             bool aWrapAround, bool aWholeWord, bool aSearchInFrames,
848             bool aShowDialog, mozilla::ErrorResult& aError);
849   uint64_t GetMozPaintCount(mozilla::ErrorResult& aError);
850 
851   bool ShouldResistFingerprinting();
852 
853   already_AddRefed<nsPIDOMWindowOuter> OpenDialog(
854       JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
855       const nsAString& aOptions,
856       const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
857       mozilla::ErrorResult& aError);
858   void UpdateCommands(const nsAString& anAction, nsISelection* aSel,
859                       int16_t aReason);
860 
861   void GetContent(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
862                   mozilla::dom::CallerType aCallerType,
863                   mozilla::ErrorResult& aError);
864 
865   already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
866       JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
867       mozilla::ErrorResult& aRv);
868 
869   already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
870       JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
871       int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
872       mozilla::ErrorResult& aRv);
873 
874   already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
875       JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
876       int32_t aOffset, int32_t aLength, mozilla::dom::ImageBitmapFormat aFormat,
877       const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
878       mozilla::ErrorResult& aRv);
879 
880   // ChromeWindow bits.  Do NOT call these unless your window is in
881   // fact chrome.
882   uint16_t WindowState();
883   bool IsFullyOccluded();
884   nsIBrowserDOMWindow* GetBrowserDOMWindow(mozilla::ErrorResult& aError);
885   void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow,
886                            mozilla::ErrorResult& aError);
887   void GetAttention(mozilla::ErrorResult& aError);
888   void GetAttentionWithCycleCount(int32_t aCycleCount,
889                                   mozilla::ErrorResult& aError);
890   void SetCursor(const nsAString& aCursor, mozilla::ErrorResult& aError);
891   void Maximize();
892   void Minimize();
893   void Restore();
894   void NotifyDefaultButtonLoaded(mozilla::dom::Element& aDefaultButton,
895                                  mozilla::ErrorResult& aError);
896   nsIMessageBroadcaster* GetMessageManager(mozilla::ErrorResult& aError);
897   nsIMessageBroadcaster* GetGroupMessageManager(const nsAString& aGroup,
898                                                 mozilla::ErrorResult& aError);
899   void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent,
900                        mozilla::dom::Element* aPanel,
901                        mozilla::ErrorResult& aError);
902 
903   already_AddRefed<mozilla::dom::Promise> PromiseDocumentFlushed(
904       mozilla::dom::PromiseDocumentFlushedCallback& aCallback,
905       mozilla::ErrorResult& aError);
906 
907   void DidRefresh() override;
908 
909   void GetDialogArgumentsOuter(JSContext* aCx,
910                                JS::MutableHandle<JS::Value> aRetval,
911                                nsIPrincipal& aSubjectPrincipal,
912                                mozilla::ErrorResult& aError);
913   void GetDialogArguments(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
914                           nsIPrincipal& aSubjectPrincipal,
915                           mozilla::ErrorResult& aError);
916   void GetReturnValueOuter(JSContext* aCx,
917                            JS::MutableHandle<JS::Value> aReturnValue,
918                            nsIPrincipal& aSubjectPrincipal,
919                            mozilla::ErrorResult& aError);
920   void GetReturnValue(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
921                       nsIPrincipal& aSubjectPrincipal,
922                       mozilla::ErrorResult& aError);
923   void SetReturnValueOuter(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
924                            nsIPrincipal& aSubjectPrincipal,
925                            mozilla::ErrorResult& aError);
926   void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
927                       nsIPrincipal& aSubjectPrincipal,
928                       mozilla::ErrorResult& aError);
929 
930   void GetInterface(JSContext* aCx, nsIJSID* aIID,
931                     JS::MutableHandle<JS::Value> aRetval,
932                     mozilla::ErrorResult& aError);
933 
934   already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
935 
936   bool ShouldReportForServiceWorkerScope(const nsAString& aScope);
937 
938   void UpdateTopInnerWindow();
939 
IsInSyncOperation()940   virtual bool IsInSyncOperation() override {
941     return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
942   }
943 
944  protected:
945   // Web IDL helpers
946 
947   // Redefine the property called aPropName on this window object to be a value
948   // property with the value aValue, much like we would do for a [Replaceable]
949   // property in IDL.
950   void RedefineProperty(JSContext* aCx, const char* aPropName,
951                         JS::Handle<JS::Value> aValue,
952                         mozilla::ErrorResult& aError);
953 
954   // Implementation guts for our writable IDL attributes that are really
955   // supposed to be readonly replaceable.
956   typedef int32_t (nsGlobalWindowInner::*WindowCoordGetter)(
957       mozilla::dom::CallerType aCallerType, mozilla::ErrorResult&);
958   typedef void (nsGlobalWindowInner::*WindowCoordSetter)(
959       int32_t, mozilla::dom::CallerType aCallerType, mozilla::ErrorResult&);
960   void GetReplaceableWindowCoord(JSContext* aCx, WindowCoordGetter aGetter,
961                                  JS::MutableHandle<JS::Value> aRetval,
962                                  mozilla::dom::CallerType aCallerType,
963                                  mozilla::ErrorResult& aError);
964   void SetReplaceableWindowCoord(JSContext* aCx, WindowCoordSetter aSetter,
965                                  JS::Handle<JS::Value> aValue,
966                                  const char* aPropName,
967                                  mozilla::dom::CallerType aCallerType,
968                                  mozilla::ErrorResult& aError);
969   // And the implementations of WindowCoordGetter/WindowCoordSetter.
970  protected:
971   int32_t GetInnerWidth(mozilla::dom::CallerType aCallerType,
972                         mozilla::ErrorResult& aError);
973   nsresult GetInnerWidth(int32_t* aWidth) override;
974   void SetInnerWidth(int32_t aInnerWidth, mozilla::dom::CallerType aCallerType,
975                      mozilla::ErrorResult& aError);
976 
977  protected:
978   int32_t GetInnerHeight(mozilla::dom::CallerType aCallerType,
979                          mozilla::ErrorResult& aError);
980   nsresult GetInnerHeight(int32_t* aHeight) override;
981   void SetInnerHeight(int32_t aInnerHeight,
982                       mozilla::dom::CallerType aCallerType,
983                       mozilla::ErrorResult& aError);
984   int32_t GetScreenX(mozilla::dom::CallerType aCallerType,
985                      mozilla::ErrorResult& aError);
986   void SetScreenX(int32_t aScreenX, mozilla::dom::CallerType aCallerType,
987                   mozilla::ErrorResult& aError);
988   int32_t GetScreenY(mozilla::dom::CallerType aCallerType,
989                      mozilla::ErrorResult& aError);
990   void SetScreenY(int32_t aScreenY, mozilla::dom::CallerType aCallerType,
991                   mozilla::ErrorResult& aError);
992   int32_t GetOuterWidth(mozilla::dom::CallerType aCallerType,
993                         mozilla::ErrorResult& aError);
994   void SetOuterWidth(int32_t aOuterWidth, mozilla::dom::CallerType aCallerType,
995                      mozilla::ErrorResult& aError);
996   int32_t GetOuterHeight(mozilla::dom::CallerType aCallerType,
997                          mozilla::ErrorResult& aError);
998   void SetOuterHeight(int32_t aOuterHeight,
999                       mozilla::dom::CallerType aCallerType,
1000                       mozilla::ErrorResult& aError);
1001 
1002   // Array of idle observers that are notified of idle events.
1003   nsTObserverArray<IdleObserverHolder> mIdleObservers;
1004 
1005   // Idle timer used for function callbacks to notify idle observers.
1006   nsCOMPtr<nsITimer> mIdleTimer;
1007 
1008   // Idle fuzz time added to idle timer callbacks.
1009   uint32_t mIdleFuzzFactor;
1010 
1011   // Index in mArrayIdleObservers
1012   // Next idle observer to notify user idle status
1013   int32_t mIdleCallbackIndex;
1014 
1015   // If false then the topic is "active"
1016   // If true then the topic is "idle"
1017   bool mCurrentlyIdle;
1018 
1019   // Set to true when a fuzz time needs to be applied
1020   // to active notifications to the idle observer.
1021   bool mAddActiveEventFuzzTime;
1022 
1023   nsCOMPtr<nsIIdleService> mIdleService;
1024 
1025   RefPtr<mozilla::dom::WakeLock> mWakeLock;
1026 
1027   friend class HashchangeCallback;
1028   friend class mozilla::dom::BarProp;
1029 
1030   // Object Management
1031   virtual ~nsGlobalWindowInner();
1032   void CleanUp();
1033 
1034   void FreeInnerObjects(bool aForDocumentOpen = false);
1035   nsGlobalWindowInner* CallerInnerWindow();
1036 
1037   // Only to be called on an inner window.
1038   // aDocument must not be null.
1039   void InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument);
1040 
1041   nsresult EnsureClientSource();
1042   nsresult ExecutionReady();
1043 
1044   // Inner windows only.
1045   nsresult DefineArgumentsProperty(nsIArray* aArguments);
1046 
1047   // Get the parent, returns null if this is a toplevel window
1048   nsPIDOMWindowOuter* GetParentInternal();
1049 
1050  public:
1051   // popup tracking
1052   bool IsPopupSpamWindow();
1053 
1054  private:
1055   // A type that methods called by CallOnChildren can return.  If Stop
1056   // is returned then CallOnChildren will stop calling further children.
1057   // If Continue is returned then CallOnChildren will keep calling further
1058   // children.
1059   enum class CallState {
1060     Continue,
1061     Stop,
1062   };
1063 
1064   // Call the given method on the immediate children of this window.  The
1065   // CallState returned by the last child method invocation is returned or
1066   // CallState::Continue if the method returns void.
1067   template <typename Method, typename... Args>
1068   CallState CallOnChildren(Method aMethod, Args&... aArgs);
1069 
1070   // Helper to convert a void returning child method into an implicit
1071   // CallState::Continue value.
1072   template <typename Return, typename Method, typename... Args>
1073   typename std::enable_if<std::is_void<Return>::value,
1074                           nsGlobalWindowInner::CallState>::type
CallChild(nsGlobalWindowInner * aWindow,Method aMethod,Args &...aArgs)1075   CallChild(nsGlobalWindowInner* aWindow, Method aMethod, Args&... aArgs) {
1076     (aWindow->*aMethod)(aArgs...);
1077     return nsGlobalWindowInner::CallState::Continue;
1078   }
1079 
1080   // Helper that passes through the CallState value from a child method.
1081   template <typename Return, typename Method, typename... Args>
1082   typename std::enable_if<
1083       std::is_same<Return, nsGlobalWindowInner::CallState>::value,
1084       nsGlobalWindowInner::CallState>::type
CallChild(nsGlobalWindowInner * aWindow,Method aMethod,Args &...aArgs)1085   CallChild(nsGlobalWindowInner* aWindow, Method aMethod, Args&... aArgs) {
1086     return (aWindow->*aMethod)(aArgs...);
1087   }
1088 
1089   void FreezeInternal();
1090   void ThawInternal();
1091 
1092   CallState ShouldReportForServiceWorkerScopeInternal(const nsACString& aScope,
1093                                                       bool* aResultOut);
1094 
1095  public:
1096   // Timeout Functions
1097   // |interval| is in milliseconds.
1098   int32_t SetTimeoutOrInterval(
1099       JSContext* aCx, mozilla::dom::Function& aFunction, int32_t aTimeout,
1100       const mozilla::dom::Sequence<JS::Value>& aArguments, bool aIsInterval,
1101       mozilla::ErrorResult& aError);
1102   int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
1103                                int32_t aTimeout, bool aIsInterval,
1104                                mozilla::ErrorResult& aError);
1105 
1106   // Return true if |aTimeout| was cleared while its handler ran.
1107   bool RunTimeoutHandler(mozilla::dom::Timeout* aTimeout,
1108                          nsIScriptContext* aScx);
1109 
1110   // Helper Functions
1111   already_AddRefed<nsIDocShellTreeOwner> GetTreeOwner();
1112   already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
1113   bool IsPrivateBrowsing();
1114 
1115   void FireOfflineStatusEventIfChanged();
1116 
1117  public:
1118   // Inner windows only.
1119   nsresult ScheduleNextIdleObserverCallback();
1120   uint32_t GetFuzzTimeMS();
1121   nsresult ScheduleActiveTimerCallback();
1122   uint32_t FindInsertionIndex(IdleObserverHolder* aIdleObserver);
1123   virtual nsresult RegisterIdleObserver(
1124       nsIIdleObserver* aIdleObserverPtr) override;
1125   nsresult FindIndexOfElementToRemove(nsIIdleObserver* aIdleObserver,
1126                                       int32_t* aRemoveElementIndex);
1127   virtual nsresult UnregisterIdleObserver(
1128       nsIIdleObserver* aIdleObserverPtr) override;
1129 
1130   // Inner windows only.
1131   nsresult FireHashchange(const nsAString& aOldURL, const nsAString& aNewURL);
1132 
1133   void FlushPendingNotifications(mozilla::FlushType aType);
1134 
1135   void ScrollTo(const mozilla::CSSIntPoint& aScroll,
1136                 const mozilla::dom::ScrollOptions& aOptions);
1137 
1138   bool IsFrame();
1139 
1140   already_AddRefed<nsIWidget> GetMainWidget();
1141   nsIWidget* GetNearestWidget() const;
1142 
1143   bool IsInModalState();
1144 
1145   virtual void SetFocusedNode(nsIContent* aNode, uint32_t aFocusMethod = 0,
1146                               bool aNeedsFocus = false) override;
1147 
1148   virtual uint32_t GetFocusMethod() override;
1149 
1150   virtual bool ShouldShowFocusRing() override;
1151 
1152   // Inner windows only.
1153   void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
1154 
1155   // See PromiseWindowProxy.h for an explanation.
1156   void AddPendingPromise(mozilla::dom::Promise* aPromise);
1157   void RemovePendingPromise(mozilla::dom::Promise* aPromise);
1158 
1159  public:
1160   virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
1161 
1162  protected:
1163   static void NotifyDOMWindowDestroyed(nsGlobalWindowInner* aWindow);
1164   void NotifyWindowIDDestroyed(const char* aTopic);
1165 
1166   static void NotifyDOMWindowFrozen(nsGlobalWindowInner* aWindow);
1167   static void NotifyDOMWindowThawed(nsGlobalWindowInner* aWindow);
1168 
1169   virtual void UpdateParentTarget() override;
1170 
1171   void InitializeShowFocusRings();
1172 
1173   // Clear the document-dependent slots on our JS wrapper.  Inner windows only.
1174   void ClearDocumentDependentSlots(JSContext* aCx);
1175 
1176   // Inner windows only.
1177   already_AddRefed<mozilla::dom::StorageEvent> CloneStorageEvent(
1178       const nsAString& aType, const RefPtr<mozilla::dom::StorageEvent>& aEvent,
1179       mozilla::ErrorResult& aRv);
1180 
1181  protected:
1182   already_AddRefed<nsICSSDeclaration> GetComputedStyleHelper(
1183       mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
1184       bool aDefaultStylesOnly, mozilla::ErrorResult& aError);
1185   nsresult GetComputedStyleHelper(nsIDOMElement* aElt,
1186                                   const nsAString& aPseudoElt,
1187                                   bool aDefaultStylesOnly,
1188                                   nsICSSDeclaration** aReturn);
1189 
1190   nsGlobalWindowInner* InnerForSetTimeoutOrInterval(
1191       mozilla::ErrorResult& aError);
1192 
1193   void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
1194                       const nsAString& aTargetOrigin,
1195                       JS::Handle<JS::Value> aTransfer,
1196                       nsIPrincipal& aSubjectPrincipal,
1197                       mozilla::ErrorResult& aError);
1198 
1199  private:
1200   // Fire the JS engine's onNewGlobalObject hook.  Only used on inner windows.
1201   void FireOnNewGlobalObject();
1202 
1203   // nsPIDOMWindow{Inner,Outer} should be able to see these helper methods.
1204   friend class nsPIDOMWindowInner;
1205   friend class nsPIDOMWindowOuter;
1206 
1207   mozilla::dom::TabGroup* TabGroupInner();
1208 
1209   bool IsBackgroundInternal() const;
1210 
1211   // NOTE: Chrome Only
DisconnectAndClearGroupMessageManagers()1212   void DisconnectAndClearGroupMessageManagers() {
1213     MOZ_RELEASE_ASSERT(IsChromeWindow());
1214     for (auto iter = mChromeFields.mGroupMessageManagers.Iter(); !iter.Done();
1215          iter.Next()) {
1216       nsIMessageBroadcaster* mm = iter.UserData();
1217       if (mm) {
1218         static_cast<nsFrameMessageManager*>(mm)->Disconnect();
1219       }
1220     }
1221     mChromeFields.mGroupMessageManagers.Clear();
1222   }
1223 
1224   // Call or Cancel mDocumentFlushedResolvers items, and perform MicroTask
1225   // checkpoint after that, and adds observer if new mDocumentFlushedResolvers
1226   // items are added while Promise callbacks inside the checkpoint.
1227   template <bool call>
1228   void CallOrCancelDocumentFlushedResolvers();
1229 
1230   void CallDocumentFlushedResolvers();
1231   void CancelDocumentFlushedResolvers();
1232 
1233  public:
1234   // Dispatch a runnable related to the global.
1235   virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
1236                             already_AddRefed<nsIRunnable>&& aRunnable) override;
1237 
1238   virtual nsISerialEventTarget* EventTargetFor(
1239       mozilla::TaskCategory aCategory) const override;
1240 
1241   virtual mozilla::AbstractThread* AbstractMainThreadFor(
1242       mozilla::TaskCategory aCategory) override;
1243 
1244   void DisableIdleCallbackRequests();
LastIdleRequestHandle()1245   uint32_t LastIdleRequestHandle() const {
1246     return mIdleRequestCallbackCounter - 1;
1247   }
1248   nsresult RunIdleRequest(mozilla::dom::IdleRequest* aRequest,
1249                           DOMHighResTimeStamp aDeadline, bool aDidTimeout);
1250   nsresult ExecuteIdleRequest(TimeStamp aDeadline);
1251   void ScheduleIdleRequestDispatch();
1252   void SuspendIdleRequests();
1253   void ResumeIdleRequests();
1254 
1255   typedef mozilla::LinkedList<RefPtr<mozilla::dom::IdleRequest>> IdleRequests;
1256   void RemoveIdleCallback(mozilla::dom::IdleRequest* aRequest);
1257 
1258  protected:
1259   // Window offline status. Checked to see if we need to fire offline event
1260   bool mWasOffline : 1;
1261 
1262   // Represents whether the inner window's page has had a slow script notice.
1263   // Only used by inner windows; will always be false for outer windows.
1264   // This is used to implement Telemetry measures such as
1265   // SLOW_SCRIPT_PAGE_COUNT.
1266   bool mHasHadSlowScript : 1;
1267 
1268   // Track what sorts of events we need to fire when thawed
1269   bool mNotifyIdleObserversIdleOnThaw : 1;
1270   bool mNotifyIdleObserversActiveOnThaw : 1;
1271 
1272   // Fast way to tell if this is a chrome window (without having to QI).
1273   bool mIsChrome : 1;
1274 
1275   // Hack to indicate whether a chrome window needs its message manager
1276   // to be disconnected, since clean up code is shared in the global
1277   // window superclass.
1278   bool mCleanMessageManager : 1;
1279 
1280   // Indicates that the current document has never received a document focus
1281   // event.
1282   bool mNeedsFocus : 1;
1283   bool mHasFocus : 1;
1284 
1285   // when true, show focus rings for the current focused content only.
1286   // This will be reset when another element is focused
1287   bool mShowFocusRingForContent : 1;
1288 
1289   // true if tab navigation has occurred for this window. Focus rings
1290   // should be displayed.
1291   bool mFocusByKeyOccurred : 1;
1292 
1293   // Indicates whether this window wants gamepad input events
1294   bool mHasGamepad : 1;
1295 
1296   // Indicates whether this window wants VR events
1297   bool mHasVREvents : 1;
1298 
1299   // Indicates whether this window wants VRDisplayActivate events
1300   bool mHasVRDisplayActivateEvents : 1;
1301   nsCheapSet<nsUint32HashKey> mGamepadIndexSet;
1302   nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
1303   bool mHasSeenGamepadInput;
1304 
1305   RefPtr<nsScreen> mScreen;
1306 
1307   RefPtr<mozilla::dom::BarProp> mMenubar;
1308   RefPtr<mozilla::dom::BarProp> mToolbar;
1309   RefPtr<mozilla::dom::BarProp> mLocationbar;
1310   RefPtr<mozilla::dom::BarProp> mPersonalbar;
1311   RefPtr<mozilla::dom::BarProp> mStatusbar;
1312   RefPtr<mozilla::dom::BarProp> mScrollbars;
1313 
1314   RefPtr<nsGlobalWindowObserver> mObserver;
1315   RefPtr<mozilla::dom::Crypto> mCrypto;
1316   RefPtr<mozilla::dom::U2F> mU2F;
1317   RefPtr<mozilla::dom::cache::CacheStorage> mCacheStorage;
1318   RefPtr<mozilla::dom::Console> mConsole;
1319   RefPtr<mozilla::dom::Worklet> mAudioWorklet;
1320   RefPtr<mozilla::dom::Worklet> mPaintWorklet;
1321   // We need to store an nsISupports pointer to this object because the
1322   // mozilla::dom::External class doesn't exist on b2g and using the type
1323   // forward declared here means that ~nsGlobalWindow wouldn't compile because
1324   // it wouldn't see the ~External function's declaration.
1325   nsCOMPtr<nsISupports> mExternal;
1326 
1327   RefPtr<mozilla::dom::Storage> mLocalStorage;
1328   RefPtr<mozilla::dom::Storage> mSessionStorage;
1329 
1330   RefPtr<mozilla::EventListenerManager> mListenerManager;
1331   RefPtr<mozilla::dom::Location> mLocation;
1332   RefPtr<nsHistory> mHistory;
1333   RefPtr<mozilla::dom::CustomElementRegistry> mCustomElements;
1334 
1335   nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
1336   // mTabChild is only ever populated in the content process.
1337   nsCOMPtr<nsITabChild> mTabChild;
1338 
1339   uint32_t mSuspendDepth;
1340   uint32_t mFreezeDepth;
1341 
1342   // the method that was used to focus mFocusedNode
1343   uint32_t mFocusMethod;
1344 
1345   uint32_t mSerial;
1346 
1347   // The current idle request callback handle
1348   uint32_t mIdleRequestCallbackCounter;
1349   IdleRequests mIdleRequestCallbacks;
1350   RefPtr<IdleRequestExecutor> mIdleRequestExecutor;
1351 
1352 #ifdef DEBUG
1353   nsCOMPtr<nsIURI> mLastOpenedURI;
1354 #endif
1355 
1356   bool mCleanedUp;
1357 
1358   nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
1359 
1360   using XBLPrototypeHandlerTable =
1361       nsJSThingHashtable<nsPtrHashKey<nsXBLPrototypeHandler>, JSObject*>;
1362   mozilla::UniquePtr<XBLPrototypeHandlerTable> mCachedXBLPrototypeHandlers;
1363 
1364   RefPtr<mozilla::dom::IDBFactory> mIndexedDB;
1365 
1366   // This counts the number of windows that have been opened in rapid succession
1367   // (i.e. within dom.successive_dialog_time_limit of each other). It is reset
1368   // to 0 once a dialog is opened after dom.successive_dialog_time_limit seconds
1369   // have elapsed without any other dialogs.
1370   uint32_t mDialogAbuseCount;
1371 
1372   // This holds the time when the last modal dialog was shown. If more than
1373   // MAX_DIALOG_LIMIT dialogs are shown within the time span defined by
1374   // dom.successive_dialog_time_limit, we show a checkbox or confirmation prompt
1375   // to allow disabling of further dialogs from this window.
1376   TimeStamp mLastDialogQuitTime;
1377 
1378   // This flag keeps track of whether dialogs are
1379   // currently enabled on this window.
1380   bool mAreDialogsEnabled;
1381 
1382   // This flag keeps track of whether this window is currently
1383   // observing DidRefresh notifications from the refresh driver.
1384   bool mObservingDidRefresh;
1385   // This flag keeps track of whether or not we're going through
1386   // promiseDocumentFlushed resolvers. When true, promiseDocumentFlushed
1387   // cannot be called.
1388   bool mIteratingDocumentFlushedResolvers;
1389 
1390   nsTArray<uint32_t> mEnabledSensors;
1391 
1392 #if defined(MOZ_WIDGET_ANDROID)
1393   mozilla::UniquePtr<mozilla::dom::WindowOrientationObserver>
1394       mOrientationChangeObserver;
1395 #endif
1396 
1397 #ifdef MOZ_WEBSPEECH
1398   RefPtr<mozilla::dom::SpeechSynthesis> mSpeechSynthesis;
1399 #endif
1400 
1401   // This is the CC generation the last time we called CanSkip.
1402   uint32_t mCanSkipCCGeneration;
1403 
1404   // The VR Displays for this window
1405   nsTArray<RefPtr<mozilla::dom::VRDisplay>> mVRDisplays;
1406 
1407   RefPtr<mozilla::dom::VREventObserver> mVREventObserver;
1408 
1409   int64_t mBeforeUnloadListenerCount;
1410 
1411   RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
1412 
1413   mozilla::UniquePtr<mozilla::dom::ClientSource> mClientSource;
1414 
1415   nsTArray<RefPtr<mozilla::dom::Promise>> mPendingPromises;
1416 
1417   nsTArray<mozilla::UniquePtr<PromiseDocumentFlushedResolver>>
1418       mDocumentFlushedResolvers;
1419 
1420   static InnerWindowByIdTable* sInnerWindowsById;
1421 
1422   // Members in the mChromeFields member should only be used in chrome windows.
1423   // All accesses to this field should be guarded by a check of mIsChrome.
1424   struct ChromeFields {
ChromeFieldsChromeFields1425     ChromeFields() : mGroupMessageManagers(1) {}
1426 
1427     nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
1428     nsInterfaceHashtable<nsStringHashKey, nsIMessageBroadcaster>
1429         mGroupMessageManagers;
1430   } mChromeFields;
1431 
1432   // These fields are used by the inner and outer windows to prevent
1433   // programatically moving the window while the mouse is down.
1434   static bool sMouseDown;
1435   static bool sDragServiceDisabled;
1436 
1437   friend class nsDOMScriptableHelper;
1438   friend class nsDOMWindowUtils;
1439   friend class mozilla::dom::PostMessageEvent;
1440   friend class DesktopNotification;
1441   friend class mozilla::dom::TimeoutManager;
1442   friend class IdleRequestExecutor;
1443   friend class nsGlobalWindowOuter;
1444 };
1445 
ToSupports(nsGlobalWindowInner * p)1446 inline nsISupports* ToSupports(nsGlobalWindowInner* p) {
1447   return static_cast<nsIDOMEventTarget*>(p);
1448 }
1449 
ToCanonicalSupports(nsGlobalWindowInner * p)1450 inline nsISupports* ToCanonicalSupports(nsGlobalWindowInner* p) {
1451   return static_cast<nsIDOMEventTarget*>(p);
1452 }
1453 
1454 // XXX: EWW - This is an awful hack - let's not do this
1455 #include "nsGlobalWindowOuter.h"
1456 
GetOwnerGlobal()1457 inline nsIGlobalObject* nsGlobalWindowInner::GetOwnerGlobal() const {
1458   return const_cast<nsGlobalWindowInner*>(this);
1459 }
1460 
GetTopInternal()1461 inline nsGlobalWindowOuter* nsGlobalWindowInner::GetTopInternal() {
1462   nsGlobalWindowOuter* outer = GetOuterWindowInternal();
1463   nsCOMPtr<nsPIDOMWindowOuter> top = outer ? outer->GetTop() : nullptr;
1464   if (top) {
1465     return nsGlobalWindowOuter::Cast(top);
1466   }
1467   return nullptr;
1468 }
1469 
GetScriptableTopInternal()1470 inline nsGlobalWindowOuter* nsGlobalWindowInner::GetScriptableTopInternal() {
1471   nsPIDOMWindowOuter* top = GetScriptableTop();
1472   return nsGlobalWindowOuter::Cast(top);
1473 }
1474 
GetContextInternal()1475 inline nsIScriptContext* nsGlobalWindowInner::GetContextInternal() {
1476   if (mOuterWindow) {
1477     return GetOuterWindowInternal()->mContext;
1478   }
1479 
1480   return nullptr;
1481 }
1482 
GetOuterWindowInternal()1483 inline nsGlobalWindowOuter* nsGlobalWindowInner::GetOuterWindowInternal()
1484     const {
1485   return nsGlobalWindowOuter::Cast(GetOuterWindow());
1486 }
1487 
IsPopupSpamWindow()1488 inline bool nsGlobalWindowInner::IsPopupSpamWindow() {
1489   if (!mOuterWindow) {
1490     return false;
1491   }
1492 
1493   return GetOuterWindowInternal()->mIsPopupSpam;
1494 }
1495 
IsFrame()1496 inline bool nsGlobalWindowInner::IsFrame() {
1497   return GetParentInternal() != nullptr;
1498 }
1499 
1500 #endif /* nsGlobalWindowInner_h___ */
1501