Bug 1852754: part 9) Add tests for dynamically loading <link rel="prefetch"> elements...
[gecko.git] / dom / base / nsGlobalWindowOuter.h
blob361ffe4b6adaf13e6536bd7825cb208a4b8a8665
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 RequestOrUSVString;
109 class Selection;
110 struct SizeToContentConstraints;
111 class SpeechSynthesis;
112 class Timeout;
113 class U2F;
114 class VRDisplay;
115 enum class VRDisplayEventReason : uint8_t;
116 class VREventObserver;
117 class WakeLock;
118 class Worklet;
119 namespace cache {
120 class CacheStorage;
121 } // namespace cache
122 class IDBFactory;
123 } // namespace dom
124 namespace layout {
125 class RemotePrintJobChild;
126 } // namespace layout
127 } // namespace mozilla
129 extern const JSClass OuterWindowProxyClass;
131 //*****************************************************************************
132 // nsGlobalWindowOuter
133 //*****************************************************************************
135 // nsGlobalWindowOuter inherits PRCList for maintaining a list of all inner
136 // windows still in memory for any given outer window. This list is needed to
137 // ensure that mOuterWindow doesn't end up dangling. The nature of PRCList means
138 // that the window itself is always in the list, and an outer window's list will
139 // also contain all inner window objects that are still in memory (and in
140 // reality all inner window object's lists also contain its outer and all other
141 // inner windows belonging to the same outer window, but that's an unimportant
142 // side effect of inheriting PRCList).
144 class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
145 public nsPIDOMWindowOuter,
146 private nsIDOMWindow,
147 public nsIScriptGlobalObject,
148 public nsIScriptObjectPrincipal,
149 public nsSupportsWeakReference,
150 public nsIInterfaceRequestor,
151 public PRCListStr {
152 public:
153 using OuterWindowByIdTable =
154 nsTHashMap<nsUint64HashKey, nsGlobalWindowOuter*>;
156 using PrintPreviewResolver =
157 std::function<void(const mozilla::dom::PrintPreviewResultInfo&)>;
159 static void AssertIsOnMainThread()
160 #ifdef DEBUG
162 #else
165 #endif
167 static nsGlobalWindowOuter* Cast(nsPIDOMWindowOuter* aPIWin) {
168 return static_cast<nsGlobalWindowOuter*>(aPIWin);
170 static const nsGlobalWindowOuter* Cast(const nsPIDOMWindowOuter* aPIWin) {
171 return static_cast<const nsGlobalWindowOuter*>(aPIWin);
173 static nsGlobalWindowOuter* Cast(mozIDOMWindowProxy* aWin) {
174 return Cast(nsPIDOMWindowOuter::From(aWin));
177 bool IsOuterWindow() const final { return true; } // Overriding EventTarget
179 static nsGlobalWindowOuter* GetOuterWindowWithId(uint64_t aWindowID) {
180 AssertIsOnMainThread();
182 if (!sOuterWindowsById) {
183 return nullptr;
186 nsGlobalWindowOuter* outerWindow = sOuterWindowsById->Get(aWindowID);
187 return outerWindow;
190 static OuterWindowByIdTable* GetWindowsTable() {
191 AssertIsOnMainThread();
193 return sOuterWindowsById;
196 static nsGlobalWindowOuter* FromSupports(nsISupports* supports) {
197 // Make sure this matches the casts we do in QueryInterface().
198 return (nsGlobalWindowOuter*)(mozilla::dom::EventTarget*)supports;
201 static already_AddRefed<nsGlobalWindowOuter> Create(nsDocShell* aDocShell,
202 bool aIsChrome);
204 // public methods
205 nsPIDOMWindowOuter* GetPrivateParent();
207 // callback for close event
208 void ReallyCloseWindow();
210 // nsISupports
211 NS_DECL_ISUPPORTS_INHERITED
212 NS_IMETHOD_(void) DeleteCycleCollectable() override;
214 // nsWrapperCache
215 virtual JSObject* WrapObject(JSContext* cx,
216 JS::Handle<JSObject*> aGivenProto) override {
217 return EnsureInnerWindow() ? GetWrapper() : nullptr;
220 // nsIGlobalObject
221 bool ShouldResistFingerprinting(RFPTarget aTarget) const final;
222 mozilla::OriginTrials Trials() const final;
223 mozilla::dom::FontFaceSet* GetFonts() final;
225 // nsIGlobalJSObjectHolder
226 JSObject* GetGlobalJSObject() final { return GetWrapper(); }
227 JSObject* GetGlobalJSObjectPreserveColor() const final {
228 return GetWrapperPreserveColor();
231 virtual nsresult EnsureScriptEnvironment() override;
233 virtual nsIScriptContext* GetScriptContext() override;
235 void PoisonOuterWindowProxy(JSObject* aObject);
237 virtual bool IsBlackForCC(bool aTracingNeeded = true) override;
239 // nsIScriptObjectPrincipal
240 virtual nsIPrincipal* GetPrincipal() override;
242 virtual nsIPrincipal* GetEffectiveCookiePrincipal() override;
244 virtual nsIPrincipal* GetEffectiveStoragePrincipal() override;
246 virtual nsIPrincipal* PartitionedPrincipal() override;
248 // nsIDOMWindow
249 NS_DECL_NSIDOMWINDOW
251 mozilla::dom::ChromeMessageBroadcaster* GetMessageManager();
252 mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(
253 const nsAString& aGroup);
255 nsresult OpenJS(const nsAString& aUrl, const nsAString& aName,
256 const nsAString& aOptions,
257 mozilla::dom::BrowsingContext** _retval);
259 virtual mozilla::EventListenerManager* GetExistingListenerManager()
260 const override;
262 virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
264 bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
266 virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override;
268 virtual nsIGlobalObject* GetOwnerGlobal() const override;
270 EventTarget* GetTargetForEventTargetChain() override;
272 using mozilla::dom::EventTarget::DispatchEvent;
273 bool DispatchEvent(mozilla::dom::Event& aEvent,
274 mozilla::dom::CallerType aCallerType,
275 mozilla::ErrorResult& aRv) override;
277 void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
279 nsresult PostHandleEvent(mozilla::EventChainPostVisitor& aVisitor) override;
281 // nsPIDOMWindow
282 virtual nsPIDOMWindowOuter* GetPrivateRoot() override;
284 // Outer windows only.
285 virtual void SetIsBackground(bool aIsBackground) override;
286 virtual void SetChromeEventHandler(
287 mozilla::dom::EventTarget* aChromeEventHandler) override;
289 // Outer windows only.
290 virtual void SetInitialPrincipal(
291 nsIPrincipal* aNewWindowPrincipal, nsIContentSecurityPolicy* aCSP,
292 const mozilla::Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCoep)
293 override;
295 virtual already_AddRefed<nsISupports> SaveWindowState() override;
296 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsresult RestoreWindowState(
297 nsISupports* aState) override;
299 virtual bool IsSuspended() const override;
300 virtual bool IsFrozen() const override;
302 virtual nsresult FireDelayedDOMEvents(bool aIncludeSubWindows) override;
304 // Outer windows only.
305 bool WouldReuseInnerWindow(Document* aNewDocument);
307 void DetachFromDocShell(bool aIsBeingDiscarded);
309 virtual nsresult SetNewDocument(
310 Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
311 mozilla::dom::WindowGlobalChild* aActor = nullptr) override;
313 // Outer windows only.
314 static void PrepareForProcessChange(JSObject* aProxy);
316 // Outer windows only.
317 void DispatchDOMWindowCreated();
319 // Outer windows only.
320 virtual void EnsureSizeAndPositionUpToDate() override;
322 virtual void SuppressEventHandling() override;
323 virtual void UnsuppressEventHandling() override;
325 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual nsGlobalWindowOuter* EnterModalState()
326 override;
327 virtual void LeaveModalState() override;
329 // Outer windows only.
330 virtual bool CanClose() override;
331 virtual void ForceClose() override;
333 // Outer windows only.
334 virtual bool DispatchCustomEvent(
335 const nsAString& aEventName,
336 mozilla::ChromeOnlyDispatch aChromeOnlyDispatch) override;
337 bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
339 // For accessing protected field mFullscreen
340 friend class FullscreenTransitionTask;
342 // Outer windows only.
343 nsresult SetFullscreenInternal(FullscreenReason aReason,
344 bool aIsFullscreen) final;
345 void FullscreenWillChange(bool aIsFullscreen) final;
346 void FinishFullscreenChange(bool aIsFullscreen) final;
347 void ForceFullScreenInWidget() final;
348 void MacFullscreenMenubarOverlapChanged(
349 mozilla::DesktopCoord aOverlapAmount) final;
350 bool SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
351 nsIWidget* aWidget);
352 bool Fullscreen() const;
354 // nsIInterfaceRequestor
355 NS_DECL_NSIINTERFACEREQUESTOR
357 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetterOuter(
358 uint32_t aIndex);
360 already_AddRefed<nsPIDOMWindowOuter> GetInProcessTop() override;
361 // Similar to GetInProcessTop() except that it stops at content frames that
362 // an extension has permission to access. This is used by the third-party
363 // util service in order to determine the top window for a channel which is
364 // used in third-partiness checks.
365 already_AddRefed<nsPIDOMWindowOuter>
366 GetTopExcludingExtensionAccessibleContentFrames(nsIURI* aURIBeingLoaded);
367 nsPIDOMWindowOuter* GetInProcessScriptableTop() override;
368 inline nsGlobalWindowOuter* GetInProcessTopInternal();
370 inline nsGlobalWindowOuter* GetInProcessScriptableTopInternal();
372 already_AddRefed<mozilla::dom::BrowsingContext> GetChildWindow(
373 const nsAString& aName);
375 // Returns true if we've reached the state in windows of this BC group
376 // where we ask the user if further dialogs should be blocked.
378 // This function is implemented in terms of
379 // BrowsingContextGroup::DialogsAreBeingAbused.
380 bool ShouldPromptToBlockDialogs();
382 // These functions are used for controlling and determining whether dialogs
383 // (alert, prompt, confirm) are currently allowed in this browsing context
384 // group. If you want to temporarily disable dialogs, please use
385 // TemporarilyDisableDialogs, not EnableDialogs/DisableDialogs, because
386 // correctly determining whether to re-enable dialogs is actually quite
387 // difficult.
388 void EnableDialogs();
389 void DisableDialogs();
390 // Outer windows only.
391 bool AreDialogsEnabled();
393 class MOZ_RAII TemporarilyDisableDialogs {
394 public:
395 explicit TemporarilyDisableDialogs(mozilla::dom::BrowsingContext* aBC);
396 ~TemporarilyDisableDialogs();
398 private:
399 // This is the browsing context group whose dialog state we messed
400 // with. We just want to keep it alive, because we plan to poke at its
401 // members in our destructor.
402 RefPtr<mozilla::dom::BrowsingContextGroup> mGroup;
403 // This is not a AutoRestore<bool> because that would require careful
404 // member destructor ordering, which is a bit fragile. This way we can
405 // explicitly restore things before we drop our ref to mGroup.
406 bool mSavedDialogsEnabled = false;
408 friend class TemporarilyDisableDialogs;
410 nsIScriptContext* GetContextInternal();
412 bool IsCreatingInnerWindow() const { return mCreatingInnerWindow; }
414 bool IsChromeWindow() const { return mIsChrome; }
416 // GetScrollFrame does not flush. Callers should do it themselves as needed,
417 // depending on which info they actually want off the scrollable frame.
418 nsIScrollableFrame* GetScrollFrame();
420 // Outer windows only.
421 void UnblockScriptedClosing();
423 static void Init();
424 static void ShutDown();
425 static bool IsCallerChrome();
427 friend class WindowStateHolder;
429 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
430 nsGlobalWindowOuter, mozilla::dom::EventTarget)
432 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) override;
433 virtual void SetReadyForFocus() override;
434 virtual void PageHidden() override;
437 * Set a arguments for this window. This will be set on the window
438 * right away (if there's an existing document) and it will also be
439 * installed on the window when the next document is loaded.
441 * This function passes |arguments| back from nsWindowWatcher to
442 * nsGlobalWindow.
444 nsresult SetArguments(nsIArray* aArguments);
446 bool IsClosedOrClosing() {
447 return (mIsClosed || mInClose || mHavePendingClose || mCleanedUp);
450 bool IsCleanedUp() const { return mCleanedUp; }
452 virtual void FirePopupBlockedEvent(
453 Document* aDoc, nsIURI* aPopupURI, const nsAString& aPopupWindowName,
454 const nsAString& aPopupWindowFeatures) override;
456 void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
458 void AllowScriptsToClose() { mAllowScriptsToClose = true; }
460 // Outer windows only.
461 uint32_t GetAutoActivateVRDisplayID();
462 // Outer windows only.
463 void SetAutoActivateVRDisplayID(uint32_t aAutoActivateVRDisplayID);
465 #define EVENT(name_, id_, type_, struct_) \
466 mozilla::dom::EventHandlerNonNull* GetOn##name_() { \
467 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
468 return elm ? elm->GetEventHandler(nsGkAtoms::on##name_) : nullptr; \
470 void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) { \
471 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
472 if (elm) { \
473 elm->SetEventHandler(nsGkAtoms::on##name_, handler); \
476 #define ERROR_EVENT(name_, id_, type_, struct_) \
477 mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_() { \
478 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
479 return elm ? elm->GetOnErrorEventHandler() : nullptr; \
481 void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler) { \
482 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
483 if (elm) { \
484 elm->SetEventHandler(handler); \
487 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_) \
488 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_() { \
489 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
490 return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr; \
492 void SetOn##name_( \
493 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) { \
494 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
495 if (elm) { \
496 elm->SetEventHandler(handler); \
499 #define WINDOW_ONLY_EVENT EVENT
500 #define TOUCH_EVENT EVENT
501 #include "mozilla/EventNameList.h"
502 #undef TOUCH_EVENT
503 #undef WINDOW_ONLY_EVENT
504 #undef BEFOREUNLOAD_EVENT
505 #undef ERROR_EVENT
506 #undef EVENT
508 nsISupports* GetParentObject() { return nullptr; }
510 Document* GetDocument() { return GetDoc(); }
511 void GetNameOuter(nsAString& aName);
512 void SetNameOuter(const nsAString& aName, mozilla::ErrorResult& aError);
513 mozilla::dom::Location* GetLocation() override;
514 void GetStatusOuter(nsAString& aStatus);
515 void SetStatusOuter(const nsAString& aStatus);
516 void CloseOuter(bool aTrustedCaller);
517 nsresult Close() override;
518 bool GetClosedOuter();
519 bool Closed() override;
520 void StopOuter(mozilla::ErrorResult& aError);
521 // TODO: Convert FocusOuter() to MOZ_CAN_RUN_SCRIPT and get rid of the
522 // kungFuDeathGrip in it.
523 MOZ_CAN_RUN_SCRIPT_BOUNDARY void FocusOuter(
524 mozilla::dom::CallerType aCallerType, bool aFromOtherProcess,
525 uint64_t aActionId);
526 nsresult Focus(mozilla::dom::CallerType aCallerType) override;
527 // TODO: Convert BlurOuter() to MOZ_CAN_RUN_SCRIPT and get rid of the
528 // kungFuDeathGrip in it.
529 MOZ_CAN_RUN_SCRIPT_BOUNDARY void BlurOuter(
530 mozilla::dom::CallerType aCallerType);
531 mozilla::dom::WindowProxyHolder GetFramesOuter();
532 uint32_t Length();
533 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
535 nsresult GetPrompter(nsIPrompt** aPrompt) override;
537 protected:
538 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
539 GetOpenerWindowOuter();
540 // Initializes the mWasOffline member variable
541 void InitWasOffline();
543 public:
544 nsPIDOMWindowOuter* GetSameProcessOpener();
545 already_AddRefed<mozilla::dom::BrowsingContext> GetOpenerBrowsingContext();
546 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetOpener() override;
547 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetParentOuter();
548 already_AddRefed<nsPIDOMWindowOuter> GetInProcessParent() override;
549 nsPIDOMWindowOuter* GetInProcessScriptableParent() override;
550 nsPIDOMWindowOuter* GetInProcessScriptableParentOrNull() override;
551 mozilla::dom::Element* GetFrameElement(nsIPrincipal& aSubjectPrincipal);
552 mozilla::dom::Element* GetFrameElement() override;
553 mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> OpenOuter(
554 const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions,
555 mozilla::ErrorResult& aError);
556 nsresult Open(const nsAString& aUrl, const nsAString& aName,
557 const nsAString& aOptions, nsDocShellLoadState* aLoadState,
558 bool aForceNoOpener,
559 mozilla::dom::BrowsingContext** _retval) override;
560 mozilla::dom::Navigator* GetNavigator() override;
562 protected:
563 bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
564 nsIPrincipal& aSubjectPrincipal,
565 mozilla::ErrorResult& aError);
567 public:
568 void AlertOuter(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
569 mozilla::ErrorResult& aError);
570 bool ConfirmOuter(const nsAString& aMessage, nsIPrincipal& aSubjectPrincipal,
571 mozilla::ErrorResult& aError);
572 void PromptOuter(const nsAString& aMessage, const nsAString& aInitial,
573 nsAString& aReturn, nsIPrincipal& aSubjectPrincipal,
574 mozilla::ErrorResult& aError);
576 MOZ_CAN_RUN_SCRIPT void PrintOuter(mozilla::ErrorResult& aError);
578 enum class IsPreview : bool { No, Yes };
579 enum class IsForWindowDotPrint : bool { No, Yes };
580 MOZ_CAN_RUN_SCRIPT mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
581 Print(nsIPrintSettings*,
582 mozilla::layout::RemotePrintJobChild* aRemotePrintJob,
583 nsIWebProgressListener*, nsIDocShell*, IsPreview, IsForWindowDotPrint,
584 PrintPreviewResolver&&, 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 virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
987 already_AddRefed<nsIRunnable>&& aRunnable) override;
989 virtual nsISerialEventTarget* EventTargetFor(
990 mozilla::TaskCategory aCategory) const override;
992 virtual mozilla::AbstractThread* AbstractMainThreadFor(
993 mozilla::TaskCategory aCategory) override;
995 protected:
996 nsresult ProcessWidgetFullscreenRequest(FullscreenReason aReason,
997 bool aFullscreen);
999 // Indicates whether browser window should be in fullscreen mode and the
1000 // reason, e.g. browser fullscreen mode or DOM fullscreen API, which should
1001 // never be ForForceExitFullscreen. Nothing if browser window should not be in
1002 // fullscreen mode.
1003 mozilla::Maybe<FullscreenReason> mFullscreen;
1005 // Indicates whether new fullscreen request have been made when previous
1006 // fullscreen request is still in-process.
1007 bool mFullscreenHasChangedDuringProcessing : 1;
1009 using FullscreenRequest = struct FullscreenRequest {
1010 FullscreenRequest(FullscreenReason aReason, bool aFullscreen)
1011 : mReason(aReason), mFullscreen(aFullscreen) {
1012 MOZ_ASSERT(
1013 mReason != FullscreenReason::ForForceExitFullscreen || !mFullscreen,
1014 "FullscreenReason::ForForceExitFullscreen can only be used with "
1015 "exiting fullscreen");
1017 FullscreenReason mReason;
1018 bool mFullscreen : 1;
1020 // The current in-process fullscreen request. Nothing if there is no
1021 // in-process request.
1022 mozilla::Maybe<FullscreenRequest> mInProcessFullscreenRequest;
1024 bool mForceFullScreenInWidget : 1;
1025 bool mIsClosed : 1;
1026 bool mInClose : 1;
1027 // mHavePendingClose means we've got a termination function set to
1028 // close us when the JS stops executing or that we have a close
1029 // event posted. If this is set, just ignore window.close() calls.
1030 bool mHavePendingClose : 1;
1032 // Indicates whether scripts are allowed to close this window.
1033 bool mBlockScriptedClosingFlag : 1;
1035 // Window offline status. Checked to see if we need to fire offline event
1036 bool mWasOffline : 1;
1038 // Indicates whether we're in the middle of creating an initializing
1039 // a new inner window object.
1040 bool mCreatingInnerWindow : 1;
1042 // Fast way to tell if this is a chrome window (without having to QI).
1043 bool mIsChrome : 1;
1045 // whether scripts may close the window,
1046 // even if "dom.allow_scripts_to_close_windows" is false.
1047 bool mAllowScriptsToClose : 1;
1049 bool mTopLevelOuterContentWindow : 1;
1051 // Whether we've delayed a print until after load.
1052 bool mDelayedPrintUntilAfterLoad : 1;
1053 // Whether we've delayed a close() operation because there was a pending
1054 // print() operation.
1055 bool mDelayedCloseForPrinting : 1;
1056 // Whether we should delay printing until after load.
1057 bool mShouldDelayPrintUntilAfterLoad : 1;
1059 nsCOMPtr<nsIScriptContext> mContext;
1060 nsCOMPtr<nsIControllers> mControllers;
1062 // For |window.arguments|, via |openDialog|.
1063 nsCOMPtr<nsIArray> mArguments;
1065 RefPtr<nsDOMWindowUtils> mWindowUtils;
1066 nsString mStatus;
1068 RefPtr<mozilla::dom::Storage> mLocalStorage;
1070 nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
1071 nsCOMPtr<nsIPrincipal> mDocumentCookiePrincipal;
1072 nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
1073 nsCOMPtr<nsIPrincipal> mDocumentPartitionedPrincipal;
1075 #ifdef DEBUG
1076 uint32_t mSerial;
1078 bool mSetOpenerWindowCalled;
1079 nsCOMPtr<nsIURI> mLastOpenedURI;
1080 #endif
1082 bool mCleanedUp;
1084 // It's useful when we get matched EnterModalState/LeaveModalState calls, in
1085 // which case the outer window is responsible for unsuspending events on the
1086 // documents. If we don't (for example, if the outer window is closed before
1087 // the LeaveModalState call), then the inner window whose mDoc is in our
1088 // mSuspendedDocs is responsible for unsuspending.
1089 nsTArray<RefPtr<Document>> mSuspendedDocs;
1091 // This is the CC generation the last time we called CanSkip.
1092 uint32_t mCanSkipCCGeneration;
1094 // When non-zero, the document should receive a vrdisplayactivate event
1095 // after loading. The value is the ID of the VRDisplay that content should
1096 // begin presentation on.
1097 uint32_t mAutoActivateVRDisplayID;
1099 static OuterWindowByIdTable* sOuterWindowsById;
1101 // Members in the mChromeFields member should only be used in chrome windows.
1102 // All accesses to this field should be guarded by a check of mIsChrome.
1103 struct ChromeFields {
1104 nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
1105 // A weak pointer to the PresShell that we are doing fullscreen for.
1106 // The pointer being set indicates we've set the IsInFullscreenChange
1107 // flag on this pres shell.
1108 nsWeakPtr mFullscreenPresShell;
1109 } mChromeFields;
1111 friend class nsDOMWindowUtils;
1112 friend class mozilla::dom::BrowsingContext;
1113 friend class mozilla::dom::PostMessageEvent;
1114 friend class mozilla::dom::TimeoutManager;
1115 friend class nsGlobalWindowInner;
1118 inline nsISupports* ToSupports(nsGlobalWindowOuter* p) {
1119 return static_cast<mozilla::dom::EventTarget*>(p);
1122 inline nsISupports* ToCanonicalSupports(nsGlobalWindowOuter* p) {
1123 return static_cast<mozilla::dom::EventTarget*>(p);
1126 inline nsGlobalWindowOuter* nsGlobalWindowOuter::GetInProcessTopInternal() {
1127 nsCOMPtr<nsPIDOMWindowOuter> top = GetInProcessTop();
1128 if (top) {
1129 return nsGlobalWindowOuter::Cast(top);
1131 return nullptr;
1134 inline nsGlobalWindowOuter*
1135 nsGlobalWindowOuter::GetInProcessScriptableTopInternal() {
1136 nsPIDOMWindowOuter* top = GetInProcessScriptableTop();
1137 return nsGlobalWindowOuter::Cast(top);
1140 inline nsIScriptContext* nsGlobalWindowOuter::GetContextInternal() {
1141 return mContext;
1144 inline void nsGlobalWindowOuter::MaybeClearInnerWindow(
1145 nsPIDOMWindowInner* aExpectedInner) {
1146 if (mInnerWindow == aExpectedInner) {
1147 mInnerWindow = nullptr;
1151 #endif /* nsGlobalWindowOuter_h___ */