Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et 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 nsGlobalWindow_h___
8 #define nsGlobalWindow_h___
10 #include "nsPIDOMWindow.h"
12 #include "nsTHashtable.h"
13 #include "nsHashKeys.h"
14 #include "nsRefPtrHashtable.h"
16 // Local Includes
17 // Helper Classes
18 #include "nsCOMPtr.h"
19 #include "nsAutoPtr.h"
20 #include "nsWeakReference.h"
21 #include "nsDataHashtable.h"
22 #include "nsJSThingHashtable.h"
23 #include "nsCycleCollectionParticipant.h"
25 // Interfaces Needed
26 #include "nsIBrowserDOMWindow.h"
27 #include "nsIDOMEventTarget.h"
28 #include "nsIInterfaceRequestor.h"
29 #include "nsIDOMJSWindow.h"
30 #include "nsIDOMChromeWindow.h"
31 #include "nsIScriptGlobalObject.h"
32 #include "nsIScriptObjectPrincipal.h"
33 #include "nsITimer.h"
34 #include "nsIDOMModalContentWindow.h"
35 #include "mozilla/EventListenerManager.h"
36 #include "nsIPrincipal.h"
37 #include "nsSize.h"
38 #include "mozFlushType.h"
39 #include "prclist.h"
40 #include "nsIDOMStorageEvent.h"
41 #include "nsFrameMessageManager.h"
42 #include "mozilla/LinkedList.h"
43 #include "mozilla/TimeStamp.h"
44 #include "nsIInlineEventHandlers.h"
45 #include "nsWrapperCacheInlines.h"
46 #include "nsIIdleObserver.h"
47 #include "nsIDocument.h"
48 #include "nsIDOMTouchEvent.h"
49 #include "mozilla/dom/EventTarget.h"
50 #include "Units.h"
51 #include "nsComponentManagerUtils.h"
53 #ifdef MOZ_B2G
54 #include "nsIDOMWindowB2G.h"
55 #endif // MOZ_B2G
57 #ifdef MOZ_WEBSPEECH
58 #include "nsISpeechSynthesisGetter.h"
59 #endif // MOZ_WEBSPEECH
61 #define DEFAULT_HOME_PAGE "www.mozilla.org"
62 #define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
64 // Amount of time allowed between alert/prompt/confirm before enabling
65 // the stop dialog checkbox.
66 #define DEFAULT_SUCCESSIVE_DIALOG_TIME_LIMIT 3 // 3 sec
68 // Maximum number of successive dialogs before we prompt users to disable
69 // dialogs for this window.
70 #define MAX_SUCCESSIVE_DIALOG_COUNT 5
72 // Idle fuzz time upper limit
73 #define MAX_IDLE_FUZZ_TIME_MS 90000
75 // Min idle notification time in seconds.
76 #define MIN_IDLE_NOTIFICATION_TIME_S 1
78 class nsIArray;
79 class nsIBaseWindow;
80 class nsIContent;
81 class nsICSSDeclaration;
82 class nsIDocShellTreeOwner;
83 class nsIDOMCrypto;
84 class nsIDOMOfflineResourceList;
85 class nsIScrollableFrame;
86 class nsIControllers;
87 class nsIJSID;
88 class nsIScriptContext;
89 class nsIScriptTimeoutHandler;
90 class nsIWebBrowserChrome;
92 class nsDOMWindowList;
93 class nsLocation;
94 class nsScreen;
95 class nsHistory;
96 class nsGlobalWindowObserver;
97 class nsGlobalWindow;
98 class nsDOMWindowUtils;
99 class nsIIdleService;
100 struct nsIntSize;
101 struct nsRect;
103 class nsWindowSizes;
105 namespace mozilla {
106 class DOMEventTargetHelper;
107 namespace dom {
108 class BarProp;
109 class Console;
110 class External;
111 class Function;
112 class Gamepad;
113 class MediaQueryList;
114 class Navigator;
115 class OwningExternalOrWindowProxy;
116 class Selection;
117 class SpeechSynthesis;
118 class WakeLock;
119 namespace indexedDB {
120 class IDBFactory;
121 } // namespace indexedDB
122 } // namespace dom
123 } // namespace mozilla
125 extern nsresult
126 NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
127 bool *aIsInterval,
128 int32_t *aInterval,
129 nsIScriptTimeoutHandler **aRet);
131 extern already_AddRefed<nsIScriptTimeoutHandler>
132 NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
133 mozilla::dom::Function& aFunction,
134 const mozilla::dom::Sequence<JS::Value>& aArguments,
135 mozilla::ErrorResult& aError);
137 extern already_AddRefed<nsIScriptTimeoutHandler>
138 NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
139 const nsAString& aExpression,
140 mozilla::ErrorResult& aError);
142 /*
143 * Timeout struct that holds information about each script
144 * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
145 * abstracts the language specific cruft.
146 */
147 struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
148 {
149 nsTimeout();
150 ~nsTimeout();
152 NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout)
153 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsTimeout)
155 nsresult InitTimer(nsTimerCallbackFunc aFunc, uint32_t aDelay)
156 {
157 return mTimer->InitWithFuncCallback(aFunc, this, aDelay,
158 nsITimer::TYPE_ONE_SHOT);
159 }
161 bool HasRefCntOne();
163 // Window for which this timeout fires
164 nsRefPtr<nsGlobalWindow> mWindow;
166 // The actual timer object
167 nsCOMPtr<nsITimer> mTimer;
169 // True if the timeout was cleared
170 bool mCleared;
172 // True if this is one of the timeouts that are currently running
173 bool mRunning;
175 // True if this is a repeating/interval timer
176 bool mIsInterval;
178 // Returned as value of setTimeout()
179 uint32_t mPublicId;
181 // Interval in milliseconds
182 uint32_t mInterval;
184 // mWhen and mTimeRemaining can't be in a union, sadly, because they
185 // have constructors.
186 // Nominal time to run this timeout. Use only when timeouts are not
187 // suspended.
188 mozilla::TimeStamp mWhen;
189 // Remaining time to wait. Used only when timeouts are suspended.
190 mozilla::TimeDuration mTimeRemaining;
192 // Principal with which to execute
193 nsCOMPtr<nsIPrincipal> mPrincipal;
195 // stack depth at which timeout is firing
196 uint32_t mFiringDepth;
198 //
199 uint32_t mNestingLevel;
201 // The popup state at timeout creation time if not created from
202 // another timeout
203 PopupControlState mPopupState;
205 // The language-specific information about the callback.
206 nsCOMPtr<nsIScriptTimeoutHandler> mScriptHandler;
207 };
209 struct IdleObserverHolder
210 {
211 nsCOMPtr<nsIIdleObserver> mIdleObserver;
212 uint32_t mTimeInS;
213 bool mPrevNotificationIdle;
215 IdleObserverHolder()
216 : mTimeInS(0), mPrevNotificationIdle(false)
217 {
218 MOZ_COUNT_CTOR(IdleObserverHolder);
219 }
221 IdleObserverHolder(const IdleObserverHolder& aOther)
222 : mIdleObserver(aOther.mIdleObserver), mTimeInS(aOther.mTimeInS),
223 mPrevNotificationIdle(aOther.mPrevNotificationIdle)
224 {
225 MOZ_COUNT_CTOR(IdleObserverHolder);
226 }
228 bool operator==(const IdleObserverHolder& aOther) const {
229 return
230 mIdleObserver == aOther.mIdleObserver &&
231 mTimeInS == aOther.mTimeInS;
232 }
234 ~IdleObserverHolder()
235 {
236 MOZ_COUNT_DTOR(IdleObserverHolder);
237 }
238 };
240 static inline already_AddRefed<nsIVariant>
241 CreateVoidVariant()
242 {
243 nsCOMPtr<nsIWritableVariant> writable =
244 do_CreateInstance(NS_VARIANT_CONTRACTID);
245 writable->SetAsVoid();
246 return writable.forget();
247 }
249 // Helper class to manage modal dialog arguments and all their quirks.
250 //
251 // Given our clunky embedding APIs, modal dialog arguments need to be passed
252 // as an nsISupports parameter to WindowWatcher, get stuck inside an array of
253 // length 1, and then passed back to the newly-created dialog.
254 //
255 // However, we need to track both the caller-passed value as well as the
256 // caller's, so that we can do an origin check (even for primitives) when the
257 // value is accessed. This class encapsulates that magic.
258 //
259 // We also use the same machinery for |returnValue|, which needs similar origin
260 // checks.
261 class DialogValueHolder : public nsISupports
262 {
263 public:
264 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
265 NS_DECL_CYCLE_COLLECTION_CLASS(DialogValueHolder)
267 DialogValueHolder(nsIPrincipal* aSubject, nsIVariant* aValue)
268 : mOrigin(aSubject)
269 , mValue(aValue) {}
270 nsresult Get(nsIPrincipal* aSubject, nsIVariant** aResult)
271 {
272 nsCOMPtr<nsIVariant> result;
273 if (aSubject->SubsumesConsideringDomain(mOrigin)) {
274 result = mValue;
275 } else {
276 result = CreateVoidVariant();
277 }
278 result.forget(aResult);
279 return NS_OK;
280 }
281 void Get(JSContext* aCx, JS::Handle<JSObject*> aScope, nsIPrincipal* aSubject,
282 JS::MutableHandle<JS::Value> aResult, mozilla::ErrorResult& aError)
283 {
284 if (aSubject->Subsumes(mOrigin)) {
285 aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope,
286 mValue, aResult);
287 } else {
288 aResult.setUndefined();
289 }
290 }
291 virtual ~DialogValueHolder() {}
292 private:
293 nsCOMPtr<nsIPrincipal> mOrigin;
294 nsCOMPtr<nsIVariant> mValue;
295 };
297 //*****************************************************************************
298 // nsGlobalWindow: Global Object for Scripting
299 //*****************************************************************************
300 // Beware that all scriptable interfaces implemented by
301 // nsGlobalWindow will be reachable from JS, if you make this class
302 // implement new interfaces you better know what you're
303 // doing. Security wise this is very sensitive code. --
304 // jst@netscape.com
306 // nsGlobalWindow inherits PRCList for maintaining a list of all inner
307 // windows still in memory for any given outer window. This list is
308 // needed to ensure that mOuterWindow doesn't end up dangling. The
309 // nature of PRCList means that the window itself is always in the
310 // list, and an outer window's list will also contain all inner window
311 // objects that are still in memory (and in reality all inner window
312 // object's lists also contain its outer and all other inner windows
313 // belonging to the same outer window, but that's an unimportant
314 // side effect of inheriting PRCList).
316 class nsGlobalWindow : public mozilla::dom::EventTarget,
317 public nsPIDOMWindow,
318 public nsIScriptGlobalObject,
319 public nsIScriptObjectPrincipal,
320 public nsIDOMJSWindow,
321 public nsSupportsWeakReference,
322 public nsIInterfaceRequestor,
323 public PRCListStr,
324 public nsIDOMWindowPerformance,
325 public nsITouchEventReceiver,
326 public nsIInlineEventHandlers
327 #ifdef MOZ_B2G
328 , public nsIDOMWindowB2G
329 #endif // MOZ_B2G
330 #ifdef MOZ_WEBSPEECH
331 , public nsISpeechSynthesisGetter
332 #endif // MOZ_WEBSPEECH
333 {
334 public:
335 typedef mozilla::TimeStamp TimeStamp;
336 typedef mozilla::TimeDuration TimeDuration;
337 typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindow*> WindowByIdTable;
339 // public methods
340 nsPIDOMWindow* GetPrivateParent();
341 // callback for close event
342 void ReallyCloseWindow();
344 // nsISupports
345 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
347 // nsWrapperCache
348 virtual JSObject *WrapObject(JSContext *cx) MOZ_OVERRIDE
349 {
350 NS_ASSERTION(IsOuterWindow(),
351 "Inner window supports nsWrapperCache, fix WrapObject!");
352 return EnsureInnerWindow() ? GetWrapper() : nullptr;
353 }
355 // nsIGlobalJSObjectHolder
356 virtual JSObject *GetGlobalJSObject();
358 // nsIScriptGlobalObject
359 JSObject *FastGetGlobalJSObject() const
360 {
361 return GetWrapperPreserveColor();
362 }
364 void TraceGlobalJSObject(JSTracer* aTrc);
366 virtual nsresult EnsureScriptEnvironment();
368 virtual nsIScriptContext *GetScriptContext();
370 void PoisonOuterWindowProxy(JSObject *aObject);
372 virtual bool IsBlackForCC(bool aTracingNeeded = true);
374 static JSObject* OuterObject(JSContext* aCx, JS::Handle<JSObject*> aObj);
376 // nsIScriptObjectPrincipal
377 virtual nsIPrincipal* GetPrincipal();
379 // nsIDOMWindow
380 NS_DECL_NSIDOMWINDOW
382 #ifdef MOZ_B2G
383 // nsIDOMWindowB2G
384 NS_DECL_NSIDOMWINDOWB2G
385 #endif // MOZ_B2G
387 #ifdef MOZ_WEBSPEECH
388 // nsISpeechSynthesisGetter
389 NS_DECL_NSISPEECHSYNTHESISGETTER
390 #endif // MOZ_WEBSPEECH
392 // nsIDOMWindowPerformance
393 NS_DECL_NSIDOMWINDOWPERFORMANCE
395 // nsIDOMJSWindow
396 NS_DECL_NSIDOMJSWINDOW
398 // nsIDOMEventTarget
399 NS_DECL_NSIDOMEVENTTARGET
401 virtual mozilla::EventListenerManager*
402 GetExistingListenerManager() const MOZ_OVERRIDE;
404 virtual mozilla::EventListenerManager*
405 GetOrCreateListenerManager() MOZ_OVERRIDE;
407 using mozilla::dom::EventTarget::RemoveEventListener;
408 virtual void AddEventListener(const nsAString& aType,
409 mozilla::dom::EventListener* aListener,
410 bool aUseCapture,
411 const mozilla::dom::Nullable<bool>& aWantsUntrusted,
412 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
413 virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE
414 {
415 if (IsOuterWindow()) {
416 return this;
417 }
419 return GetOuterFromCurrentInner(this);
420 }
422 // nsITouchEventReceiver
423 NS_DECL_NSITOUCHEVENTRECEIVER
425 // nsIInlineEventHandlers
426 NS_DECL_NSIINLINEEVENTHANDLERS
428 // nsPIDOMWindow
429 virtual NS_HIDDEN_(nsPIDOMWindow*) GetPrivateRoot();
431 // Outer windows only.
432 virtual NS_HIDDEN_(void) ActivateOrDeactivate(bool aActivate);
433 virtual NS_HIDDEN_(void) SetActive(bool aActive);
434 virtual NS_HIDDEN_(void) SetIsBackground(bool aIsBackground);
435 virtual NS_HIDDEN_(void) SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler);
437 virtual NS_HIDDEN_(void) SetInitialPrincipalToSubject();
439 virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const;
440 virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
441 virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
443 virtual already_AddRefed<nsISupports> SaveWindowState();
444 virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
445 virtual NS_HIDDEN_(void) SuspendTimeouts(uint32_t aIncrease = 1,
446 bool aFreezeChildren = true);
447 virtual NS_HIDDEN_(nsresult) ResumeTimeouts(bool aThawChildren = true);
448 virtual NS_HIDDEN_(uint32_t) TimeoutSuspendCount();
449 virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents();
450 virtual NS_HIDDEN_(bool) IsFrozen() const
451 {
452 return mIsFrozen;
453 }
454 virtual NS_HIDDEN_(bool) IsRunningTimeout() { return mTimeoutFiringDepth > 0; }
456 virtual NS_HIDDEN_(bool) WouldReuseInnerWindow(nsIDocument *aNewDocument);
458 virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell);
459 virtual void DetachFromDocShell();
460 virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument,
461 nsISupports *aState,
462 bool aForceReuseInnerWindow);
463 void DispatchDOMWindowCreated();
464 virtual NS_HIDDEN_(void) SetOpenerWindow(nsIDOMWindow* aOpener,
465 bool aOriginalOpener);
467 // Outer windows only.
468 virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
470 virtual NS_HIDDEN_(void) EnterModalState();
471 virtual NS_HIDDEN_(void) LeaveModalState();
473 virtual NS_HIDDEN_(bool) CanClose();
474 virtual NS_HIDDEN_(nsresult) ForceClose();
476 virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
477 virtual NS_HIDDEN_(void) UpdateTouchState();
478 virtual NS_HIDDEN_(bool) DispatchCustomEvent(const char *aEventName);
479 virtual NS_HIDDEN_(bool) DispatchResizeEvent(const nsIntSize& aSize);
480 virtual NS_HIDDEN_(void) RefreshCompartmentPrincipal();
481 virtual NS_HIDDEN_(nsresult) SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust);
483 virtual NS_HIDDEN_(void) SetHasGamepadEventListener(bool aHasGamepad = true);
485 // nsIInterfaceRequestor
486 NS_DECL_NSIINTERFACEREQUESTOR
488 // WebIDL interface.
489 already_AddRefed<nsIDOMWindow> IndexedGetter(uint32_t aIndex, bool& aFound);
491 void GetSupportedNames(nsTArray<nsString>& aNames);
493 static bool IsChromeWindow(JSContext* /* unused */, JSObject* aObj);
495 bool IsChrome() const;
497 bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
498 JS::Handle<jsid> aId,
499 JS::MutableHandle<JSPropertyDescriptor> aDesc);
501 void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
502 mozilla::ErrorResult& aRv);
504 // Object Management
505 nsGlobalWindow(nsGlobalWindow *aOuterWindow);
507 static nsGlobalWindow *FromSupports(nsISupports *supports)
508 {
509 // Make sure this matches the casts we do in QueryInterface().
510 return (nsGlobalWindow *)(mozilla::dom::EventTarget *)supports;
511 }
512 static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper)
513 {
514 return FromSupports(wrapper->Native());
515 }
517 /**
518 * Wrap nsIDOMWindow::GetTop so we can overload the inline GetTop()
519 * implementation below. (nsIDOMWindow::GetTop simply calls
520 * nsIDOMWindow::GetRealTop().)
521 */
522 nsresult GetTop(nsIDOMWindow **aWindow)
523 {
524 return nsIDOMWindow::GetTop(aWindow);
525 }
527 inline nsGlobalWindow *GetTop()
528 {
529 nsCOMPtr<nsIDOMWindow> top;
530 GetTop(getter_AddRefs(top));
531 if (top)
532 return static_cast<nsGlobalWindow *>(top.get());
533 return nullptr;
534 }
536 inline nsGlobalWindow* GetScriptableTop()
537 {
538 nsCOMPtr<nsIDOMWindow> top;
539 GetScriptableTop(getter_AddRefs(top));
540 return static_cast<nsGlobalWindow *>(top.get());
541 }
543 already_AddRefed<nsIDOMWindow> GetChildWindow(const nsAString& aName);
545 // These return true if we've reached the state in this top level window
546 // where we ask the user if further dialogs should be blocked.
547 //
548 // DialogsAreBeingAbused must be called on the scriptable top inner window.
549 //
550 // ShouldPromptToBlockDialogs is implemented in terms of
551 // DialogsAreBeingAbused, and will get the scriptable top inner window
552 // automatically.
553 // Outer windows only.
554 bool ShouldPromptToBlockDialogs();
555 // Inner windows only.
556 bool DialogsAreBeingAbused();
558 // These functions are used for controlling and determining whether dialogs
559 // (alert, prompt, confirm) are currently allowed in this window.
560 void EnableDialogs();
561 void DisableDialogs();
562 bool AreDialogsEnabled();
564 nsIScriptContext *GetContextInternal()
565 {
566 if (mOuterWindow) {
567 return GetOuterWindowInternal()->mContext;
568 }
570 return mContext;
571 }
573 nsGlobalWindow *GetOuterWindowInternal()
574 {
575 return static_cast<nsGlobalWindow *>(GetOuterWindow());
576 }
578 nsGlobalWindow *GetCurrentInnerWindowInternal() const
579 {
580 return static_cast<nsGlobalWindow *>(mInnerWindow);
581 }
583 nsGlobalWindow *EnsureInnerWindowInternal()
584 {
585 return static_cast<nsGlobalWindow *>(EnsureInnerWindow());
586 }
588 bool IsCreatingInnerWindow() const
589 {
590 return mCreatingInnerWindow;
591 }
593 bool IsChromeWindow() const
594 {
595 return mIsChrome;
596 }
598 using nsPIDOMWindow::IsModalContentWindow;
599 static bool IsModalContentWindow(JSContext* aCx, JSObject* aGlobal);
601 // GetScrollFrame does not flush. Callers should do it themselves as needed,
602 // depending on which info they actually want off the scrollable frame.
603 nsIScrollableFrame *GetScrollFrame();
605 nsresult Observe(nsISupports* aSubject, const char* aTopic,
606 const char16_t* aData);
608 // Outer windows only.
609 void UnblockScriptedClosing();
611 static void Init();
612 static void ShutDown();
613 static void CleanupCachedXBLHandlers(nsGlobalWindow* aWindow);
614 static bool IsCallerChrome();
616 static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow,
617 nsGlobalWindow *aWindow);
619 friend class WindowStateHolder;
621 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
622 nsIDOMEventTarget)
624 #ifdef DEBUG
625 // Call Unlink on this window. This may cause bad things to happen, so use
626 // with caution.
627 void RiskyUnlink();
628 #endif
630 virtual NS_HIDDEN_(JSObject*)
631 GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
633 virtual NS_HIDDEN_(void)
634 CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
635 JS::Handle<JSObject*> aHandler);
637 virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod);
638 virtual void SetReadyForFocus();
639 virtual void PageHidden();
640 virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI);
641 virtual nsresult DispatchSyncPopState();
643 // Inner windows only.
644 virtual void EnableDeviceSensor(uint32_t aType);
645 virtual void DisableDeviceSensor(uint32_t aType);
647 virtual void EnableTimeChangeNotifications();
648 virtual void DisableTimeChangeNotifications();
650 #ifdef MOZ_B2G
651 // Inner windows only.
652 virtual void EnableNetworkEvent(uint32_t aType);
653 virtual void DisableNetworkEvent(uint32_t aType);
654 #endif // MOZ_B2G
656 virtual nsresult SetArguments(nsIArray *aArguments);
658 void MaybeForgiveSpamCount();
659 bool IsClosedOrClosing() {
660 return (mIsClosed ||
661 mInClose ||
662 mHavePendingClose ||
663 mCleanedUp);
664 }
666 static void FirePopupBlockedEvent(nsIDocument* aDoc,
667 nsIDOMWindow *aRequestingWindow, nsIURI *aPopupURI,
668 const nsAString &aPopupWindowName,
669 const nsAString &aPopupWindowFeatures);
671 virtual uint32_t GetSerial() {
672 return mSerial;
673 }
675 static nsGlobalWindow* GetOuterWindowWithId(uint64_t aWindowID) {
676 if (!sWindowsById) {
677 return nullptr;
678 }
680 nsGlobalWindow* outerWindow = sWindowsById->Get(aWindowID);
681 return outerWindow && !outerWindow->IsInnerWindow() ? outerWindow : nullptr;
682 }
684 static nsGlobalWindow* GetInnerWindowWithId(uint64_t aInnerWindowID) {
685 if (!sWindowsById) {
686 return nullptr;
687 }
689 nsGlobalWindow* innerWindow = sWindowsById->Get(aInnerWindowID);
690 return innerWindow && innerWindow->IsInnerWindow() ? innerWindow : nullptr;
691 }
693 static WindowByIdTable* GetWindowsTable() {
694 return sWindowsById;
695 }
697 void AddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const;
699 void UnmarkGrayTimers();
701 void AddEventTargetObject(mozilla::DOMEventTargetHelper* aObject);
702 void RemoveEventTargetObject(mozilla::DOMEventTargetHelper* aObject);
704 void NotifyIdleObserver(IdleObserverHolder* aIdleObserverHolder,
705 bool aCallOnidle);
706 nsresult HandleIdleActiveEvent();
707 bool ContainsIdleObserver(nsIIdleObserver* aIdleObserver, uint32_t timeInS);
708 void HandleIdleObserverCallback();
710 void AllowScriptsToClose()
711 {
712 mAllowScriptsToClose = true;
713 }
715 enum SlowScriptResponse {
716 ContinueSlowScript = 0,
717 AlwaysContinueSlowScript,
718 KillSlowScript
719 };
720 SlowScriptResponse ShowSlowScriptDialog();
722 #ifdef MOZ_GAMEPAD
723 void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad);
724 void RemoveGamepad(uint32_t aIndex);
725 void GetGamepads(nsTArray<nsRefPtr<mozilla::dom::Gamepad> >& aGamepads);
726 already_AddRefed<mozilla::dom::Gamepad> GetGamepad(uint32_t aIndex);
727 void SetHasSeenGamepadInput(bool aHasSeen);
728 bool HasSeenGamepadInput();
729 void SyncGamepadState();
730 static PLDHashOperator EnumGamepadsForSync(const uint32_t& aKey,
731 mozilla::dom::Gamepad* aData,
732 void* aUserArg);
733 static PLDHashOperator EnumGamepadsForGet(const uint32_t& aKey,
734 mozilla::dom::Gamepad* aData,
735 void* aUserArg);
736 #endif
738 // Enable/disable updates for gamepad input.
739 void EnableGamepadUpdates();
740 void DisableGamepadUpdates();
743 #define EVENT(name_, id_, type_, struct_) \
744 mozilla::dom::EventHandlerNonNull* GetOn##name_() \
745 { \
746 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
747 return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \
748 : nullptr; \
749 } \
750 void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) \
751 { \
752 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
753 if (elm) { \
754 elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler); \
755 } \
756 }
757 #define ERROR_EVENT(name_, id_, type_, struct_) \
758 mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_() \
759 { \
760 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
761 return elm ? elm->GetOnErrorEventHandler() : nullptr; \
762 } \
763 void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler) \
764 { \
765 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
766 if (elm) { \
767 elm->SetEventHandler(handler); \
768 } \
769 }
770 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_) \
771 mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_() \
772 { \
773 mozilla::EventListenerManager* elm = GetExistingListenerManager(); \
774 return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr; \
775 } \
776 void SetOn##name_(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) \
777 { \
778 mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \
779 if (elm) { \
780 elm->SetEventHandler(handler); \
781 } \
782 }
783 #define WINDOW_ONLY_EVENT EVENT
784 #define TOUCH_EVENT EVENT
785 #include "mozilla/EventNameList.h"
786 #undef TOUCH_EVENT
787 #undef WINDOW_ONLY_EVENT
788 #undef BEFOREUNLOAD_EVENT
789 #undef ERROR_EVENT
790 #undef EVENT
792 nsISupports* GetParentObject()
793 {
794 return nullptr;
795 }
797 static bool WindowOnWebIDL(JSContext* /* unused */, JSObject* aObj);
799 nsIDOMWindow* GetWindow(mozilla::ErrorResult& aError);
800 nsIDOMWindow* GetSelf(mozilla::ErrorResult& aError);
801 nsIDocument* GetDocument()
802 {
803 return GetDoc();
804 }
805 void GetName(nsAString& aName, mozilla::ErrorResult& aError);
806 void SetName(const nsAString& aName, mozilla::ErrorResult& aError);
807 nsIDOMLocation* GetLocation(mozilla::ErrorResult& aError);
808 nsHistory* GetHistory(mozilla::ErrorResult& aError);
809 mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError);
810 mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError);
811 mozilla::dom::BarProp* GetPersonalbar(mozilla::ErrorResult& aError);
812 mozilla::dom::BarProp* GetScrollbars(mozilla::ErrorResult& aError);
813 mozilla::dom::BarProp* GetStatusbar(mozilla::ErrorResult& aError);
814 mozilla::dom::BarProp* GetToolbar(mozilla::ErrorResult& aError);
815 void GetStatus(nsAString& aStatus, mozilla::ErrorResult& aError);
816 void SetStatus(const nsAString& aStatus, mozilla::ErrorResult& aError);
817 void Close(mozilla::ErrorResult& aError);
818 bool GetClosed(mozilla::ErrorResult& aError);
819 void Stop(mozilla::ErrorResult& aError);
820 void Focus(mozilla::ErrorResult& aError);
821 void Blur(mozilla::ErrorResult& aError);
822 already_AddRefed<nsIDOMWindow> GetFrames(mozilla::ErrorResult& aError);
823 uint32_t Length();
824 already_AddRefed<nsIDOMWindow> GetTop(mozilla::ErrorResult& aError)
825 {
826 nsCOMPtr<nsIDOMWindow> top;
827 aError = GetScriptableTop(getter_AddRefs(top));
828 return top.forget();
829 }
830 protected:
831 nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
832 public:
833 void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
834 mozilla::ErrorResult& aError);
835 void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
836 mozilla::ErrorResult& aError);
837 using nsIDOMWindow::GetParent;
838 already_AddRefed<nsIDOMWindow> GetParent(mozilla::ErrorResult& aError);
839 mozilla::dom::Element* GetFrameElement(mozilla::ErrorResult& aError);
840 already_AddRefed<nsIDOMWindow> Open(const nsAString& aUrl,
841 const nsAString& aName,
842 const nsAString& aOptions,
843 mozilla::ErrorResult& aError);
844 mozilla::dom::Navigator* GetNavigator(mozilla::ErrorResult& aError);
845 nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError);
847 mozilla::dom::Console* GetConsole(mozilla::ErrorResult& aRv);
849 void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult,
850 mozilla::ErrorResult& aRv);
851 already_AddRefed<mozilla::dom::External> GetExternal(mozilla::ErrorResult& aRv);
853 protected:
854 bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
855 mozilla::ErrorResult& aError);
857 public:
858 void Alert(const nsAString& aMessage, mozilla::ErrorResult& aError);
859 bool Confirm(const nsAString& aMessage, mozilla::ErrorResult& aError);
860 void Prompt(const nsAString& aMessage, const nsAString& aInitial,
861 nsAString& aReturn, mozilla::ErrorResult& aError);
862 void Print(mozilla::ErrorResult& aError);
863 void ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
864 JS::Handle<JS::Value> aArgument,
865 const nsAString& aOptions,
866 JS::MutableHandle<JS::Value> aRetval,
867 mozilla::ErrorResult& aError);
868 void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
869 const nsAString& aTargetOrigin,
870 const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
871 mozilla::ErrorResult& aError);
872 int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
873 int32_t aTimeout,
874 const mozilla::dom::Sequence<JS::Value>& aArguments,
875 mozilla::ErrorResult& aError);
876 int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
877 int32_t aTimeout,
878 const mozilla::dom::Sequence<JS::Value>& /* unused */,
879 mozilla::ErrorResult& aError);
880 void ClearTimeout(int32_t aHandle, mozilla::ErrorResult& aError);
881 int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
882 const mozilla::dom::Optional<int32_t>& aTimeout,
883 const mozilla::dom::Sequence<JS::Value>& aArguments,
884 mozilla::ErrorResult& aError);
885 int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
886 const mozilla::dom::Optional<int32_t>& aTimeout,
887 const mozilla::dom::Sequence<JS::Value>& /* unused */,
888 mozilla::ErrorResult& aError);
889 void ClearInterval(int32_t aHandle, mozilla::ErrorResult& aError);
890 void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData,
891 mozilla::ErrorResult& aError);
892 void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
893 mozilla::ErrorResult& aError);
894 nsIDOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
895 nsIDOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
896 mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
897 mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
898 already_AddRefed<nsICSSDeclaration>
899 GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
900 mozilla::ErrorResult& aError);
901 already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(const nsAString& aQuery,
902 mozilla::ErrorResult& aError);
903 nsScreen* GetScreen(mozilla::ErrorResult& aError);
904 void MoveTo(int32_t aXPos, int32_t aYPos, mozilla::ErrorResult& aError);
905 void MoveBy(int32_t aXDif, int32_t aYDif, mozilla::ErrorResult& aError);
906 void ResizeTo(int32_t aWidth, int32_t aHeight,
907 mozilla::ErrorResult& aError);
908 void ResizeBy(int32_t aWidthDif, int32_t aHeightDif,
909 mozilla::ErrorResult& aError);
910 int32_t GetInnerWidth(mozilla::ErrorResult& aError);
911 void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError);
912 int32_t GetInnerHeight(mozilla::ErrorResult& aError);
913 void SetInnerHeight(int32_t aInnerHeight, mozilla::ErrorResult& aError);
914 int32_t GetScrollX(mozilla::ErrorResult& aError);
915 int32_t GetPageXOffset(mozilla::ErrorResult& aError)
916 {
917 return GetScrollX(aError);
918 }
919 int32_t GetScrollY(mozilla::ErrorResult& aError);
920 int32_t GetPageYOffset(mozilla::ErrorResult& aError)
921 {
922 return GetScrollY(aError);
923 }
924 int32_t GetScreenX(mozilla::ErrorResult& aError);
925 void SetScreenX(int32_t aScreenX, mozilla::ErrorResult& aError);
926 int32_t GetScreenY(mozilla::ErrorResult& aError);
927 void SetScreenY(int32_t aScreenY, mozilla::ErrorResult& aError);
928 int32_t GetOuterWidth(mozilla::ErrorResult& aError);
929 void SetOuterWidth(int32_t aOuterWidth, mozilla::ErrorResult& aError);
930 int32_t GetOuterHeight(mozilla::ErrorResult& aError);
931 void SetOuterHeight(int32_t aOuterHeight, mozilla::ErrorResult& aError);
932 int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
933 mozilla::ErrorResult& aError);
934 void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
935 nsPerformance* GetPerformance(mozilla::ErrorResult& aError);
936 nsresult GetFirstPartyIsolationURI(nsIURI** aFirstPartyIsolationURI);
938 #ifdef MOZ_WEBSPEECH
939 mozilla::dom::SpeechSynthesis*
940 GetSpeechSynthesis(mozilla::ErrorResult& aError);
941 #endif
942 already_AddRefed<nsICSSDeclaration>
943 GetDefaultComputedStyle(mozilla::dom::Element& aElt,
944 const nsAString& aPseudoElt,
945 mozilla::ErrorResult& aError);
946 mozilla::dom::indexedDB::IDBFactory*
947 GetMozIndexedDB(mozilla::ErrorResult& aError)
948 {
949 return GetIndexedDB(aError);
950 }
951 int32_t MozRequestAnimationFrame(nsIFrameRequestCallback* aRequestCallback,
952 mozilla::ErrorResult& aError);
953 void MozCancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError)
954 {
955 return CancelAnimationFrame(aHandle, aError);
956 }
957 void MozCancelRequestAnimationFrame(int32_t aHandle,
958 mozilla::ErrorResult& aError)
959 {
960 return CancelAnimationFrame(aHandle, aError);
961 }
962 int64_t GetMozAnimationStartTime(mozilla::ErrorResult& aError);
963 void SizeToContent(mozilla::ErrorResult& aError);
964 nsIDOMCrypto* GetCrypto(mozilla::ErrorResult& aError);
965 nsIControllers* GetControllers(mozilla::ErrorResult& aError);
966 float GetMozInnerScreenX(mozilla::ErrorResult& aError);
967 float GetMozInnerScreenY(mozilla::ErrorResult& aError);
968 float GetDevicePixelRatio(mozilla::ErrorResult& aError);
969 int32_t GetScrollMaxX(mozilla::ErrorResult& aError);
970 int32_t GetScrollMaxY(mozilla::ErrorResult& aError);
971 bool GetFullScreen(mozilla::ErrorResult& aError);
972 void SetFullScreen(bool aFullScreen, mozilla::ErrorResult& aError);
973 void Back(mozilla::ErrorResult& aError);
974 void Forward(mozilla::ErrorResult& aError);
975 void Home(mozilla::ErrorResult& aError);
976 bool Find(const nsAString& aString, bool aCaseSensitive, bool aBackwards,
977 bool aWrapAround, bool aWholeWord, bool aSearchInFrames,
978 bool aShowDialog, mozilla::ErrorResult& aError);
979 uint64_t GetMozPaintCount(mozilla::ErrorResult& aError);
980 already_AddRefed<nsIDOMWindow> OpenDialog(JSContext* aCx,
981 const nsAString& aUrl,
982 const nsAString& aName,
983 const nsAString& aOptions,
984 const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
985 mozilla::ErrorResult& aError);
986 void GetContent(JSContext* aCx,
987 JS::MutableHandle<JSObject*> aRetval,
988 mozilla::ErrorResult& aError);
989 void Get_content(JSContext* aCx,
990 JS::MutableHandle<JSObject*> aRetval,
991 mozilla::ErrorResult& aError)
992 {
993 if (mDoc) {
994 mDoc->WarnOnceAbout(nsIDocument::eWindow_Content);
995 }
996 GetContent(aCx, aRetval, aError);
997 }
999 // ChromeWindow bits. Do NOT call these unless your window is in
1000 // fact an nsGlobalChromeWindow.
1001 uint16_t WindowState();
1002 nsIBrowserDOMWindow* GetBrowserDOMWindow(mozilla::ErrorResult& aError);
1003 void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow,
1004 mozilla::ErrorResult& aError);
1005 void GetAttention(mozilla::ErrorResult& aError);
1006 void GetAttentionWithCycleCount(int32_t aCycleCount,
1007 mozilla::ErrorResult& aError);
1008 void SetCursor(const nsAString& aCursor, mozilla::ErrorResult& aError);
1009 void Maximize(mozilla::ErrorResult& aError);
1010 void Minimize(mozilla::ErrorResult& aError);
1011 void Restore(mozilla::ErrorResult& aError);
1012 void NotifyDefaultButtonLoaded(mozilla::dom::Element& aDefaultButton,
1013 mozilla::ErrorResult& aError);
1014 nsIMessageBroadcaster* GetMessageManager(mozilla::ErrorResult& aError);
1015 void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent,
1016 mozilla::dom::Element* aPanel,
1017 mozilla::ErrorResult& aError);
1019 void GetDialogArguments(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
1020 mozilla::ErrorResult& aError);
1021 void GetReturnValue(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
1022 mozilla::ErrorResult& aError);
1023 void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
1024 mozilla::ErrorResult& aError);
1026 void GetInterface(JSContext* aCx, nsIJSID* aIID,
1027 JS::MutableHandle<JS::Value> aRetval,
1028 mozilla::ErrorResult& aError);
1030 protected:
1031 // Array of idle observers that are notified of idle events.
1032 nsTObserverArray<IdleObserverHolder> mIdleObservers;
1034 // Idle timer used for function callbacks to notify idle observers.
1035 nsCOMPtr<nsITimer> mIdleTimer;
1037 // Idle fuzz time added to idle timer callbacks.
1038 uint32_t mIdleFuzzFactor;
1040 // Index in mArrayIdleObservers
1041 // Next idle observer to notify user idle status
1042 int32_t mIdleCallbackIndex;
1044 // If false then the topic is "active"
1045 // If true then the topic is "idle"
1046 bool mCurrentlyIdle;
1048 // Set to true when a fuzz time needs to be applied
1049 // to active notifications to the idle observer.
1050 bool mAddActiveEventFuzzTime;
1052 nsCOMPtr <nsIIdleService> mIdleService;
1054 nsRefPtr<mozilla::dom::WakeLock> mWakeLock;
1056 static bool sIdleObserversAPIFuzzTimeDisabled;
1058 friend class HashchangeCallback;
1059 friend class mozilla::dom::BarProp;
1061 // Object Management
1062 virtual ~nsGlobalWindow();
1063 void DropOuterWindowDocs();
1064 void CleanUp();
1065 void ClearControllers();
1066 nsresult FinalClose();
1068 inline void MaybeClearInnerWindow(nsGlobalWindow* aExpectedInner)
1069 {
1070 if(mInnerWindow == aExpectedInner) {
1071 mInnerWindow = nullptr;
1072 }
1073 }
1075 void FreeInnerObjects();
1076 JSObject *CallerGlobal();
1077 nsGlobalWindow *CallerInnerWindow();
1079 // Only to be called on an inner window.
1080 // aDocument must not be null.
1081 void InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument);
1083 nsresult DefineArgumentsProperty(nsIArray *aArguments);
1085 // Get the parent, returns null if this is a toplevel window
1086 nsIDOMWindow* GetParentInternal();
1088 // popup tracking
1089 bool IsPopupSpamWindow()
1090 {
1091 if (IsInnerWindow() && !mOuterWindow) {
1092 return false;
1093 }
1095 return GetOuterWindowInternal()->mIsPopupSpam;
1096 }
1098 void SetPopupSpamWindow(bool aPopup)
1099 {
1100 if (IsInnerWindow() && !mOuterWindow) {
1101 NS_ERROR("SetPopupSpamWindow() called on inner window w/o an outer!");
1103 return;
1104 }
1106 GetOuterWindowInternal()->mIsPopupSpam = aPopup;
1107 }
1109 // Window Control Functions
1111 virtual nsresult
1112 OpenNoNavigate(const nsAString& aUrl,
1113 const nsAString& aName,
1114 const nsAString& aOptions,
1115 nsIDOMWindow **_retval);
1117 /**
1118 * @param aUrl the URL we intend to load into the window. If aNavigate is
1119 * true, we'll actually load this URL into the window. Otherwise,
1120 * aUrl is advisory; OpenInternal will not load the URL into the
1121 * new window.
1122 *
1123 * @param aName the name to use for the new window
1124 *
1125 * @param aOptions the window options to use for the new window
1126 *
1127 * @param aDialog true when called from variants of OpenDialog. If this is
1128 * true, this method will skip popup blocking checks. The aDialog
1129 * argument is passed on to the window watcher.
1130 *
1131 * @param aCalledNoScript true when called via the [noscript] open()
1132 * and openDialog() methods. When this is true, we do NOT want to use
1133 * the JS stack for things like caller determination.
1134 *
1135 * @param aDoJSFixups true when this is the content-accessible JS version of
1136 * window opening. When true, popups do not cause us to throw, we save
1137 * the caller's principal in the new window for later consumption, and
1138 * we make sure that there is a document in the newly-opened window.
1139 * Note that this last will only be done if the newly-opened window is
1140 * non-chrome.
1141 *
1142 * @param aNavigate true if we should navigate to the provided URL, false
1143 * otherwise. When aNavigate is false, we also skip our can-load
1144 * security check, on the assumption that whoever *actually* loads this
1145 * page will do their own security check.
1146 *
1147 * @param argv The arguments to pass to the new window. The first
1148 * three args, if present, will be aUrl, aName, and aOptions. So this
1149 * param only matters if there are more than 3 arguments.
1150 *
1151 * @param argc The number of arguments in argv.
1152 *
1153 * @param aExtraArgument Another way to pass arguments in. This is mutually
1154 * exclusive with the argv/argc approach.
1155 *
1156 * @param aJSCallerContext The calling script's context. This must be null
1157 * when aCalledNoScript is true.
1158 *
1159 * @param aReturn [out] The window that was opened, if any.
1160 */
1161 NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl,
1162 const nsAString& aName,
1163 const nsAString& aOptions,
1164 bool aDialog,
1165 bool aContentModal,
1166 bool aCalledNoScript,
1167 bool aDoJSFixups,
1168 bool aNavigate,
1169 nsIArray *argv,
1170 nsISupports *aExtraArgument,
1171 nsIPrincipal *aCalleePrincipal,
1172 JSContext *aJSCallerContext,
1173 nsIDOMWindow **aReturn);
1175 // Timeout Functions
1176 // Language agnostic timeout function (all args passed).
1177 // |interval| is in milliseconds.
1178 nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
1179 int32_t interval,
1180 bool aIsInterval, int32_t *aReturn);
1181 int32_t SetTimeoutOrInterval(mozilla::dom::Function& aFunction,
1182 int32_t aTimeout,
1183 const mozilla::dom::Sequence<JS::Value>& aArguments,
1184 bool aIsInterval, mozilla::ErrorResult& aError);
1185 int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
1186 int32_t aTimeout, bool aIsInterval,
1187 mozilla::ErrorResult& aError);
1188 void ClearTimeoutOrInterval(int32_t aTimerID,
1189 mozilla::ErrorResult& aError);
1190 nsresult ClearTimeoutOrInterval(int32_t aTimerID)
1191 {
1192 mozilla::ErrorResult rv;
1193 ClearTimeoutOrInterval(aTimerID, rv);
1194 return rv.ErrorCode();
1195 }
1197 // JS specific timeout functions (JS args grabbed from context).
1198 nsresult SetTimeoutOrInterval(bool aIsInterval, int32_t* aReturn);
1199 nsresult ResetTimersForNonBackgroundWindow();
1201 // The timeout implementation functions.
1202 void RunTimeout(nsTimeout *aTimeout);
1203 void RunTimeout() { RunTimeout(nullptr); }
1204 // Return true if |aTimeout| was cleared while its handler ran.
1205 bool RunTimeoutHandler(nsTimeout* aTimeout, nsIScriptContext* aScx);
1206 // Return true if |aTimeout| needs to be reinserted into the timeout list.
1207 bool RescheduleTimeout(nsTimeout* aTimeout, const TimeStamp& now,
1208 bool aRunningPendingTimeouts);
1210 void ClearAllTimeouts();
1211 // Insert aTimeout into the list, before all timeouts that would
1212 // fire after it, but no earlier than mTimeoutInsertionPoint, if any.
1213 void InsertTimeoutIntoList(nsTimeout *aTimeout);
1214 static void TimerCallback(nsITimer *aTimer, void *aClosure);
1216 // Helper Functions
1217 already_AddRefed<nsIDocShellTreeOwner> GetTreeOwner();
1218 already_AddRefed<nsIBaseWindow> GetTreeOwnerWindow();
1219 already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
1220 nsresult SecurityCheckURL(const char *aURL);
1222 bool PopupWhitelisted();
1223 PopupControlState RevisePopupAbuseLevel(PopupControlState);
1224 void FireAbuseEvents(bool aBlocked, bool aWindow,
1225 const nsAString &aPopupURL,
1226 const nsAString &aPopupWindowName,
1227 const nsAString &aPopupWindowFeatures);
1228 void FireOfflineStatusEvent();
1230 // Inner windows only.
1231 nsresult ScheduleNextIdleObserverCallback();
1232 uint32_t GetFuzzTimeMS();
1233 nsresult ScheduleActiveTimerCallback();
1234 uint32_t FindInsertionIndex(IdleObserverHolder* aIdleObserver);
1235 virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserverPtr);
1236 nsresult FindIndexOfElementToRemove(nsIIdleObserver* aIdleObserver,
1237 int32_t* aRemoveElementIndex);
1238 virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserverPtr);
1240 // Inner windows only.
1241 nsresult FireHashchange(const nsAString &aOldURL, const nsAString &aNewURL);
1243 void FlushPendingNotifications(mozFlushType aType);
1245 // Outer windows only.
1246 void EnsureReflowFlushAndPaint();
1247 void CheckSecurityWidthAndHeight(int32_t* width, int32_t* height);
1248 void CheckSecurityLeftAndTop(int32_t* left, int32_t* top);
1250 // Outer windows only.
1251 // Arguments to this function should have values in app units
1252 void SetCSSViewportWidthAndHeight(nscoord width, nscoord height);
1253 // Arguments to this function should have values in device pixels
1254 nsresult SetDocShellWidthAndHeight(int32_t width, int32_t height);
1256 static bool CanSetProperty(const char *aPrefName);
1258 static void MakeScriptDialogTitle(nsAString &aOutTitle);
1260 // Outer windows only.
1261 bool CanMoveResizeWindows();
1263 // If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
1264 // just flush our parent and only flush ourselves if we think we need to.
1265 mozilla::CSSIntPoint GetScrollXY(bool aDoFlush, mozilla::ErrorResult& aError);
1266 nsresult GetScrollXY(int32_t* aScrollX, int32_t* aScrollY, bool aDoFlush);
1267 void GetScrollMaxXY(int32_t* aScrollMaxX, int32_t* aScrollMaxY,
1268 mozilla::ErrorResult& aError);
1270 // Outer windows only.
1271 nsresult GetInnerSize(mozilla::CSSIntSize& aSize);
1272 nsIntSize GetOuterSize(mozilla::ErrorResult& aError);
1273 void SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
1274 mozilla::ErrorResult& aError);
1275 nsRect GetInnerScreenRect();
1277 void ScrollTo(const mozilla::CSSIntPoint& aScroll);
1279 bool IsFrame()
1280 {
1281 return GetParentInternal() != nullptr;
1282 }
1284 // Outer windows only.
1285 // If aLookForCallerOnJSStack is true, this method will look at the JS stack
1286 // to determine who the caller is. If it's false, it'll use |this| as the
1287 // caller.
1288 bool WindowExists(const nsAString& aName, bool aLookForCallerOnJSStack);
1290 already_AddRefed<nsIWidget> GetMainWidget();
1291 nsIWidget* GetNearestWidget();
1293 void Freeze()
1294 {
1295 NS_ASSERTION(!IsFrozen(), "Double-freezing?");
1296 mIsFrozen = true;
1297 NotifyDOMWindowFrozen(this);
1298 }
1300 void Thaw()
1301 {
1302 mIsFrozen = false;
1303 NotifyDOMWindowThawed(this);
1304 }
1306 bool IsInModalState();
1308 // Convenience functions for the many methods that need to scale
1309 // from device to CSS pixels or vice versa. Note: if a presentation
1310 // context is not available, they will assume a 1:1 ratio.
1311 int32_t DevToCSSIntPixels(int32_t px);
1312 int32_t CSSToDevIntPixels(int32_t px);
1313 nsIntSize DevToCSSIntPixels(nsIntSize px);
1314 nsIntSize CSSToDevIntPixels(nsIntSize px);
1316 virtual void SetFocusedNode(nsIContent* aNode,
1317 uint32_t aFocusMethod = 0,
1318 bool aNeedsFocus = false);
1320 virtual uint32_t GetFocusMethod();
1322 virtual bool ShouldShowFocusRing();
1324 virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
1325 UIStateChangeType aShowFocusRings);
1326 virtual void GetKeyboardIndicators(bool* aShowAccelerators,
1327 bool* aShowFocusRings);
1329 // Inner windows only.
1330 void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent);
1332 public:
1333 virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() MOZ_OVERRIDE;
1335 protected:
1336 static void NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow);
1337 void NotifyWindowIDDestroyed(const char* aTopic);
1339 static void NotifyDOMWindowFrozen(nsGlobalWindow* aWindow);
1340 static void NotifyDOMWindowThawed(nsGlobalWindow* aWindow);
1342 void ClearStatus();
1344 virtual void UpdateParentTarget();
1346 inline int32_t DOMMinTimeoutValue() const;
1348 nsresult CloneStorageEvent(const nsAString& aType,
1349 nsCOMPtr<nsIDOMStorageEvent>& aEvent);
1351 // Outer windows only.
1352 nsDOMWindowList* GetWindowList();
1354 // Helper for getComputedStyle and getDefaultComputedStyle
1355 already_AddRefed<nsICSSDeclaration>
1356 GetComputedStyleHelper(mozilla::dom::Element& aElt,
1357 const nsAString& aPseudoElt,
1358 bool aDefaultStylesOnly,
1359 mozilla::ErrorResult& aError);
1360 nsresult GetComputedStyleHelper(nsIDOMElement* aElt,
1361 const nsAString& aPseudoElt,
1362 bool aDefaultStylesOnly,
1363 nsIDOMCSSStyleDeclaration** aReturn);
1365 void PreloadLocalStorage();
1367 // Returns device pixels. Outer windows only.
1368 nsIntPoint GetScreenXY(mozilla::ErrorResult& aError);
1370 int32_t RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback,
1371 mozilla::ErrorResult& aError);
1373 nsGlobalWindow* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError);
1375 mozilla::dom::Element* GetRealFrameElement(mozilla::ErrorResult& aError);
1377 void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
1378 const nsAString& aTargetOrigin,
1379 JS::Handle<JS::Value> aTransfer,
1380 mozilla::ErrorResult& aError);
1382 already_AddRefed<nsIVariant>
1383 ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
1384 const nsAString& aOptions, mozilla::ErrorResult& aError);
1386 already_AddRefed<nsIDOMWindow>
1387 GetContentInternal(mozilla::ErrorResult& aError);
1389 // Ask the user if further dialogs should be blocked, if dialogs are currently
1390 // being abused. This is used in the cases where we have no modifiable UI to
1391 // show, in that case we show a separate dialog to ask this question.
1392 bool ConfirmDialogIfNeeded();
1394 // When adding new member variables, be careful not to create cycles
1395 // through JavaScript. If there is any chance that a member variable
1396 // could own objects that are implemented in JavaScript, then those
1397 // objects will keep the global object (this object) alive. To prevent
1398 // these cycles, ownership of such members must be released in
1399 // |CleanUp| and |DetachFromDocShell|.
1401 // This member is also used on both inner and outer windows, but
1402 // for slightly different purposes. On inner windows it means the
1403 // inner window is held onto by session history and should not
1404 // change. On outer windows it means that the window is in a state
1405 // where we don't want to force creation of a new inner window since
1406 // we're in the middle of doing just that.
1407 bool mIsFrozen : 1;
1409 // These members are only used on outer window objects. Make sure
1410 // you never set any of these on an inner object!
1411 bool mFullScreen : 1;
1412 bool mIsClosed : 1;
1413 bool mInClose : 1;
1414 // mHavePendingClose means we've got a termination function set to
1415 // close us when the JS stops executing or that we have a close
1416 // event posted. If this is set, just ignore window.close() calls.
1417 bool mHavePendingClose : 1;
1418 bool mHadOriginalOpener : 1;
1419 bool mIsPopupSpam : 1;
1421 // Indicates whether scripts are allowed to close this window.
1422 bool mBlockScriptedClosingFlag : 1;
1424 // Track what sorts of events we need to fire when thawed
1425 bool mFireOfflineStatusChangeEventOnThaw : 1;
1426 bool mNotifyIdleObserversIdleOnThaw : 1;
1427 bool mNotifyIdleObserversActiveOnThaw : 1;
1429 // Indicates whether we're in the middle of creating an initializing
1430 // a new inner window object.
1431 bool mCreatingInnerWindow : 1;
1433 // Fast way to tell if this is a chrome window (without having to QI).
1434 bool mIsChrome : 1;
1436 // Hack to indicate whether a chrome window needs its message manager
1437 // to be disconnected, since clean up code is shared in the global
1438 // window superclass.
1439 bool mCleanMessageManager : 1;
1441 // Indicates that the current document has never received a document focus
1442 // event.
1443 bool mNeedsFocus : 1;
1444 bool mHasFocus : 1;
1446 // whether to show keyboard accelerators
1447 bool mShowAccelerators : 1;
1449 // whether to show focus rings
1450 bool mShowFocusRings : 1;
1452 // when true, show focus rings for the current focused content only.
1453 // This will be reset when another element is focused
1454 bool mShowFocusRingForContent : 1;
1456 // true if tab navigation has occurred for this window. Focus rings
1457 // should be displayed.
1458 bool mFocusByKeyOccurred : 1;
1460 // Ensure that a call to ResumeTimeouts() after FreeInnerObjects() does nothing.
1461 // This member is only used by inner windows.
1462 bool mInnerObjectsFreed : 1;
1464 // Indicates whether this window wants gamepad input events
1465 bool mHasGamepad : 1;
1466 #ifdef MOZ_GAMEPAD
1467 nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
1468 bool mHasSeenGamepadInput;
1469 #endif
1471 // whether we've sent the destroy notification for our window id
1472 bool mNotifiedIDDestroyed : 1;
1473 // whether scripts may close the window,
1474 // even if "dom.allow_scripts_to_close_windows" is false.
1475 bool mAllowScriptsToClose : 1;
1477 nsCOMPtr<nsIScriptContext> mContext;
1478 nsWeakPtr mOpener;
1479 nsCOMPtr<nsIControllers> mControllers;
1481 // For |window.arguments|, via |openDialog|.
1482 nsCOMPtr<nsIArray> mArguments;
1484 // For |window.dialogArguments|, via |showModalDialog|.
1485 nsRefPtr<DialogValueHolder> mDialogArguments;
1487 // Only used in the outer.
1488 nsRefPtr<DialogValueHolder> mReturnValue;
1490 nsRefPtr<mozilla::dom::Navigator> mNavigator;
1491 nsRefPtr<nsScreen> mScreen;
1492 nsRefPtr<nsDOMWindowList> mFrames;
1493 nsRefPtr<mozilla::dom::BarProp> mMenubar;
1494 nsRefPtr<mozilla::dom::BarProp> mToolbar;
1495 nsRefPtr<mozilla::dom::BarProp> mLocationbar;
1496 nsRefPtr<mozilla::dom::BarProp> mPersonalbar;
1497 nsRefPtr<mozilla::dom::BarProp> mStatusbar;
1498 nsRefPtr<mozilla::dom::BarProp> mScrollbars;
1499 nsRefPtr<nsDOMWindowUtils> mWindowUtils;
1500 nsString mStatus;
1501 nsString mDefaultStatus;
1502 nsGlobalWindowObserver* mObserver; // Inner windows only.
1503 nsCOMPtr<nsIDOMCrypto> mCrypto;
1504 nsRefPtr<mozilla::dom::Console> mConsole;
1505 // We need to store an nsISupports pointer to this object because the
1506 // mozilla::dom::External class doesn't exist on b2g and using the type
1507 // forward declared here means that ~nsGlobalWindow wouldn't compile because
1508 // it wouldn't see the ~External function's declaration.
1509 nsCOMPtr<nsISupports> mExternal;
1511 nsCOMPtr<nsIDOMStorage> mLocalStorage;
1512 nsCOMPtr<nsIDOMStorage> mSessionStorage;
1514 // These member variable are used only on inner windows.
1515 nsRefPtr<mozilla::EventListenerManager> mListenerManager;
1516 // mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
1517 // non-null. In that case, the dummy timeout pointed to by
1518 // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
1519 // that come after it.
1520 mozilla::LinkedList<nsTimeout> mTimeouts;
1521 // If mTimeoutInsertionPoint is non-null, insertions should happen after it.
1522 // This is a dummy timeout at the moment; if that ever changes, the logic in
1523 // ResetTimersForNonBackgroundWindow needs to change.
1524 nsTimeout* mTimeoutInsertionPoint;
1525 uint32_t mTimeoutPublicIdCounter;
1526 uint32_t mTimeoutFiringDepth;
1527 nsRefPtr<nsLocation> mLocation;
1528 nsRefPtr<nsHistory> mHistory;
1530 // These member variables are used on both inner and the outer windows.
1531 nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
1533 typedef nsCOMArray<nsIDOMStorageEvent> nsDOMStorageEventArray;
1534 nsDOMStorageEventArray mPendingStorageEvents;
1536 uint32_t mTimeoutsSuspendDepth;
1538 // the method that was used to focus mFocusedNode
1539 uint32_t mFocusMethod;
1541 uint32_t mSerial;
1543 #ifdef DEBUG
1544 bool mSetOpenerWindowCalled;
1545 nsCOMPtr<nsIURI> mLastOpenedURI;
1546 #endif
1548 #ifdef MOZ_B2G
1549 bool mNetworkUploadObserverEnabled;
1550 bool mNetworkDownloadObserverEnabled;
1551 #endif // MOZ_B2G
1553 bool mCleanedUp;
1555 nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
1557 nsAutoPtr<nsJSThingHashtable<nsPtrHashKey<nsXBLPrototypeHandler>, JSObject*> > mCachedXBLPrototypeHandlers;
1559 // mSuspendedDoc is only set on outer windows. It's useful when we get matched
1560 // EnterModalState/LeaveModalState calls, in which case the outer window is
1561 // responsible for unsuspending events on the document. If we don't (for
1562 // example, if the outer window is closed before the LeaveModalState call),
1563 // then the inner window whose mDoc is our mSuspendedDoc is responsible for
1564 // unsuspending it.
1565 nsCOMPtr<nsIDocument> mSuspendedDoc;
1567 nsRefPtr<mozilla::dom::indexedDB::IDBFactory> mIndexedDB;
1569 // This counts the number of windows that have been opened in rapid succession
1570 // (i.e. within dom.successive_dialog_time_limit of each other). It is reset
1571 // to 0 once a dialog is opened after dom.successive_dialog_time_limit seconds
1572 // have elapsed without any other dialogs.
1573 uint32_t mDialogAbuseCount;
1575 // This holds the time when the last modal dialog was shown. If more than
1576 // MAX_DIALOG_LIMIT dialogs are shown within the time span defined by
1577 // dom.successive_dialog_time_limit, we show a checkbox or confirmation prompt
1578 // to allow disabling of further dialogs from this window.
1579 TimeStamp mLastDialogQuitTime;
1581 // This flag keeps track of whether dialogs are
1582 // currently enabled on this window.
1583 bool mAreDialogsEnabled;
1585 nsTHashtable<nsPtrHashKey<mozilla::DOMEventTargetHelper> > mEventTargetObjects;
1587 nsTArray<uint32_t> mEnabledSensors;
1589 #ifdef MOZ_WEBSPEECH
1590 // mSpeechSynthesis is only used on inner windows.
1591 nsRefPtr<mozilla::dom::SpeechSynthesis> mSpeechSynthesis;
1592 #endif
1594 friend class nsDOMScriptableHelper;
1595 friend class nsDOMWindowUtils;
1596 friend class PostMessageEvent;
1597 friend class DesktopNotification;
1599 static WindowByIdTable* sWindowsById;
1600 static bool sWarnedAboutWindowInternal;
1601 };
1603 inline nsISupports*
1604 ToSupports(nsGlobalWindow *p)
1605 {
1606 return static_cast<nsIDOMEventTarget*>(p);
1607 }
1609 inline nsISupports*
1610 ToCanonicalSupports(nsGlobalWindow *p)
1611 {
1612 return static_cast<nsIDOMEventTarget*>(p);
1613 }
1615 /*
1616 * nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global
1617 * object created for a Chrome Window only.
1618 */
1619 class nsGlobalChromeWindow : public nsGlobalWindow,
1620 public nsIDOMChromeWindow
1621 {
1622 public:
1623 // nsISupports
1624 NS_DECL_ISUPPORTS_INHERITED
1626 // nsIDOMChromeWindow interface
1627 NS_DECL_NSIDOMCHROMEWINDOW
1629 nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
1630 : nsGlobalWindow(aOuterWindow)
1631 {
1632 mIsChrome = true;
1633 mCleanMessageManager = true;
1634 }
1636 ~nsGlobalChromeWindow()
1637 {
1638 NS_ABORT_IF_FALSE(mCleanMessageManager,
1639 "chrome windows may always disconnect the msg manager");
1640 if (mMessageManager) {
1641 static_cast<nsFrameMessageManager *>(
1642 mMessageManager.get())->Disconnect();
1643 }
1645 mCleanMessageManager = false;
1646 }
1648 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalChromeWindow,
1649 nsGlobalWindow)
1651 using nsGlobalWindow::GetBrowserDOMWindow;
1652 using nsGlobalWindow::SetBrowserDOMWindow;
1653 using nsGlobalWindow::GetAttention;
1654 using nsGlobalWindow::GetAttentionWithCycleCount;
1655 using nsGlobalWindow::SetCursor;
1656 using nsGlobalWindow::Maximize;
1657 using nsGlobalWindow::Minimize;
1658 using nsGlobalWindow::Restore;
1659 using nsGlobalWindow::NotifyDefaultButtonLoaded;
1660 using nsGlobalWindow::GetMessageManager;
1661 using nsGlobalWindow::BeginWindowMove;
1663 nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
1664 nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
1665 };
1667 /*
1668 * nsGlobalModalWindow inherits from nsGlobalWindow. It is the global
1669 * object created for a modal content windows only (i.e. not modal
1670 * chrome dialogs).
1671 */
1672 class nsGlobalModalWindow : public nsGlobalWindow,
1673 public nsIDOMModalContentWindow
1674 {
1675 public:
1676 nsGlobalModalWindow(nsGlobalWindow *aOuterWindow)
1677 : nsGlobalWindow(aOuterWindow)
1678 {
1679 mIsModalContentWindow = true;
1680 }
1682 NS_DECL_ISUPPORTS_INHERITED
1683 NS_DECL_NSIDOMMODALCONTENTWINDOW
1684 };
1686 /* factory function */
1687 inline already_AddRefed<nsGlobalWindow>
1688 NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow)
1689 {
1690 nsRefPtr<nsGlobalWindow> global;
1692 if (aIsChrome) {
1693 global = new nsGlobalChromeWindow(nullptr);
1694 } else if (aIsModalContentWindow) {
1695 global = new nsGlobalModalWindow(nullptr);
1696 } else {
1697 global = new nsGlobalWindow(nullptr);
1698 }
1700 return global.forget();
1701 }
1703 #endif /* nsGlobalWindow_h___ */