Coverage Report

Created: 2018-09-25 14:53

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