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"
20 #include "nsWeakReference.h"
21 #include "nsTHashMap.h"
22 #include "nsCycleCollectionParticipant.h"
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"
32 #include "mozilla/FlushType.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"
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"
57 class nsICSSDeclaration
;
58 class nsIDocShellTreeOwner
;
59 class nsIDOMWindowUtils
;
60 class nsIScrollableFrame
;
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
;
74 class nsGlobalWindowObserver
;
75 class nsGlobalWindowInner
;
76 class nsDOMWindowUtils
;
83 class DOMEventTargetHelper
;
85 class ThrottledEventQueue
;
88 struct ChannelPixelLayout
;
91 class CustomElementRegistry
;
97 enum class ImageBitmapFormat
: uint8_t;
100 class MediaQueryList
;
102 class OwningExternalOrWindowProxy
;
104 class PostMessageData
;
105 class PostMessageEvent
;
106 class PrintPreviewResultInfo
;
108 class RequestOrUSVString
;
110 struct SizeToContentConstraints
;
111 class SpeechSynthesis
;
115 enum class VRDisplayEventReason
: uint8_t;
116 class VREventObserver
;
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
,
153 using OuterWindowByIdTable
=
154 nsTHashMap
<nsUint64HashKey
, nsGlobalWindowOuter
*>;
156 using PrintPreviewResolver
=
157 std::function
<void(const mozilla::dom::PrintPreviewResultInfo
&)>;
159 static void AssertIsOnMainThread()
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
) {
186 nsGlobalWindowOuter
* outerWindow
= sOuterWindowsById
->Get(aWindowID
);
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
,
205 nsPIDOMWindowOuter
* GetPrivateParent();
207 // callback for close event
208 void ReallyCloseWindow();
211 NS_DECL_ISUPPORTS_INHERITED
212 NS_IMETHOD_(void) DeleteCycleCollectable() override
;
215 virtual JSObject
* WrapObject(JSContext
* cx
,
216 JS::Handle
<JSObject
*> aGivenProto
) override
{
217 return EnsureInnerWindow() ? GetWrapper() : nullptr;
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
;
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()
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
;
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
)
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()
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
,
352 bool Fullscreen() const;
354 // nsIInterfaceRequestor
355 NS_DECL_NSIINTERFACEREQUESTOR
357 mozilla::dom::Nullable
<mozilla::dom::WindowProxyHolder
> IndexedGetterOuter(
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
388 void EnableDialogs();
389 void DisableDialogs();
390 // Outer windows only.
391 bool AreDialogsEnabled();
393 class MOZ_RAII TemporarilyDisableDialogs
{
395 explicit TemporarilyDisableDialogs(mozilla::dom::BrowsingContext
* aBC
);
396 ~TemporarilyDisableDialogs();
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();
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
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(); \
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(); \
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; \
493 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) { \
494 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
496 elm->SetEventHandler(handler); \
499 #define WINDOW_ONLY_EVENT EVENT
500 #define TOUCH_EVENT EVENT
501 #include "mozilla/EventNameList.h"
503 #undef WINDOW_ONLY_EVENT
504 #undef BEFOREUNLOAD_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
,
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();
533 mozilla::dom::Nullable
<mozilla::dom::WindowProxyHolder
> GetTopOuter();
535 nsresult
GetPrompter(nsIPrompt
** aPrompt
) override
;
538 mozilla::dom::Nullable
<mozilla::dom::WindowProxyHolder
>
539 GetOpenerWindowOuter();
540 // Initializes the mWasOffline member variable
541 void InitWasOffline();
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
,
559 mozilla::dom::BrowsingContext
** _retval
) override
;
560 mozilla::dom::Navigator
* GetNavigator() override
;
563 bool AlertOrConfirm(bool aAlert
, const nsAString
& aMessage
,
564 nsIPrincipal
& aSubjectPrincipal
,
565 mozilla::ErrorResult
& aError
);
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
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
;
649 double GetInnerWidthOuter(mozilla::ErrorResult
& aError
);
652 nsresult
GetInnerWidth(double* aInnerWidth
) override
;
655 double GetInnerHeightOuter(mozilla::ErrorResult
& aError
);
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
;
672 virtual ~nsGlobalWindowOuter();
673 void DropOuterWindowDocs();
675 void ClearControllers();
676 // Outer windows only.
679 inline void MaybeClearInnerWindow(nsPIDOMWindowInner
* aExpectedInner
);
681 // Get the parent, returns null if this is a toplevel window
682 nsPIDOMWindowOuter
* GetInProcessParentInternal();
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
;
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
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
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
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
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
);
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
,
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
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
;
838 already_AddRefed
<nsPIWindowRoot
> GetTopWindowRoot() override
;
841 void NotifyWindowIDDestroyed(const char* aTopic
);
845 void UpdateParentTarget() override
;
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
);
872 * Compute the principal to use for checking against the target principal in a
875 * @param aTargetOrigin The value passed as the targetOrigin argument to the
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
);
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
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
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();
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(
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
);
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
;
996 nsresult
ProcessWidgetFullscreenRequest(FullscreenReason aReason
,
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
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
) {
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;
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).
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
;
1068 RefPtr
<mozilla::dom::Storage
> mLocalStorage
;
1070 nsCOMPtr
<nsIPrincipal
> mDocumentPrincipal
;
1071 nsCOMPtr
<nsIPrincipal
> mDocumentCookiePrincipal
;
1072 nsCOMPtr
<nsIPrincipal
> mDocumentStoragePrincipal
;
1073 nsCOMPtr
<nsIPrincipal
> mDocumentPartitionedPrincipal
;
1078 bool mSetOpenerWindowCalled
;
1079 nsCOMPtr
<nsIURI
> mLastOpenedURI
;
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
;
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();
1129 return nsGlobalWindowOuter::Cast(top
);
1134 inline nsGlobalWindowOuter
*
1135 nsGlobalWindowOuter::GetInProcessScriptableTopInternal() {
1136 nsPIDOMWindowOuter
* top
= GetInProcessScriptableTop();
1137 return nsGlobalWindowOuter::Cast(top
);
1140 inline nsIScriptContext
* nsGlobalWindowOuter::GetContextInternal() {
1144 inline void nsGlobalWindowOuter::MaybeClearInnerWindow(
1145 nsPIDOMWindowInner
* aExpectedInner
) {
1146 if (mInnerWindow
== aExpectedInner
) {
1147 mInnerWindow
= nullptr;
1151 #endif /* nsGlobalWindowOuter_h___ */