Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / base / nsGlobalWindowOuter.h
blob3c26344c3d45c57606d498008946fc480cd2eb96
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 nsGlobalWindowOuter_h___
8 #define nsGlobalWindowOuter_h___
10 #include "nsPIDOMWindow.h"
12 #include "nsTHashtable.h"
13 #include "nsHashKeys.h"
14 #include "nsRefPtrHashtable.h"
15 #include "nsInterfaceHashtable.h"
17 // Local Includes
18 // Helper Classes
19 #include "nsCOMPtr.h"
20 #include "nsWeakReference.h"
21 #include "nsTHashMap.h"
22 #include "nsCycleCollectionParticipant.h"
24 // Interfaces Needed
25 #include "nsIBrowserDOMWindow.h"
26 #include "nsIInterfaceRequestor.h"
27 #include "nsIScriptGlobalObject.h"
28 #include "nsIScriptObjectPrincipal.h"
29 #include "mozilla/EventListenerManager.h"
30 #include "nsIPrincipal.h"
31 #include "nsSize.h"
32 #include "mozilla/FlushType.h"
33 #include "prclist.h"
34 #include "mozilla/dom/BindingDeclarations.h"
35 #include "mozilla/dom/ChromeMessageBroadcaster.h"
36 #include "mozilla/dom/PopupBlocker.h"
37 #include "mozilla/dom/StorageEvent.h"
38 #include "mozilla/dom/StorageEventBinding.h"
39 #include "mozilla/dom/UnionTypes.h"
40 #include "mozilla/Attributes.h"
41 #include "mozilla/LinkedList.h"
42 #include "nsWrapperCacheInlines.h"
43 #include "mozilla/dom/EventTarget.h"
44 #include "mozilla/dom/WindowBinding.h"
45 #include "Units.h"
46 #include "nsComponentManagerUtils.h"
47 #include "nsCheapSets.h"
48 #include "mozilla/dom/ImageBitmapSource.h"
49 #include "mozilla/UniquePtr.h"
50 #include "mozilla/dom/BrowsingContext.h"
51 #include "X11UndefineNone.h"
53 class nsDocShell;
54 class nsIArray;
55 class nsIBaseWindow;
56 class nsIContent;
57 class nsICSSDeclaration;
58 class nsIDocShellTreeOwner;
59 class nsIDOMWindowUtils;
60 class nsIScrollableFrame;
61 class nsIControllers;
62 class nsIPrintSettings;
63 class nsIScriptContext;
64 class nsIScriptTimeoutHandler;
65 class nsIBrowserChild;
66 class nsITimeoutHandler;
67 class nsIWebBrowserChrome;
68 class nsIWebProgressListener;
69 class mozIDOMWindowProxy;
71 class nsDocShellLoadState;
72 class nsScreen;
73 class nsHistory;
74 class nsGlobalWindowObserver;
75 class nsGlobalWindowInner;
76 class nsDOMWindowUtils;
77 struct nsRect;
79 class nsWindowSizes;
81 namespace mozilla {
82 class AbstractThread;
83 class DOMEventTargetHelper;
84 class ErrorResult;
85 class ThrottledEventQueue;
86 namespace dom {
87 class BarProp;
88 struct ChannelPixelLayout;
89 class Console;
90 class Crypto;
91 class CustomElementRegistry;
92 class DocGroup;
93 class Document;
94 class External;
95 class Function;
96 class Gamepad;
97 enum class ImageBitmapFormat : uint8_t;
98 class IntlUtils;
99 class Location;
100 class MediaQueryList;
101 class Navigator;
102 class OwningExternalOrWindowProxy;
103 class Promise;
104 class PostMessageData;
105 class PostMessageEvent;
106 class PrintPreviewResultInfo;
107 struct RequestInit;
108 class Selection;
109 struct SizeToContentConstraints;
110 class SpeechSynthesis;
111 class Timeout;
112 class U2F;
113 class VRDisplay;
114 enum class VRDisplayEventReason : uint8_t;
115 class VREventObserver;
116 class WakeLock;
117 class Worklet;
118 namespace cache {
119 class CacheStorage;
120 } // namespace cache
121 class IDBFactory;
122 } // namespace dom
123 namespace layout {
124 class RemotePrintJobChild;
125 } // namespace layout
126 } // namespace mozilla
128 extern const JSClass OuterWindowProxyClass;
130 //*****************************************************************************
131 // nsGlobalWindowOuter
132 //*****************************************************************************
134 // nsGlobalWindowOuter inherits PRCList for maintaining a list of all inner
135 // windows still in memory for any given outer window. This list is needed to
136 // ensure that mOuterWindow doesn't end up dangling. The nature of PRCList means
137 // that the window itself is always in the list, and an outer window's list will
138 // also contain all inner window objects that are still in memory (and in
139 // reality all inner window object's lists also contain its outer and all other
140 // inner windows belonging to the same outer window, but that's an unimportant
141 // side effect of inheriting PRCList).
143 class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
144 public nsPIDOMWindowOuter,
145 private nsIDOMWindow,
146 public nsIScriptGlobalObject,
147 public nsIScriptObjectPrincipal,
148 public nsSupportsWeakReference,
149 public nsIInterfaceRequestor,
150 public PRCListStr {
151 public:
152 using OuterWindowByIdTable =
153 nsTHashMap<nsUint64HashKey, nsGlobalWindowOuter*>;
155 using PrintPreviewResolver =
156 std::function<void(const mozilla::dom::PrintPreviewResultInfo&)>;
158 static void AssertIsOnMainThread()
159 #ifdef DEBUG
161 #else
164 #endif
166 static nsGlobalWindowOuter* Cast(nsPIDOMWindowOuter* aPIWin) {
167 return static_cast<nsGlobalWindowOuter*>(aPIWin);
169 static const nsGlobalWindowOuter* Cast(const nsPIDOMWindowOuter* aPIWin) {
170 return static_cast<const nsGlobalWindowOuter*>(aPIWin);
172 static nsGlobalWindowOuter* Cast(mozIDOMWindowProxy* aWin) {
173 return Cast(nsPIDOMWindowOuter::From(aWin));
176 bool IsOuterWindow() const final { return true; } // Overriding EventTarget
178 static nsGlobalWindowOuter* GetOuterWindowWithId(uint64_t aWindowID) {
179 AssertIsOnMainThread();
181 if (!sOuterWindowsById) {
182 return nullptr;
185 nsGlobalWindowOuter* outerWindow = sOuterWindowsById->Get(aWindowID);
186 return outerWindow;
189 static OuterWindowByIdTable* GetWindowsTable() {
190 AssertIsOnMainThread();
192 return sOuterWindowsById;
195 static nsGlobalWindowOuter* FromSupports(nsISupports* supports) {
196 // Make sure this matches the casts we do in QueryInterface().
197 return (nsGlobalWindowOuter*)(mozilla::dom::EventTarget*)supports;
200 static already_AddRefed<nsGlobalWindowOuter> Create(nsDocShell* aDocShell,
201 bool aIsChrome);
203 // public methods
204 nsPIDOMWindowOuter* GetPrivateParent();
206 // callback for close event
207 void ReallyCloseWindow();
209 // nsISupports
210 NS_DECL_ISUPPORTS_INHERITED
211 NS_IMETHOD_(void) DeleteCycleCollectable() override;
213 // nsWrapperCache
214 virtual JSObject* WrapObject(JSContext* cx,
215 JS::Handle<JSObject*> aGivenProto) override {
216 return EnsureInnerWindow() ? GetWrapper() : nullptr;
219 // nsIGlobalObject
220 bool ShouldResistFingerprinting(RFPTarget aTarget) const final;
221 mozilla::OriginTrials Trials() const final;
222 mozilla::dom::FontFaceSet* GetFonts() final;
224 // nsIGlobalJSObjectHolder
225 JSObject* GetGlobalJSObject() final { return GetWrapper(); }
226 JSObject* GetGlobalJSObjectPreserveColor() const final {
227 return GetWrapperPreserveColor();
230 virtual nsresult EnsureScriptEnvironment() override;
232 virtual nsIScriptContext* GetScriptContext() override;
234 void PoisonOuterWindowProxy(JSObject* aObject);
236 virtual bool IsBlackForCC(bool aTracingNeeded = true) override;
238 // nsIScriptObjectPrincipal
239 virtual nsIPrincipal* GetPrincipal() override;
241 virtual nsIPrincipal* GetEffectiveCookiePrincipal() override;
243 virtual nsIPrincipal* GetEffectiveStoragePrincipal() override;
245 virtual nsIPrincipal* PartitionedPrincipal() override;
247 // nsIDOMWindow
248 NS_DECL_NSIDOMWINDOW
250 mozilla::dom::ChromeMessageBroadcaster* GetMessageManager();
251 mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(
252 const nsAString& aGroup);
254 nsresult OpenJS(const nsAString& aUrl, const nsAString& aName,
255 const nsAString& aOptions,
256 mozilla::dom::BrowsingContext** _retval);
258 virtual mozilla::EventListenerManager* GetExistingListenerManager()
259 const override;
261 virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
263 bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
265 virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override;
267 virtual nsIGlobalObject* GetOwnerGlobal() const override;
269 EventTarget* GetTargetForEventTargetChain() override;
271 using mozilla::dom::EventTarget::DispatchEvent;
272 bool DispatchEvent(mozilla::dom::Event& aEvent,
273 mozilla::dom::CallerType aCallerType,
274 mozilla::ErrorResult& aRv) override;
276 void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
278 nsresult PostHandleEvent(mozilla::EventChainPostVisitor& aVisitor) override;
280 // nsPIDOMWindow
281 virtual nsPIDOMWindowOuter* GetPrivateRoot() override;
283 // Outer windows only.
284 virtual void SetIsBackground(bool aIsBackground) override;
285 virtual void SetChromeEventHandler(
286 mozilla::dom::EventTarget* aChromeEventHandler) override;
288 // Outer windows only.
289 virtual void SetInitialPrincipal(
290 nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP,
291 const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep)
292 override;
294 virtual already_AddRefed<nsISupports> SaveWindowState() override;
295 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsresult RestoreWindowState(
296 nsISupports* aState) override;
298 virtual bool IsSuspended() const override;
299 virtual bool IsFrozen() const override;
301 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) override;
303 // Outer windows only.
304 bool WouldReuseInnerWindow(Document* aNewDocument);
306 void DetachFromDocShell(bool aIsBeingDiscarded);
308 virtual nsresult SetNewDocument(
309 Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
310 mozilla::dom::WindowGlobalChild* aActor = nullptr) override;
312 // Outer windows only.
313 static void PrepareForProcessChange(JSObject* aProxy);
315 // Outer windows only.
316 void DispatchDOMWindowCreated();
318 // Outer windows only.
319 virtual void EnsureSizeAndPositionUpToDate() override;
321 virtual void SuppressEventHandling() override;
322 virtual void UnsuppressEventHandling() override;
324 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsGlobalWindowOuter* EnterModalState()
325 override;
326 virtual void LeaveModalState() override;
328 // Outer windows only.
329 virtual bool CanClose() override;
330 virtual void ForceClose() override;
332 // Outer windows only.
333 virtual bool DispatchCustomEvent(
334 const nsAString& aEventName,
335 mozilla::ChromeOnlyDispatch aChromeOnlyDispatch) override;
336 bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
338 // For accessing protected field mFullscreen
339 friend class FullscreenTransitionTask;
341 // Outer windows only.
342 nsresult SetFullscreenInternal(FullscreenReason aReason,
343 bool aIsFullscreen) final;
344 void FullscreenWillChange(bool aIsFullscreen) final;
345 void FinishFullscreenChange(bool aIsFullscreen) final;
346 void ForceFullScreenInWidget() final;
347 void MacFullscreenMenubarOverlapChanged(
348 mozilla::DesktopCoord aOverlapAmount) final;
349 bool SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
350 nsIWidget* aWidget);
351 bool Fullscreen() const;
353 // nsIInterfaceRequestor
354 NS_DECL_NSIINTERFACEREQUESTOR
356 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetterOuter(
357 uint32_t aIndex);
359 already_AddRefed<nsPIDOMWindowOuter> GetInProcessTop() override;
360 // Similar to GetInProcessTop() except that it stops at content frames that
361 // an extension has permission to access. This is used by the third-party
362 // util service in order to determine the top window for a channel which is
363 // used in third-partiness checks.
364 already_AddRefed<nsPIDOMWindowOuter>
365 GetTopExcludingExtensionAccessibleContentFrames(nsIURI* aURIBeingLoaded);
366 nsPIDOMWindowOuter* GetInProcessScriptableTop() override;
367 inline nsGlobalWindowOuter* GetInProcessTopInternal();
369 inline nsGlobalWindowOuter* GetInProcessScriptableTopInternal();
371 already_AddRefed<mozilla::dom::BrowsingContext> GetChildWindow(
372 const nsAString& aName);
374 // Returns true if we've reached the state in windows of this BC group
375 // where we ask the user if further dialogs should be blocked.
377 // This function is implemented in terms of
378 // BrowsingContextGroup::DialogsAreBeingAbused.
379 bool ShouldPromptToBlockDialogs();
381 // These functions are used for controlling and determining whether dialogs
382 // (alert, prompt, confirm) are currently allowed in this browsing context
383 // group. If you want to temporarily disable dialogs, please use
384 // TemporarilyDisableDialogs, not EnableDialogs/DisableDialogs, because
385 // correctly determining whether to re-enable dialogs is actually quite
386 // difficult.
387 void EnableDialogs();
388 void DisableDialogs();
389 // Outer windows only.
390 bool AreDialogsEnabled();
392 class MOZ_RAII TemporarilyDisableDialogs {
393 public:
394 explicit TemporarilyDisableDialogs(mozilla::dom::BrowsingContext* aBC);
395 ~TemporarilyDisableDialogs();
397 private:
398 // This is the browsing context group whose dialog state we messed
399 // with. We just want to keep it alive, because we plan to poke at its
400 // members in our destructor.
401 RefPtr<mozilla::dom::BrowsingContextGroup> mGroup;
402 // This is not a AutoRestore<bool> because that would require careful
403 // member destructor ordering, which is a bit fragile. This way we can
404 // explicitly restore things before we drop our ref to mGroup.
405 bool mSavedDialogsEnabled = false;
407 friend class TemporarilyDisableDialogs;
409 nsIScriptContext* GetContextInternal();
411 bool IsCreatingInnerWindow() const { return mCreatingInnerWindow; }
413 bool IsChromeWindow() const { return mIsChrome; }
415 // GetScrollFrame does not flush. Callers should do it themselves as needed,
416 // depending on which info they actually want off the scrollable frame.
417 nsIScrollableFrame* GetScrollFrame();
419 // Outer windows only.
420 void UnblockScriptedClosing();
422 static void Init();
423 static void ShutDown();
424 static bool IsCallerChrome();
426 friend class WindowStateHolder;
428 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
429 nsGlobalWindowOuter, mozilla::dom::EventTarget)
431 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
432 virtual void SetReadyForFocus() override;
433 virtual void PageHidden() override;
436 * Set a arguments for this window. This will be set on the window
437 * right away (if there's an existing document) and it will also be
438 * installed on the window when the next document is loaded.
440 * This function passes |arguments| back from nsWindowWatcher to
441 * nsGlobalWindow.
443 nsresult SetArguments(nsIArray* aArguments);
445 bool IsClosedOrClosing() {
446 return (mIsClosed || mInClose || mHavePendingClose || mCleanedUp);
449 bool IsCleanedUp() const { return mCleanedUp; }
451 virtual void FirePopupBlockedEvent(
452 Document* aDoc, nsIURI* aPopupURI, const nsAString& aPopupWindowName,
453 const nsAString& aPopupWindowFeatures) override;
455 void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
457 void AllowScriptsToClose() { mAllowScriptsToClose = true; }
459 // Outer windows only.
460 uint32_t GetAutoActivateVRDisplayID();
461 // Outer windows only.
462 void SetAutoActivateVRDisplayID(uint32_t aAutoActivateVRDisplayID);
464 #define EVENT(name_, id_, type_, struct_) \
465 mozilla::dom::EventHandlerNonNull* GetOn##name_() { \
466 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
467 return elm ? elm->GetEventHandler(nsGkAtoms::on##name_) : nullptr; \
469 void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) { \
470 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
471 if (elm) { \
472 elm->SetEventHandler(nsGkAtoms::on##name_, handler); \
475 #define ERROR_EVENT(name_, id_, type_, struct_) \
476 mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_() { \
477 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
478 return elm ? elm->GetOnErrorEventHandler() : nullptr; \
480 void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler) { \
481 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
482 if (elm) { \
483 elm->SetEventHandler(handler); \
486 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_) \
487 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_() { \
488 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
489 return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr; \
491 void SetOn##name_( \
492 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) { \
493 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
494 if (elm) { \
495 elm->SetEventHandler(handler); \
498 #define WINDOW_ONLY_EVENT EVENT
499 #define TOUCH_EVENT EVENT
500 #include "mozilla/EventNameList.h"
501 #undef TOUCH_EVENT
502 #undef WINDOW_ONLY_EVENT
503 #undef BEFOREUNLOAD_EVENT
504 #undef ERROR_EVENT
505 #undef EVENT
507 nsISupports* GetParentObject() { return nullptr; }
509 Document* GetDocument() { return GetDoc(); }
510 void GetNameOuter(nsAString& aName);
511 void SetNameOuter(const nsAString& aName, mozilla::ErrorResult& aError);
512 mozilla::dom::Location* GetLocation() override;
513 void GetStatusOuter(nsAString& aStatus);
514 void SetStatusOuter(const nsAString& aStatus);
515 void CloseOuter(bool aTrustedCaller);
516 nsresult Close() override;
517 bool GetClosedOuter();
518 bool Closed() override;
519 void StopOuter(mozilla::ErrorResult& aError);
520 // TODO: Convert FocusOuter() to MOZ_CAN_RUN_SCRIPT and get rid of the
521 // kungFuDeathGrip in it.
522 MOZ_CAN_RUN_SCRIPT_BOUNDARY void FocusOuter(
523 mozilla::dom::CallerType aCallerType, bool aFromOtherProcess,
524 uint64_t aActionId);
525 nsresult Focus(mozilla::dom::CallerType aCallerType) override;
526 // TODO: Convert BlurOuter() to MOZ_CAN_RUN_SCRIPT and get rid of the
527 // kungFuDeathGrip in it.
528 MOZ_CAN_RUN_SCRIPT_BOUNDARY void BlurOuter(
529 mozilla::dom::CallerType aCallerType);
530 mozilla::dom::WindowProxyHolder GetFramesOuter();
531 uint32_t Length();
532 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
534 nsresult GetPrompter(nsIPrompt** aPrompt) override;
536 protected:
537 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
538 GetOpenerWindowOuter();
539 // Initializes the mWasOffline member variable
540 void InitWasOffline();
542 public:
543 nsPIDOMWindowOuter* GetSameProcessOpener();
544 already_AddRefed<mozilla::dom::BrowsingContext> GetOpenerBrowsingContext();
545 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetOpener() override;
546 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetParentOuter();
547 already_AddRefed<nsPIDOMWindowOuter> GetInProcessParent() override;
548 nsPIDOMWindowOuter* GetInProcessScriptableParent() override;
549 nsPIDOMWindowOuter* GetInProcessScriptableParentOrNull() override;
550 mozilla::dom::Element* GetFrameElement(nsIPrincipal& aSubjectPrincipal);
551 mozilla::dom::Element* GetFrameElement() override;
552 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> OpenOuter(
553 const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions,
554 mozilla::ErrorResult& aError);
555 nsresult Open(const nsAString& aUrl, const nsAString& aName,
556 const nsAString& aOptions, nsDocShellLoadState* aLoadState,
557 bool aForceNoOpener,
558 mozilla::dom::BrowsingContext** _retval) override;
559 mozilla::dom::Navigator* GetNavigator() override;
561 protected:
562 bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
563 nsIPrincipal& aSubjectPrincipal,
564 mozilla::ErrorResult& aError);
566 public:
567 void AlertOuter(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
568 mozilla::ErrorResult& aError);
569 bool ConfirmOuter(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
570 mozilla::ErrorResult& aError);
571 void PromptOuter(const nsAString& aMessage, const nsAString& aInitial,
572 nsAString& aReturn, nsIPrincipal& aSubjectPrincipal,
573 mozilla::ErrorResult& aError);
575 MOZ_CAN_RUN_SCRIPT void PrintOuter(mozilla::ErrorResult& aError);
577 enum class IsPreview : bool { No, Yes };
578 enum class IsForWindowDotPrint : bool { No, Yes };
579 MOZ_CAN_RUN_SCRIPT mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
580 Print(nsIPrintSettings*,
581 mozilla::layout::RemotePrintJobChild* aRemotePrintJob,
582 nsIWebProgressListener*, nsIDocShell*, IsPreview, IsForWindowDotPrint,
583 PrintPreviewResolver&&, RefPtr<mozilla::dom::BrowsingContext>*,
584 mozilla::ErrorResult&);
585 mozilla::dom::Selection* GetSelectionOuter();
586 already_AddRefed<mozilla::dom::Selection> GetSelection() override;
587 nsScreen* GetScreen();
588 void MoveToOuter(int32_t aXPos, int32_t aYPos,
589 mozilla::dom::CallerType aCallerType,
590 mozilla::ErrorResult& aError);
591 void MoveByOuter(int32_t aXDif, int32_t aYDif,
592 mozilla::dom::CallerType aCallerType,
593 mozilla::ErrorResult& aError);
594 nsresult MoveBy(int32_t aXDif, int32_t aYDif) override;
595 void ResizeToOuter(int32_t aWidth, int32_t aHeight,
596 mozilla::dom::CallerType aCallerType,
597 mozilla::ErrorResult& aError);
598 void ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
599 mozilla::dom::CallerType aCallerType,
600 mozilla::ErrorResult& aError);
601 double GetScrollXOuter();
602 double GetScrollYOuter();
604 MOZ_CAN_RUN_SCRIPT_BOUNDARY
605 void SizeToContentOuter(mozilla::dom::CallerType,
606 const mozilla::dom::SizeToContentConstraints&,
607 mozilla::ErrorResult&);
608 nsIControllers* GetControllersOuter(mozilla::ErrorResult& aError);
609 nsresult GetControllers(nsIControllers** aControllers) override;
610 float GetMozInnerScreenXOuter(mozilla::dom::CallerType aCallerType);
611 float GetMozInnerScreenYOuter(mozilla::dom::CallerType aCallerType);
612 bool GetFullscreenOuter();
613 bool GetFullScreen() override;
614 void SetFullscreenOuter(bool aFullscreen, mozilla::ErrorResult& aError);
615 nsresult SetFullScreen(bool aFullscreen) override;
616 bool FindOuter(const nsAString& aString, bool aCaseSensitive, bool aBackwards,
617 bool aWrapAround, bool aWholeWord, bool aSearchInFrames,
618 bool aShowDialog, mozilla::ErrorResult& aError);
620 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> OpenDialogOuter(
621 JSContext* aCx, const nsAString& aUrl, const nsAString& aName,
622 const nsAString& aOptions,
623 const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
624 mozilla::ErrorResult& aError);
625 nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
626 const nsAString& aOptions, nsISupports* aExtraArgument,
627 mozilla::dom::BrowsingContext** _retval) override;
628 void UpdateCommands(const nsAString& anAction) override;
630 already_AddRefed<mozilla::dom::BrowsingContext> GetContentInternal(
631 mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError);
632 void GetContentOuter(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
633 mozilla::dom::CallerType aCallerType,
634 mozilla::ErrorResult& aError);
636 // ChromeWindow bits. Do NOT call these unless your window is in
637 // fact chrome.
638 nsIBrowserDOMWindow* GetBrowserDOMWindow();
639 void SetBrowserDOMWindowOuter(nsIBrowserDOMWindow* aBrowserWindow);
640 void SetCursorOuter(const nsACString& aCursor, mozilla::ErrorResult& aError);
642 already_AddRefed<nsWindowRoot> GetWindowRootOuter();
644 nsIDOMWindowUtils* WindowUtils();
646 virtual bool IsInSyncOperation() override;
648 public:
649 double GetInnerWidthOuter(mozilla::ErrorResult& aError);
651 protected:
652 nsresult GetInnerWidth(double* aInnerWidth) override;
654 public:
655 double GetInnerHeightOuter(mozilla::ErrorResult& aError);
657 protected:
658 nsresult GetInnerHeight(double* aInnerHeight) override;
659 int32_t GetScreenXOuter(mozilla::dom::CallerType aCallerType,
660 mozilla::ErrorResult& aError);
661 int32_t GetScreenYOuter(mozilla::dom::CallerType aCallerType,
662 mozilla::ErrorResult& aError);
663 int32_t GetOuterWidthOuter(mozilla::dom::CallerType aCallerType,
664 mozilla::ErrorResult& aError);
665 int32_t GetOuterHeightOuter(mozilla::dom::CallerType aCallerType,
666 mozilla::ErrorResult& aError);
668 friend class HashchangeCallback;
669 friend class mozilla::dom::BarProp;
671 // Object Management
672 virtual ~nsGlobalWindowOuter();
673 void DropOuterWindowDocs();
674 void CleanUp();
675 void ClearControllers();
676 // Outer windows only.
677 void FinalClose();
679 inline void MaybeClearInnerWindow(nsPIDOMWindowInner* aExpectedInner);
681 // Get the parent, returns null if this is a toplevel window
682 nsPIDOMWindowOuter* GetInProcessParentInternal();
684 protected:
685 // Window Control Functions
687 // Outer windows only.
688 virtual nsresult OpenNoNavigate(
689 const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions,
690 mozilla::dom::BrowsingContext** _retval) override;
692 private:
693 explicit nsGlobalWindowOuter(uint64_t aWindowID);
695 enum class PrintKind : uint8_t { None, InternalPrint, WindowDotPrint };
698 * @param aUrl the URL we intend to load into the window. If aNavigate is
699 * true, we'll actually load this URL into the window. Otherwise,
700 * aUrl is advisory; OpenInternal will not load the URL into the
701 * new window.
703 * @param aName the name to use for the new window
705 * @param aOptions the window options to use for the new window
707 * @param aDialog true when called from variants of OpenDialog. If this is
708 * true, this method will skip popup blocking checks. The aDialog
709 * argument is passed on to the window watcher.
711 * @param aCalledNoScript true when called via the [noscript] open()
712 * and openDialog() methods. When this is true, we do NOT want to use
713 * the JS stack for things like caller determination.
715 * @param aDoJSFixups true when this is the content-accessible JS version of
716 * window opening. When true, popups do not cause us to throw, we save
717 * the caller's principal in the new window for later consumption, and
718 * we make sure that there is a document in the newly-opened window.
719 * Note that this last will only be done if the newly-opened window is
720 * non-chrome.
722 * @param aNavigate true if we should navigate to the provided URL, false
723 * otherwise. When aNavigate is false, we also skip our can-load
724 * security check, on the assumption that whoever *actually* loads this
725 * page will do their own security check.
727 * @param argv The arguments to pass to the new window. The first
728 * three args, if present, will be aUrl, aName, and aOptions. So this
729 * param only matters if there are more than 3 arguments.
731 * @param aExtraArgument Another way to pass arguments in. This is mutually
732 * exclusive with the argv approach.
734 * @param aLoadState to be passed on along to the windowwatcher.
736 * @param aForceNoOpener if true, will act as if "noopener" were passed in
737 * aOptions, but without affecting any other window
738 * features.
740 * @param aPrintKind Whether this is a browser created for printing, and
741 * if so for which kind of print.
743 * @param aReturn [out] The window that was opened, if any. Will be null if
744 * aForceNoOpener is true of if aOptions contains
745 * "noopener".
747 * Outer windows only.
749 nsresult OpenInternal(const nsAString& aUrl, const nsAString& aName,
750 const nsAString& aOptions, bool aDialog,
751 bool aContentModal, bool aCalledNoScript,
752 bool aDoJSFixups, bool aNavigate, nsIArray* argv,
753 nsISupports* aExtraArgument,
754 nsDocShellLoadState* aLoadState, bool aForceNoOpener,
755 PrintKind aPrintKind,
756 mozilla::dom::BrowsingContext** aReturn);
758 public:
759 nsresult SecurityCheckURL(const char* aURL, nsIURI** aURI);
761 mozilla::dom::PopupBlocker::PopupControlState RevisePopupAbuseLevel(
762 mozilla::dom::PopupBlocker::PopupControlState aState);
763 void FireAbuseEvents(const nsAString& aPopupURL,
764 const nsAString& aPopupWindowName,
765 const nsAString& aPopupWindowFeatures);
767 void FlushPendingNotifications(mozilla::FlushType aType);
769 // Outer windows only.
770 void EnsureReflowFlushAndPaint();
771 void CheckSecurityWidthAndHeight(int32_t* width, int32_t* height,
772 mozilla::dom::CallerType aCallerType);
773 void CheckSecurityLeftAndTop(int32_t* left, int32_t* top,
774 mozilla::dom::CallerType aCallerType);
776 // Outer windows only.
777 // Arguments to this function should have values in app units
778 void SetCSSViewportWidthAndHeight(nscoord width, nscoord height);
780 static bool CanSetProperty(const char* aPrefName);
782 static void MakeMessageWithPrincipal(nsAString& aOutMessage,
783 nsIPrincipal* aSubjectPrincipal,
784 bool aUseHostPort,
785 const char* aNullMessage,
786 const char* aContentMessage,
787 const char* aFallbackMessage);
789 // Outer windows only.
790 MOZ_CAN_RUN_SCRIPT_BOUNDARY
791 bool CanMoveResizeWindows(mozilla::dom::CallerType aCallerType);
793 // If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
794 // just flush our parent and only flush ourselves if we think we need to.
795 // Outer windows only.
796 mozilla::CSSPoint GetScrollXY(bool aDoFlush);
798 int32_t GetScrollBoundaryOuter(mozilla::Side aSide);
800 // Outer windows only.
801 nsresult GetInnerSize(mozilla::CSSSize& aSize);
802 mozilla::CSSIntSize GetOuterSize(mozilla::dom::CallerType aCallerType,
803 mozilla::ErrorResult& aError);
804 nsRect GetInnerScreenRect();
805 static mozilla::Maybe<mozilla::CSSIntSize> GetRDMDeviceSize(
806 const Document& aDocument);
808 // Outer windows only.
809 // If aLookForCallerOnJSStack is true, this method will look at the JS stack
810 // to determine who the caller is. If it's false, it'll use |this| as the
811 // caller.
812 bool WindowExists(const nsAString& aName, bool aForceNoOpener,
813 bool aLookForCallerOnJSStack);
815 already_AddRefed<nsIWidget> GetMainWidget();
816 nsIWidget* GetNearestWidget() const;
818 bool IsInModalState();
820 // Convenience functions for the methods which call methods of nsIBaseWindow
821 // because it takes/returns device pixels. Unfortunately, mPresContext may
822 // have older scale value for the corresponding widget. Therefore, these
823 // helper methods convert between CSS pixels and device pixels with aWindow.
825 // FIXME(emilio): Seems like updating the pres context dpi sync shouldn't be
826 // all that much work and should avoid some hackiness?
827 mozilla::CSSToLayoutDeviceScale CSSToDevScaleForBaseWindow(nsIBaseWindow*);
829 void SetFocusedElement(mozilla::dom::Element* aElement,
830 uint32_t aFocusMethod = 0,
831 bool aNeedsFocus = false) override;
833 uint32_t GetFocusMethod() override;
835 bool ShouldShowFocusRing() override;
837 public:
838 already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
840 protected:
841 void NotifyWindowIDDestroyed(const char* aTopic);
843 void ClearStatus();
845 void UpdateParentTarget() override;
847 protected:
848 // Helper for getComputedStyle and getDefaultComputedStyle
849 already_AddRefed<nsICSSDeclaration> GetComputedStyleHelperOuter(
850 mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
851 bool aDefaultStylesOnly, mozilla::ErrorResult& aRv);
853 // Outer windows only.
854 void PreloadLocalStorage();
856 mozilla::CSSPoint ScreenEdgeSlop();
857 mozilla::CSSCoord ScreenEdgeSlopX() { return ScreenEdgeSlop().X(); }
858 mozilla::CSSCoord ScreenEdgeSlopY() { return ScreenEdgeSlop().Y(); }
860 // Returns CSS pixels based on primary screen. Outer windows only.
861 mozilla::CSSIntPoint GetScreenXY(mozilla::dom::CallerType aCallerType,
862 mozilla::ErrorResult& aError);
864 void PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessage,
865 const nsAString& aTargetOrigin,
866 JS::Handle<JS::Value> aTransfer,
867 nsIPrincipal& aSubjectPrincipal,
868 mozilla::ErrorResult& aError);
870 public:
872 * Compute the principal to use for checking against the target principal in a
873 * postMessage call.
875 * @param aTargetOrigin The value passed as the targetOrigin argument to the
876 * postMessage call.
878 * @param aTargetOriginURI The origin of the URI contained in aTargetOrigin
879 * (see GatherPostMessageData).
881 * @param aCallerPrincipal The principal of the incumbent global of the
882 * postMessage call (see GatherPostMessageData).
884 * @param aSubjectPrincipal The subject principal for the postMessage call.
886 * @param aProvidedPrincipal [out] The principal to use for checking against
887 * the target's principal.
889 * @return Whether the postMessage call should continue or return now.
891 bool GetPrincipalForPostMessage(const nsAString& aTargetOrigin,
892 nsIURI* aTargetOriginURI,
893 nsIPrincipal* aCallerPrincipal,
894 nsIPrincipal& aSubjectPrincipal,
895 nsIPrincipal** aProvidedPrincipal);
897 private:
899 * Gather the necessary data from the caller for a postMessage call.
901 * @param aCx The JSContext.
903 * @param aTargetOrigin The value passed as the targetOrigin argument to the
904 * postMessage call.
906 * @param aSource [out] The browsing context for the incumbent global.
908 * @param aOrigin [out] The value to use for the origin property of the
909 * MessageEvent object.
911 * @param aTargetOriginURI [out] The origin of the URI contained in
912 * aTargetOrigin, null if aTargetOrigin is "/" or "*".
914 * @param aCallerPrincipal [out] The principal of the incumbent global of the
915 * postMessage call.
917 * @param aCallerInnerWindow [out] Inner window of the caller of
918 * postMessage, or null if the incumbent global is not a Window.
920 * @param aCallerURI [out] The URI of the document of the incumbent
921 * global if it's a Window, null otherwise.
923 * @param aCallerAgentCluterId [out] If a non-nullptr is passed, it would
924 * return the caller's agent cluster id.
926 * @param aScriptLocation [out] If we do not have a caller's URI, then
927 * use script location as a sourcename for creating an error object.
929 * @param aError [out] The error, if any.
931 * @return Whether the postMessage call should continue or return now.
933 static bool GatherPostMessageData(
934 JSContext* aCx, const nsAString& aTargetOrigin,
935 mozilla::dom::BrowsingContext** aSource, nsAString& aOrigin,
936 nsIURI** aTargetOriginURI, nsIPrincipal** aCallerPrincipal,
937 nsGlobalWindowInner** aCallerInnerWindow, nsIURI** aCallerURI,
938 mozilla::Maybe<nsID>* aCallerAgentClusterId, nsACString* aScriptLocation,
939 mozilla::ErrorResult& aError);
941 // Ask the user if further dialogs should be blocked, if dialogs are currently
942 // being abused. This is used in the cases where we have no modifiable UI to
943 // show, in that case we show a separate dialog to ask this question.
944 bool ConfirmDialogIfNeeded();
946 // Helper called after moving/resizing, to update docShell's presContext
947 // if we have caused a resolution change by moving across monitors.
948 void CheckForDPIChange();
950 private:
951 enum class SecureContextFlags { eDefault, eIgnoreOpener };
952 // Called only on outer windows to compute the value that will be returned by
953 // IsSecureContext() for the inner window that corresponds to aDocument.
954 bool ComputeIsSecureContext(
955 Document* aDocument,
956 SecureContextFlags aFlags = SecureContextFlags::eDefault);
958 void SetDocShell(nsDocShell* aDocShell);
960 // nsPIDOMWindow{Inner,Outer} should be able to see these helper methods.
961 friend class nsPIDOMWindowInner;
962 friend class nsPIDOMWindowOuter;
964 void SetIsBackgroundInternal(bool aIsBackground);
966 nsresult GetInterfaceInternal(const nsIID& aIID, void** aSink);
968 void MaybeAllowStorageForOpenedWindow(nsIURI* aURI);
970 bool IsOnlyTopLevelDocumentInSHistory();
972 void MaybeResetWindowName(Document* aNewDocument);
974 public:
975 bool DelayedPrintUntilAfterLoad() const {
976 return mDelayedPrintUntilAfterLoad;
979 bool DelayedCloseForPrinting() const { return mDelayedCloseForPrinting; }
981 void StopDelayingPrintingUntilAfterLoad() {
982 mShouldDelayPrintUntilAfterLoad = false;
985 // Dispatch a runnable related to the global.
986 nsresult Dispatch(already_AddRefed<nsIRunnable>&&) const final;
987 nsISerialEventTarget* SerialEventTarget() const final;
989 protected:
990 nsresult ProcessWidgetFullscreenRequest(FullscreenReason aReason,
991 bool aFullscreen);
993 // Indicates whether browser window should be in fullscreen mode and the
994 // reason, e.g. browser fullscreen mode or DOM fullscreen API, which should
995 // never be ForForceExitFullscreen. Nothing if browser window should not be in
996 // fullscreen mode.
997 mozilla::Maybe<FullscreenReason> mFullscreen;
999 // Indicates whether new fullscreen request have been made when previous
1000 // fullscreen request is still in-process.
1001 bool mFullscreenHasChangedDuringProcessing : 1;
1003 using FullscreenRequest = struct FullscreenRequest {
1004 FullscreenRequest(FullscreenReason aReason, bool aFullscreen)
1005 : mReason(aReason), mFullscreen(aFullscreen) {
1006 MOZ_ASSERT(
1007 mReason != FullscreenReason::ForForceExitFullscreen || !mFullscreen,
1008 "FullscreenReason::ForForceExitFullscreen can only be used with "
1009 "exiting fullscreen");
1011 FullscreenReason mReason;
1012 bool mFullscreen : 1;
1014 // The current in-process fullscreen request. Nothing if there is no
1015 // in-process request.
1016 mozilla::Maybe<FullscreenRequest> mInProcessFullscreenRequest;
1018 bool mForceFullScreenInWidget : 1;
1019 bool mIsClosed : 1;
1020 bool mInClose : 1;
1021 // mHavePendingClose means we've got a termination function set to
1022 // close us when the JS stops executing or that we have a close
1023 // event posted. If this is set, just ignore window.close() calls.
1024 bool mHavePendingClose : 1;
1026 // Indicates whether scripts are allowed to close this window.
1027 bool mBlockScriptedClosingFlag : 1;
1029 // Window offline status. Checked to see if we need to fire offline event
1030 bool mWasOffline : 1;
1032 // Indicates whether we're in the middle of creating an initializing
1033 // a new inner window object.
1034 bool mCreatingInnerWindow : 1;
1036 // Fast way to tell if this is a chrome window (without having to QI).
1037 bool mIsChrome : 1;
1039 // whether scripts may close the window,
1040 // even if "dom.allow_scripts_to_close_windows" is false.
1041 bool mAllowScriptsToClose : 1;
1043 bool mTopLevelOuterContentWindow : 1;
1045 // Whether we've delayed a print until after load.
1046 bool mDelayedPrintUntilAfterLoad : 1;
1047 // Whether we've delayed a close() operation because there was a pending
1048 // print() operation.
1049 bool mDelayedCloseForPrinting : 1;
1050 // Whether we should delay printing until after load.
1051 bool mShouldDelayPrintUntilAfterLoad : 1;
1053 nsCOMPtr<nsIScriptContext> mContext;
1054 nsCOMPtr<nsIControllers> mControllers;
1056 // For |window.arguments|, via |openDialog|.
1057 nsCOMPtr<nsIArray> mArguments;
1059 RefPtr<nsDOMWindowUtils> mWindowUtils;
1060 nsString mStatus;
1062 RefPtr<mozilla::dom::Storage> mLocalStorage;
1064 nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
1065 nsCOMPtr<nsIPrincipal> mDocumentCookiePrincipal;
1066 nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
1067 nsCOMPtr<nsIPrincipal> mDocumentPartitionedPrincipal;
1069 #ifdef DEBUG
1070 uint32_t mSerial;
1072 bool mSetOpenerWindowCalled;
1073 nsCOMPtr<nsIURI> mLastOpenedURI;
1074 #endif
1076 bool mCleanedUp;
1078 // It's useful when we get matched EnterModalState/LeaveModalState calls, in
1079 // which case the outer window is responsible for unsuspending events on the
1080 // documents. If we don't (for example, if the outer window is closed before
1081 // the LeaveModalState call), then the inner window whose mDoc is in our
1082 // mSuspendedDocs is responsible for unsuspending.
1083 nsTArray<RefPtr<Document>> mSuspendedDocs;
1085 // This is the CC generation the last time we called CanSkip.
1086 uint32_t mCanSkipCCGeneration;
1088 // When non-zero, the document should receive a vrdisplayactivate event
1089 // after loading. The value is the ID of the VRDisplay that content should
1090 // begin presentation on.
1091 uint32_t mAutoActivateVRDisplayID;
1093 static OuterWindowByIdTable* sOuterWindowsById;
1095 // Members in the mChromeFields member should only be used in chrome windows.
1096 // All accesses to this field should be guarded by a check of mIsChrome.
1097 struct ChromeFields {
1098 nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
1099 // A weak pointer to the PresShell that we are doing fullscreen for.
1100 // The pointer being set indicates we've set the IsInFullscreenChange
1101 // flag on this pres shell.
1102 nsWeakPtr mFullscreenPresShell;
1103 } mChromeFields;
1105 // Whether the chrome window is currently in a full screen transition. This
1106 // flag is updated from FullscreenTransitionTask.
1107 bool mIsInFullScreenTransition = false;
1109 friend class nsDOMWindowUtils;
1110 friend class mozilla::dom::BrowsingContext;
1111 friend class mozilla::dom::PostMessageEvent;
1112 friend class mozilla::dom::TimeoutManager;
1113 friend class nsGlobalWindowInner;
1116 inline nsISupports* ToSupports(nsGlobalWindowOuter* p) {
1117 return static_cast<mozilla::dom::EventTarget*>(p);
1120 inline nsISupports* ToCanonicalSupports(nsGlobalWindowOuter* p) {
1121 return static_cast<mozilla::dom::EventTarget*>(p);
1124 inline nsGlobalWindowOuter* nsGlobalWindowOuter::GetInProcessTopInternal() {
1125 nsCOMPtr<nsPIDOMWindowOuter> top = GetInProcessTop();
1126 if (top) {
1127 return nsGlobalWindowOuter::Cast(top);
1129 return nullptr;
1132 inline nsGlobalWindowOuter*
1133 nsGlobalWindowOuter::GetInProcessScriptableTopInternal() {
1134 nsPIDOMWindowOuter* top = GetInProcessScriptableTop();
1135 return nsGlobalWindowOuter::Cast(top);
1138 inline nsIScriptContext* nsGlobalWindowOuter::GetContextInternal() {
1139 return mContext;
1142 inline void nsGlobalWindowOuter::MaybeClearInnerWindow(
1143 nsPIDOMWindowInner* aExpectedInner) {
1144 if (mInnerWindow == aExpectedInner) {
1145 mInnerWindow = nullptr;
1149 #endif /* nsGlobalWindowOuter_h___ */