Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsPIDOMWindow_h__
8 : #define nsPIDOMWindow_h__
9 :
10 : #include "nsIDOMWindow.h"
11 : #include "mozIDOMWindow.h"
12 :
13 : #include "nsCOMPtr.h"
14 : #include "nsTArray.h"
15 : #include "mozilla/dom/EventTarget.h"
16 : #include "mozilla/TaskCategory.h"
17 : #include "js/TypeDecls.h"
18 : #include "nsRefPtrHashtable.h"
19 :
20 : // Only fired for inner windows.
21 : #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed"
22 : #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen"
23 : #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
24 :
25 : class nsGlobalWindow;
26 : class nsIArray;
27 : class nsIContent;
28 : class nsICSSDeclaration;
29 : class nsIDocShell;
30 : class nsIDocShellLoadInfo;
31 : class nsIDocument;
32 : class nsIIdleObserver;
33 : class nsIPrincipal;
34 : class nsIScriptTimeoutHandler;
35 : class nsISerialEventTarget;
36 : class nsIURI;
37 : class nsPIDOMWindowInner;
38 : class nsPIDOMWindowOuter;
39 : class nsPIWindowRoot;
40 : class nsXBLPrototypeHandler;
41 :
42 : typedef uint32_t SuspendTypes;
43 :
44 : namespace mozilla {
45 : class ThrottledEventQueue;
46 : namespace dom {
47 : class AudioContext;
48 : class DocGroup;
49 : class TabGroup;
50 : class Element;
51 : class Performance;
52 : class ServiceWorkerRegistration;
53 : class Timeout;
54 : class TimeoutManager;
55 : class CustomElementRegistry;
56 : enum class CallerType : uint32_t;
57 : } // namespace dom
58 : } // namespace mozilla
59 :
60 : // Popup control state enum. The values in this enum must go from most
61 : // permissive to least permissive so that it's safe to push state in
62 : // all situations. Pushing popup state onto the stack never makes the
63 : // current popup state less permissive (see
64 : // nsGlobalWindow::PushPopupControlState()).
65 : enum PopupControlState {
66 : openAllowed = 0, // open that window without worries
67 : openControlled, // it's a popup, but allow it
68 : openAbused, // it's a popup. disallow it, but allow domain override.
69 : openOverridden // disallow window open
70 : };
71 :
72 : enum UIStateChangeType
73 : {
74 : UIStateChangeType_NoChange,
75 : UIStateChangeType_Set,
76 : UIStateChangeType_Clear,
77 : UIStateChangeType_Invalid // used for serialization only
78 : };
79 :
80 : enum class FullscreenReason
81 : {
82 : // Toggling the fullscreen mode requires trusted context.
83 : ForFullscreenMode,
84 : // Fullscreen API is the API provided to untrusted content.
85 : ForFullscreenAPI,
86 : // This reason can only be used with exiting fullscreen.
87 : // It is otherwise identical to eForFullscreenAPI except it would
88 : // suppress the fullscreen transition.
89 : ForForceExitFullscreen
90 : };
91 :
92 : namespace mozilla {
93 : namespace dom {
94 :
95 : class Location;
96 :
97 : // The states in this enum represent the different possible outcomes which the
98 : // window could be experiencing of loading a document with the
99 : // Large-Allocation header. The NONE case represents the case where no
100 : // Large-Allocation header was set.
101 : enum class LargeAllocStatus : uint8_t
102 : {
103 : // These are the OK states, NONE means that no large allocation status message
104 : // should be printed, while SUCCESS means that the success message should be
105 : // printed.
106 : NONE,
107 : SUCCESS,
108 :
109 : // These are the ERROR states. If a window is in one of these states, then the
110 : // next document loaded in that window should have an error message reported
111 : // to it.
112 : NON_GET,
113 : NON_E10S,
114 : NOT_ONLY_TOPLEVEL_IN_TABGROUP,
115 : NON_WIN32
116 : };
117 : } // namespace dom
118 : } // namespace mozilla
119 :
120 : // nsPIDOMWindowInner and nsPIDOMWindowOuter are identical in all respects
121 : // except for the type name. They *must* remain identical so that we can
122 : // reinterpret_cast between them.
123 : template<class T>
124 : class nsPIDOMWindow : public T
125 : {
126 : public:
127 : nsPIDOMWindowInner* AsInner();
128 : const nsPIDOMWindowInner* AsInner() const;
129 : nsPIDOMWindowOuter* AsOuter();
130 : const nsPIDOMWindowOuter* AsOuter() const;
131 :
132 : virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
133 : virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0;
134 : // Outer windows only.
135 : virtual void ActivateOrDeactivate(bool aActivate) = 0;
136 :
137 : // this is called GetTopWindowRoot to avoid conflicts with nsIDOMWindow::GetWindowRoot
138 : /**
139 : * |top| gets the root of the window hierarchy.
140 : *
141 : * This function does not cross chrome-content boundaries, so if this
142 : * window's parent is of a different type, |top| will return this window.
143 : *
144 : * When script reads the top property, we run GetScriptableTop, which
145 : * will not cross an <iframe mozbrowser> boundary.
146 : *
147 : * In contrast, C++ calls to GetTop are forwarded to GetRealTop, which
148 : * ignores <iframe mozbrowser> boundaries.
149 : */
150 :
151 : virtual already_AddRefed<nsPIDOMWindowOuter> GetTop() = 0; // Outer only
152 : virtual already_AddRefed<nsPIDOMWindowOuter> GetParent() = 0;
153 : virtual nsPIDOMWindowOuter* GetScriptableTop() = 0;
154 : virtual nsPIDOMWindowOuter* GetScriptableParent() = 0;
155 : virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0;
156 :
157 3 : bool IsRootOuterWindow()
158 : {
159 3 : MOZ_ASSERT(IsOuterWindow());
160 3 : return mIsRootOuterWindow;
161 : }
162 :
163 : /**
164 : * Behavies identically to GetScriptableParent extept that it returns null
165 : * if GetScriptableParent would return this window.
166 : */
167 : virtual nsPIDOMWindowOuter* GetScriptableParentOrNull() = 0;
168 :
169 : // Inner windows only.
170 : virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0;
171 : virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0;
172 :
173 : virtual bool IsTopLevelWindowActive() = 0;
174 :
175 : // Outer windows only.
176 4 : virtual void SetActive(bool aActive)
177 : {
178 4 : MOZ_ASSERT(IsOuterWindow());
179 4 : mIsActive = aActive;
180 4 : }
181 :
182 : virtual void SetIsBackground(bool aIsBackground) = 0;
183 :
184 45 : mozilla::dom::EventTarget* GetChromeEventHandler() const
185 : {
186 45 : return mChromeEventHandler;
187 : }
188 :
189 : // Outer windows only.
190 : virtual void SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler) = 0;
191 :
192 246 : mozilla::dom::EventTarget* GetParentTarget()
193 : {
194 246 : if (!mParentTarget) {
195 12 : UpdateParentTarget();
196 : }
197 246 : return mParentTarget;
198 : }
199 :
200 0 : virtual void MaybeUpdateTouchState() {}
201 :
202 1154 : nsIDocument* GetExtantDoc() const
203 : {
204 1154 : return mDoc;
205 : }
206 : nsIURI* GetDocumentURI() const;
207 : nsIURI* GetDocBaseURI() const;
208 :
209 29 : nsIDocument* GetDoc()
210 : {
211 29 : if (!mDoc) {
212 9 : MaybeCreateDoc();
213 : }
214 29 : return mDoc;
215 : }
216 :
217 : protected:
218 : // Lazily instantiate an about:blank document if necessary, and if
219 : // we have what it takes to do so.
220 : void MaybeCreateDoc();
221 :
222 : public:
223 : // Check whether a document is currently loading
224 : inline bool IsLoading() const;
225 : inline bool IsHandlingResizeEvent() const;
226 :
227 : // Set the window up with an about:blank document with the current subject
228 : // principal.
229 : // Outer windows only.
230 : virtual void SetInitialPrincipalToSubject() = 0;
231 :
232 : virtual PopupControlState PushPopupControlState(PopupControlState aState,
233 : bool aForce) const = 0;
234 : virtual void PopPopupControlState(PopupControlState state) const = 0;
235 : virtual PopupControlState GetPopupControlState() const = 0;
236 :
237 : // Returns an object containing the window's state. This also suspends
238 : // all running timeouts in the window.
239 : virtual already_AddRefed<nsISupports> SaveWindowState() = 0;
240 :
241 : // Restore the window state from aState.
242 : virtual nsresult RestoreWindowState(nsISupports *aState) = 0;
243 :
244 : // Determine if the window is suspended or frozen. Outer windows
245 : // will forward this call to the inner window for convenience. If
246 : // there is no inner window then the outer window is considered
247 : // suspended and frozen by default.
248 : virtual bool IsSuspended() const = 0;
249 : virtual bool IsFrozen() const = 0;
250 :
251 : // Fire any DOM notification events related to things that happened while
252 : // the window was frozen.
253 : virtual nsresult FireDelayedDOMEvents() = 0;
254 :
255 2992 : nsPIDOMWindowOuter* GetOuterWindow()
256 : {
257 2992 : return mIsInnerWindow ? mOuterWindow.get() : AsOuter();
258 : }
259 :
260 15209 : bool IsInnerWindow() const
261 : {
262 15209 : return mIsInnerWindow;
263 : }
264 :
265 6156 : bool IsOuterWindow() const
266 : {
267 6156 : return !IsInnerWindow();
268 : }
269 :
270 : // Outer windows only.
271 : virtual bool WouldReuseInnerWindow(nsIDocument* aNewDocument) = 0;
272 :
273 : /**
274 : * Get the docshell in this window.
275 : */
276 : nsIDocShell *GetDocShell() const;
277 :
278 : /**
279 : * Set the docshell in the window. Must not be called with a null docshell
280 : * (use DetachFromDocShell for that).
281 : */
282 : virtual void SetDocShell(nsIDocShell *aDocShell) = 0;
283 :
284 : /**
285 : * Detach an outer window from its docshell.
286 : */
287 : virtual void DetachFromDocShell() = 0;
288 :
289 : /**
290 : * Set a new document in the window. Calling this method will in
291 : * most cases create a new inner window. If this method is called on
292 : * an inner window the call will be forewarded to the outer window,
293 : * if the inner window is not the current inner window an
294 : * NS_ERROR_NOT_AVAILABLE error code will be returned. This may be
295 : * called with a pointer to the current document, in that case the
296 : * document remains unchanged, but a new inner window will be
297 : * created.
298 : *
299 : * aDocument must not be null.
300 : */
301 : virtual nsresult SetNewDocument(nsIDocument *aDocument,
302 : nsISupports *aState,
303 : bool aForceReuseInnerWindow) = 0;
304 :
305 : /**
306 : * Set the opener window. aOriginalOpener is true if and only if this is the
307 : * original opener for the window. That is, it can only be true at most once
308 : * during the life cycle of a window, and then only the first time
309 : * SetOpenerWindow is called. It might never be true, of course, if the
310 : * window does not have an opener when it's created.
311 : */
312 : virtual void SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
313 : bool aOriginalOpener) = 0;
314 :
315 : /**
316 : * Ensure the size and position of this window are up-to-date by doing
317 : * a layout flush in the parent (which will in turn, do a layout flush
318 : * in its parent, etc.).
319 : */
320 : virtual void EnsureSizeAndPositionUpToDate() = 0;
321 :
322 : /**
323 : * Callback for notifying a window about a modal dialog being
324 : * opened/closed with the window as a parent.
325 : */
326 : virtual void EnterModalState() = 0;
327 : virtual void LeaveModalState() = 0;
328 :
329 : // Outer windows only.
330 : virtual bool CanClose() = 0;
331 : virtual void ForceClose() = 0;
332 :
333 7 : bool IsModalContentWindow() const
334 : {
335 7 : return mIsModalContentWindow;
336 : }
337 :
338 : /**
339 : * Call this to indicate that some node (this window, its document,
340 : * or content in that document) has a paint event listener.
341 : */
342 2 : void SetHasPaintEventListeners()
343 : {
344 2 : mMayHavePaintEventListener = true;
345 2 : }
346 :
347 : /**
348 : * Call this to check whether some node (this window, its document,
349 : * or content in that document) has a paint event listener.
350 : */
351 27 : bool HasPaintEventListeners()
352 : {
353 27 : return mMayHavePaintEventListener;
354 : }
355 :
356 : /**
357 : * Call this to indicate that some node (this window, its document,
358 : * or content in that document) has a touch event listener.
359 : */
360 3 : void SetHasTouchEventListeners()
361 : {
362 3 : if (!mMayHaveTouchEventListener) {
363 1 : mMayHaveTouchEventListener = true;
364 1 : MaybeUpdateTouchState();
365 : }
366 3 : }
367 :
368 : /**
369 : * Call this to indicate that some node (this window, its document,
370 : * or content in that document) has a selectionchange event listener.
371 : */
372 0 : void SetHasSelectionChangeEventListeners()
373 : {
374 0 : mMayHaveSelectionChangeEventListener = true;
375 0 : }
376 :
377 : /**
378 : * Call this to check whether some node (this window, its document,
379 : * or content in that document) has a selectionchange event listener.
380 : */
381 17 : bool HasSelectionChangeEventListeners()
382 : {
383 17 : return mMayHaveSelectionChangeEventListener;
384 : }
385 :
386 : /**
387 : * Moves the top-level window into fullscreen mode if aIsFullScreen is true,
388 : * otherwise exits fullscreen.
389 : *
390 : * Outer windows only.
391 : */
392 : virtual nsresult SetFullscreenInternal(
393 : FullscreenReason aReason, bool aIsFullscreen) = 0;
394 :
395 : /**
396 : * This function should be called when the fullscreen state is flipped.
397 : * If no widget is involved the fullscreen change, this method is called
398 : * by SetFullscreenInternal, otherwise, it is called when the widget
399 : * finishes its change to or from fullscreen.
400 : *
401 : * @param aIsFullscreen indicates whether the widget is in fullscreen.
402 : *
403 : * Outer windows only.
404 : */
405 : virtual void FinishFullscreenChange(bool aIsFullscreen) = 0;
406 :
407 : virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
408 : virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
409 : JS::Handle<JSObject*> aHandler) = 0;
410 :
411 : /*
412 : * Get and set the currently focused element within the document. If
413 : * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
414 : * document focus event is needed.
415 : *
416 : * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER
417 : * INSTEAD.
418 : */
419 : nsIContent* GetFocusedNode() const;
420 : virtual void SetFocusedNode(nsIContent* aNode,
421 : uint32_t aFocusMethod = 0,
422 : bool aNeedsFocus = false) = 0;
423 :
424 : /**
425 : * Retrieves the method that was used to focus the current node.
426 : */
427 : virtual uint32_t GetFocusMethod() = 0;
428 :
429 : /*
430 : * Tells the window that it now has focus or has lost focus, based on the
431 : * state of aFocus. If this method returns true, then the document loaded
432 : * in the window has never received a focus event and expects to receive
433 : * one. If false is returned, the document has received a focus event before
434 : * and should only receive one if the window is being focused.
435 : *
436 : * aFocusMethod may be set to one of the focus method constants in
437 : * nsIFocusManager to indicate how focus was set.
438 : */
439 : virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0;
440 :
441 : /**
442 : * Indicates that the window may now accept a document focus event. This
443 : * should be called once a document has been loaded into the window.
444 : */
445 : virtual void SetReadyForFocus() = 0;
446 :
447 : /**
448 : * Whether the focused content within the window should show a focus ring.
449 : */
450 : virtual bool ShouldShowFocusRing() = 0;
451 :
452 : /**
453 : * Set the keyboard indicator state for accelerators and focus rings.
454 : */
455 : virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
456 : UIStateChangeType aShowFocusRings) = 0;
457 :
458 : /**
459 : * Indicates that the page in the window has been hidden. This is used to
460 : * reset the focus state.
461 : */
462 : virtual void PageHidden() = 0;
463 :
464 : /**
465 : * Instructs this window to asynchronously dispatch a hashchange event. This
466 : * method must be called on an inner window.
467 : */
468 : virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI,
469 : nsIURI *aNewURI) = 0;
470 :
471 : /**
472 : * Instructs this window to synchronously dispatch a popState event.
473 : */
474 : virtual nsresult DispatchSyncPopState() = 0;
475 :
476 : /**
477 : * Tell this window that it should listen for sensor changes of the given
478 : * type.
479 : *
480 : * Inner windows only.
481 : */
482 : virtual void EnableDeviceSensor(uint32_t aType) = 0;
483 :
484 : /**
485 : * Tell this window that it should remove itself from sensor change
486 : * notifications.
487 : *
488 : * Inner windows only.
489 : */
490 : virtual void DisableDeviceSensor(uint32_t aType) = 0;
491 :
492 : #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
493 : virtual void EnableOrientationChangeListener() = 0;
494 : virtual void DisableOrientationChangeListener() = 0;
495 : #endif
496 :
497 : virtual void EnableTimeChangeNotifications() = 0;
498 : virtual void DisableTimeChangeNotifications() = 0;
499 :
500 : #ifdef MOZ_B2G
501 : /**
502 : * Tell the window that it should start to listen to the network event of the
503 : * given aType.
504 : *
505 : * Inner windows only.
506 : */
507 : virtual void EnableNetworkEvent(mozilla::EventMessage aEventMessage) = 0;
508 :
509 : /**
510 : * Tell the window that it should stop to listen to the network event of the
511 : * given aType.
512 : *
513 : * Inner windows only.
514 : */
515 : virtual void DisableNetworkEvent(mozilla::EventMessage aEventMessage) = 0;
516 : #endif // MOZ_B2G
517 :
518 : /**
519 : * Tell this window that there is an observer for gamepad input
520 : *
521 : * Inner windows only.
522 : */
523 : virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0;
524 :
525 : /**
526 : * Set a arguments for this window. This will be set on the window
527 : * right away (if there's an existing document) and it will also be
528 : * installed on the window when the next document is loaded.
529 : *
530 : * This function serves double-duty for passing both |arguments| and
531 : * |dialogArguments| back from nsWindowWatcher to nsGlobalWindow. For the
532 : * latter, the array is an array of length 0 whose only element is a
533 : * DialogArgumentsHolder representing the JS value passed to showModalDialog.
534 : *
535 : * Outer windows only.
536 : */
537 : virtual nsresult SetArguments(nsIArray *aArguments) = 0;
538 :
539 : /**
540 : * NOTE! This function *will* be called on multiple threads so the
541 : * implementation must not do any AddRef/Release or other actions that will
542 : * mutate internal state.
543 : */
544 : virtual uint32_t GetSerial() = 0;
545 :
546 : /**
547 : * Return the window id of this window
548 : */
549 256 : uint64_t WindowID() const { return mWindowID; }
550 :
551 : /**
552 : * Dispatch a custom event with name aEventName targeted at this window.
553 : * Returns whether the default action should be performed.
554 : *
555 : * Outer windows only.
556 : */
557 : virtual bool DispatchCustomEvent(const nsAString& aEventName) = 0;
558 :
559 : /**
560 : * Like nsIDOMWindow::Open, except that we don't navigate to the given URL.
561 : *
562 : * Outer windows only.
563 : */
564 : virtual nsresult
565 : OpenNoNavigate(const nsAString& aUrl, const nsAString& aName,
566 : const nsAString& aOptions, nsPIDOMWindowOuter **_retval) = 0;
567 :
568 : /**
569 : * Fire a popup blocked event on the document.
570 : */
571 : virtual void
572 : FirePopupBlockedEvent(nsIDocument* aDoc,
573 : nsIURI* aPopupURI,
574 : const nsAString& aPopupWindowName,
575 : const nsAString& aPopupWindowFeatures) = 0;
576 :
577 : // WebIDL-ish APIs
578 0 : void MarkUncollectableForCCGeneration(uint32_t aGeneration)
579 : {
580 0 : mMarkedCCGeneration = aGeneration;
581 0 : }
582 :
583 0 : uint32_t GetMarkedCCGeneration()
584 : {
585 0 : return mMarkedCCGeneration;
586 : }
587 :
588 : virtual nsIDOMScreen* GetScreen() = 0;
589 : virtual nsIDOMNavigator* GetNavigator() = 0;
590 : virtual mozilla::dom::Location* GetLocation() = 0;
591 : virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0;
592 : virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
593 : virtual already_AddRefed<nsISelection> GetSelection() = 0;
594 : virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
595 : virtual already_AddRefed<nsIDOMWindowCollection> GetFrames() = 0;
596 : // aLoadInfo will be passed on through to the windowwatcher.
597 : // aForceNoOpener will act just like a "noopener" feature in aOptions except
598 : // will not affect any other window features.
599 : virtual nsresult Open(const nsAString& aUrl, const nsAString& aName,
600 : const nsAString& aOptions,
601 : nsIDocShellLoadInfo* aLoadInfo,
602 : bool aForceNoOpener,
603 : nsPIDOMWindowOuter **_retval) = 0;
604 : virtual nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName,
605 : const nsAString& aOptions,
606 : nsISupports* aExtraArgument,
607 : nsPIDOMWindowOuter** _retval) = 0;
608 :
609 : virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
610 : virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
611 : virtual already_AddRefed<nsICSSDeclaration>
612 : GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
613 : mozilla::ErrorResult& aError) = 0;
614 : virtual already_AddRefed<nsIDOMElement> GetFrameElement() = 0;
615 : virtual already_AddRefed<nsIDOMOfflineResourceList> GetApplicationCache() = 0;
616 : virtual bool Closed() = 0;
617 : virtual bool GetFullScreen() = 0;
618 : virtual nsresult SetFullScreen(bool aFullScreen) = 0;
619 :
620 : virtual nsresult Focus() = 0;
621 : virtual nsresult Close() = 0;
622 :
623 : virtual nsresult MoveBy(int32_t aXDif, int32_t aYDif) = 0;
624 : virtual nsresult UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason) = 0;
625 :
626 : mozilla::dom::TabGroup* TabGroup();
627 :
628 : mozilla::dom::DocGroup* GetDocGroup() const;
629 :
630 : virtual nsISerialEventTarget*
631 : EventTargetFor(mozilla::TaskCategory aCategory) const = 0;
632 :
633 : protected:
634 : // The nsPIDOMWindow constructor. The aOuterWindow argument should
635 : // be null if and only if the created window itself is an outer
636 : // window. In all other cases aOuterWindow should be the outer
637 : // window for the inner window that is being created.
638 : explicit nsPIDOMWindow<T>(nsPIDOMWindowOuter *aOuterWindow);
639 :
640 : ~nsPIDOMWindow<T>();
641 :
642 1 : void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler) {
643 1 : mChromeEventHandler = aChromeEventHandler;
644 : // mParentTarget will be set when the next event is dispatched.
645 1 : mParentTarget = nullptr;
646 1 : }
647 :
648 : virtual void UpdateParentTarget() = 0;
649 :
650 : // These two variables are special in that they're set to the same
651 : // value on both the outer window and the current inner window. Make
652 : // sure you keep them in sync!
653 : nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong
654 : nsCOMPtr<nsIDocument> mDoc; // strong
655 : // Cache the URI when mDoc is cleared.
656 : nsCOMPtr<nsIURI> mDocumentURI; // strong
657 : nsCOMPtr<nsIURI> mDocBaseURI; // strong
658 :
659 : nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong
660 :
661 : // These members are only used on outer windows.
662 : nsCOMPtr<mozilla::dom::Element> mFrameElement;
663 : // This reference is used by the subclass nsGlobalWindow, and cleared in it's
664 : // DetachFromDocShell() method. This method is called by nsDocShell::Destroy(),
665 : // which is called before the nsDocShell is destroyed.
666 : nsIDocShell* MOZ_NON_OWNING_REF mDocShell; // Weak Reference
667 :
668 : // mPerformance is only used on inner windows.
669 : RefPtr<mozilla::dom::Performance> mPerformance;
670 : // mTimeoutManager is only useed on inner windows.
671 : mozilla::UniquePtr<mozilla::dom::TimeoutManager> mTimeoutManager;
672 :
673 : typedef nsRefPtrHashtable<nsStringHashKey,
674 : mozilla::dom::ServiceWorkerRegistration>
675 : ServiceWorkerRegistrationTable;
676 : ServiceWorkerRegistrationTable mServiceWorkerRegistrationTable;
677 :
678 : uint32_t mModalStateDepth;
679 :
680 : // These variables are only used on inner windows.
681 : uint32_t mMutationBits;
682 :
683 : bool mIsDocumentLoaded;
684 : bool mIsHandlingResizeEvent;
685 : bool mIsInnerWindow;
686 : bool mMayHavePaintEventListener;
687 : bool mMayHaveTouchEventListener;
688 : bool mMayHaveSelectionChangeEventListener;
689 : bool mMayHaveMouseEnterLeaveEventListener;
690 : bool mMayHavePointerEnterLeaveEventListener;
691 :
692 : // Used to detect whether we have called FreeInnerObjects() (e.g. to ensure
693 : // that a call to ResumeTimeouts() after FreeInnerObjects() does nothing).
694 : // This member is only used by inner windows.
695 : bool mInnerObjectsFreed;
696 :
697 :
698 : // This variable is used on both inner and outer windows (and they
699 : // should match).
700 : bool mIsModalContentWindow;
701 :
702 : // Tracks activation state that's used for :-moz-window-inactive.
703 : // Only used on outer windows.
704 : bool mIsActive;
705 :
706 : // Tracks whether our docshell is active. If it is, mIsBackground
707 : // is false. Too bad we have so many different concepts of
708 : // "active". Only used on outer windows.
709 : bool mIsBackground;
710 :
711 : /**
712 : * The suspended types can be "disposable" or "permanent". This varable only
713 : * stores the value about permanent suspend.
714 : * - disposable
715 : * To pause all playing media in that window, but doesn't affect the media
716 : * which starts after that.
717 : *
718 : * - permanent
719 : * To pause all media in that window, and also affect the media which starts
720 : * after that.
721 : */
722 : SuspendTypes mMediaSuspend;
723 :
724 : bool mAudioMuted;
725 : float mAudioVolume;
726 :
727 : bool mAudioCaptured;
728 :
729 : // current desktop mode flag.
730 : bool mDesktopModeViewport;
731 :
732 : bool mIsRootOuterWindow;
733 :
734 : // And these are the references between inner and outer windows.
735 : nsPIDOMWindowInner* MOZ_NON_OWNING_REF mInnerWindow;
736 : nsCOMPtr<nsPIDOMWindowOuter> mOuterWindow;
737 :
738 : // the element within the document that is currently focused when this
739 : // window is active
740 : nsCOMPtr<nsIContent> mFocusedNode;
741 :
742 : // The AudioContexts created for the current document, if any.
743 : nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak
744 :
745 : // This is present both on outer and inner windows.
746 : RefPtr<mozilla::dom::TabGroup> mTabGroup;
747 :
748 : // A unique (as long as our 64-bit counter doesn't roll over) id for
749 : // this window.
750 : uint64_t mWindowID;
751 :
752 : // This is only used by the inner window. Set to true once we've sent
753 : // the (chrome|content)-document-global-created notification.
754 : bool mHasNotifiedGlobalCreated;
755 :
756 : uint32_t mMarkedCCGeneration;
757 :
758 : // Let the service workers plumbing know that some feature are enabled while
759 : // testing.
760 : bool mServiceWorkersTestingEnabled;
761 :
762 : mozilla::dom::LargeAllocStatus mLargeAllocStatus; // Outer window only
763 :
764 : // mTopInnerWindow is only used on inner windows for tab-wise check by timeout
765 : // throttling. It could be null.
766 : nsCOMPtr<nsPIDOMWindowInner> mTopInnerWindow;
767 :
768 : // The evidence that we have tried to cache mTopInnerWindow only once from
769 : // SetNewDocument(). Note: We need this extra flag because mTopInnerWindow
770 : // could be null and we don't want it to be set multiple times.
771 : bool mHasTriedToCacheTopInnerWindow;
772 :
773 : // The number of active IndexedDB databases. Inner window only.
774 : uint32_t mNumOfIndexedDBDatabases;
775 : };
776 :
777 : #define NS_PIDOMWINDOWINNER_IID \
778 : { 0x775dabc9, 0x8f43, 0x4277, \
779 : { 0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb } }
780 :
781 : #define NS_PIDOMWINDOWOUTER_IID \
782 : { 0x769693d4, 0xb009, 0x4fe2, \
783 : { 0xaf, 0x18, 0x7d, 0xc8, 0xdf, 0x74, 0x96, 0xdf } }
784 :
785 : // NB: It's very very important that these two classes have identical vtables
786 : // and memory layout!
787 : class nsPIDOMWindowInner : public nsPIDOMWindow<mozIDOMWindow>
788 : {
789 : friend nsGlobalWindow;
790 :
791 : public:
792 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOWINNER_IID)
793 :
794 3 : static nsPIDOMWindowInner* From(mozIDOMWindow* aFrom) {
795 3 : return static_cast<nsPIDOMWindowInner*>(aFrom);
796 : }
797 :
798 : // Returns true if this object has an outer window and it is the current inner
799 : // window of that outer.
800 : inline bool IsCurrentInnerWindow() const;
801 :
802 : // Returns true if the document of this window is the active document. This
803 : // is not identical to IsCurrentInnerWindow() because document.open() will
804 : // keep the same document active but create a new window.
805 : inline bool HasActiveDocument();
806 :
807 : bool AddAudioContext(mozilla::dom::AudioContext* aAudioContext);
808 : void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext);
809 : void MuteAudioContexts();
810 : void UnmuteAudioContexts();
811 :
812 : bool GetAudioCaptured() const;
813 : nsresult SetAudioCapture(bool aCapture);
814 :
815 : already_AddRefed<mozilla::dom::ServiceWorkerRegistration>
816 : GetServiceWorkerRegistration(const nsAString& aScope);
817 : void InvalidateServiceWorkerRegistration(const nsAString& aScope);
818 :
819 : mozilla::dom::Performance* GetPerformance();
820 :
821 757 : bool HasMutationListeners(uint32_t aMutationEventType) const
822 : {
823 757 : if (!mOuterWindow) {
824 0 : NS_ERROR("HasMutationListeners() called on orphan inner window!");
825 :
826 0 : return false;
827 : }
828 :
829 757 : return (mMutationBits & aMutationEventType) != 0;
830 : }
831 :
832 0 : void SetMutationListeners(uint32_t aType)
833 : {
834 0 : if (!mOuterWindow) {
835 0 : NS_ERROR("HasMutationListeners() called on orphan inner window!");
836 :
837 0 : return;
838 : }
839 :
840 0 : mMutationBits |= aType;
841 : }
842 :
843 : /**
844 : * Call this to check whether some node (this window, its document,
845 : * or content in that document) has a mouseenter/leave event listener.
846 : */
847 2 : bool HasMouseEnterLeaveEventListeners()
848 : {
849 2 : return mMayHaveMouseEnterLeaveEventListener;
850 : }
851 :
852 : /**
853 : * Call this to indicate that some node (this window, its document,
854 : * or content in that document) has a mouseenter/leave event listener.
855 : */
856 0 : void SetHasMouseEnterLeaveEventListeners()
857 : {
858 0 : mMayHaveMouseEnterLeaveEventListener = true;
859 0 : }
860 :
861 : /**
862 : * Call this to check whether some node (this window, its document,
863 : * or content in that document) has a Pointerenter/leave event listener.
864 : */
865 2 : bool HasPointerEnterLeaveEventListeners()
866 : {
867 2 : return mMayHavePointerEnterLeaveEventListener;
868 : }
869 :
870 : /**
871 : * Call this to indicate that some node (this window, its document,
872 : * or content in that document) has a Pointerenter/leave event listener.
873 : */
874 0 : void SetHasPointerEnterLeaveEventListeners()
875 : {
876 0 : mMayHavePointerEnterLeaveEventListener = true;
877 0 : }
878 :
879 : /**
880 : * Check whether this has had inner objects freed.
881 : */
882 5 : bool InnerObjectsFreed() const
883 : {
884 5 : return mInnerObjectsFreed;
885 : }
886 :
887 : /**
888 : * Check whether this window is a secure context.
889 : */
890 : bool IsSecureContext() const;
891 : bool IsSecureContextIfOpenerIgnored() const;
892 :
893 : // Calling suspend should prevent any asynchronous tasks from
894 : // executing javascript for this window. This means setTimeout,
895 : // requestAnimationFrame, and events should not be fired. Suspending
896 : // a window also suspends its children and workers. Workers may
897 : // continue to perform computations in the background. A window
898 : // can have Suspend() called multiple times and will only resume after
899 : // a matching number of Resume() calls.
900 : void Suspend();
901 : void Resume();
902 :
903 : // Calling Freeze() on a window will automatically Suspend() it. In
904 : // addition, the window and its children are further treated as no longer
905 : // suitable for interaction with the user. For example, it may be marked
906 : // non-visible, cannot be focused, etc. All worker threads are also frozen
907 : // bringing them to a complete stop. A window can have Freeze() called
908 : // multiple times and will only thaw after a matching number of Thaw()
909 : // calls.
910 : void Freeze();
911 : void Thaw();
912 :
913 : // Apply the parent window's suspend, freeze, and modal state to the current
914 : // window.
915 : void SyncStateFromParentWindow();
916 :
917 : bool IsPlayingAudio();
918 :
919 : bool IsDocumentLoaded() const;
920 :
921 : mozilla::dom::TimeoutManager& TimeoutManager();
922 :
923 : bool IsRunningTimeout();
924 :
925 : // To cache top inner-window if available after constructed for tab-wised
926 : // indexedDB counters.
927 : void TryToCacheTopInnerWindow();
928 :
929 : // Increase/Decrease the number of active IndexedDB transactions/databases for
930 : // the decision making of TabGroup scheduling and timeout-throttling.
931 : void UpdateActiveIndexedDBTransactionCount(int32_t aDelta);
932 : void UpdateActiveIndexedDBDatabaseCount(int32_t aDelta);
933 :
934 : // Return true if there is any active IndexedDB databases which could block
935 : // timeout-throttling.
936 : bool HasActiveIndexedDBDatabases();
937 :
938 : protected:
939 : void CreatePerformanceObjectIfNeeded();
940 : };
941 :
942 : NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
943 :
944 : // NB: It's very very important that these two classes have identical vtables
945 : // and memory layout!
946 : class nsPIDOMWindowOuter : public nsPIDOMWindow<mozIDOMWindowProxy>
947 : {
948 : protected:
949 : void RefreshMediaElementsVolume();
950 : void RefreshMediaElementsSuspend(SuspendTypes aSuspend);
951 : bool IsDisposableSuspend(SuspendTypes aSuspend) const;
952 : void MaybeNotifyMediaResumedFromBlock(SuspendTypes aSuspend);
953 :
954 : public:
955 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOWOUTER_IID)
956 :
957 74 : static nsPIDOMWindowOuter* From(mozIDOMWindowProxy* aFrom) {
958 74 : return static_cast<nsPIDOMWindowOuter*>(aFrom);
959 : }
960 :
961 : // Given an inner window, return its outer if the inner is the current inner.
962 : // Otherwise (argument null or not an inner or not current) return null.
963 : static nsPIDOMWindowOuter* GetFromCurrentInner(nsPIDOMWindowInner* aInner);
964 :
965 674 : nsPIDOMWindowInner* GetCurrentInnerWindow() const
966 : {
967 674 : return mInnerWindow;
968 : }
969 :
970 2 : nsPIDOMWindowInner* EnsureInnerWindow()
971 : {
972 2 : MOZ_ASSERT(IsOuterWindow());
973 : // GetDoc forces inner window creation if there isn't one already
974 2 : GetDoc();
975 2 : return GetCurrentInnerWindow();
976 : }
977 :
978 : /**
979 : * Set initial keyboard indicator state for accelerators and focus rings.
980 : */
981 : void SetInitialKeyboardIndicators(UIStateChangeType aShowAccelerators,
982 : UIStateChangeType aShowFocusRings);
983 :
984 : // Internal getter/setter for the frame element, this version of the
985 : // getter crosses chrome boundaries whereas the public scriptable
986 : // one doesn't for security reasons.
987 : mozilla::dom::Element* GetFrameElementInternal() const;
988 : void SetFrameElementInternal(mozilla::dom::Element* aFrameElement);
989 :
990 3 : bool IsActive()
991 : {
992 3 : return mIsActive;
993 : }
994 :
995 0 : void SetDesktopModeViewport(bool aDesktopModeViewport)
996 : {
997 0 : mDesktopModeViewport = aDesktopModeViewport;
998 0 : }
999 1 : bool IsDesktopModeViewport() const
1000 : {
1001 1 : return mDesktopModeViewport;
1002 : }
1003 171 : bool IsBackground()
1004 : {
1005 171 : return mIsBackground;
1006 : }
1007 :
1008 : // Audio API
1009 : SuspendTypes GetMediaSuspend() const;
1010 : void SetMediaSuspend(SuspendTypes aSuspend);
1011 :
1012 : bool GetAudioMuted() const;
1013 : void SetAudioMuted(bool aMuted);
1014 :
1015 : float GetAudioVolume() const;
1016 : nsresult SetAudioVolume(float aVolume);
1017 :
1018 : void MaybeActiveMediaComponents();
1019 :
1020 : void SetServiceWorkersTestingEnabled(bool aEnabled);
1021 : bool GetServiceWorkersTestingEnabled();
1022 :
1023 : float GetDevicePixelRatio(mozilla::dom::CallerType aCallerType);
1024 :
1025 : void SetLargeAllocStatus(mozilla::dom::LargeAllocStatus aStatus);
1026 :
1027 : bool IsTopLevelWindow();
1028 : bool HadOriginalOpener() const;
1029 : };
1030 :
1031 : NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowOuter, NS_PIDOMWINDOWOUTER_IID)
1032 :
1033 : #include "nsPIDOMWindowInlines.h"
1034 :
1035 : #ifdef MOZILLA_INTERNAL_API
1036 : PopupControlState
1037 : PushPopupControlState(PopupControlState aState, bool aForce);
1038 :
1039 : void
1040 : PopPopupControlState(PopupControlState aState);
1041 :
1042 : #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherInternal
1043 : #else
1044 : #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherExternal
1045 : #endif
1046 :
1047 : // Helper class that helps with pushing and popping popup control
1048 : // state. Note that this class looks different from within code that's
1049 : // part of the layout library than it does in code outside the layout
1050 : // library. We give the two object layouts different names so the symbols
1051 : // don't conflict, but code should always use the name
1052 : // |nsAutoPopupStatePusher|.
1053 : class NS_AUTO_POPUP_STATE_PUSHER
1054 : {
1055 : public:
1056 : #ifdef MOZILLA_INTERNAL_API
1057 830 : explicit NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false)
1058 830 : : mOldState(::PushPopupControlState(aState, aForce))
1059 : {
1060 830 : }
1061 :
1062 830 : ~NS_AUTO_POPUP_STATE_PUSHER()
1063 830 : {
1064 830 : PopPopupControlState(mOldState);
1065 830 : }
1066 : #else
1067 : NS_AUTO_POPUP_STATE_PUSHER(nsPIDOMWindowOuter *aWindow, PopupControlState aState)
1068 : : mWindow(aWindow), mOldState(openAbused)
1069 : {
1070 : if (aWindow) {
1071 : mOldState = aWindow->PushPopupControlState(aState, false);
1072 : }
1073 : }
1074 :
1075 : ~NS_AUTO_POPUP_STATE_PUSHER()
1076 : {
1077 : if (mWindow) {
1078 : mWindow->PopPopupControlState(mOldState);
1079 : }
1080 : }
1081 : #endif
1082 :
1083 : protected:
1084 : #ifndef MOZILLA_INTERNAL_API
1085 : nsCOMPtr<nsPIDOMWindowOuter> mWindow;
1086 : #endif
1087 : PopupControlState mOldState;
1088 :
1089 : private:
1090 : // Hide so that this class can only be stack-allocated
1091 : static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nullptr; }
1092 : static void operator delete(void* /*memory*/) {}
1093 : };
1094 :
1095 : #define nsAutoPopupStatePusher NS_AUTO_POPUP_STATE_PUSHER
1096 :
1097 : #endif // nsPIDOMWindow_h__
|