michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 sw=2 et tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsGlobalWindow_h___ michael@0: #define nsGlobalWindow_h___ michael@0: michael@0: #include "nsPIDOMWindow.h" michael@0: michael@0: #include "nsTHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsRefPtrHashtable.h" michael@0: michael@0: // Local Includes michael@0: // Helper Classes michael@0: #include "nsCOMPtr.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsWeakReference.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsJSThingHashtable.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: michael@0: // Interfaces Needed michael@0: #include "nsIBrowserDOMWindow.h" michael@0: #include "nsIDOMEventTarget.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIDOMJSWindow.h" michael@0: #include "nsIDOMChromeWindow.h" michael@0: #include "nsIScriptGlobalObject.h" michael@0: #include "nsIScriptObjectPrincipal.h" michael@0: #include "nsITimer.h" michael@0: #include "nsIDOMModalContentWindow.h" michael@0: #include "mozilla/EventListenerManager.h" michael@0: #include "nsIPrincipal.h" michael@0: #include "nsSize.h" michael@0: #include "mozFlushType.h" michael@0: #include "prclist.h" michael@0: #include "nsIDOMStorageEvent.h" michael@0: #include "nsFrameMessageManager.h" michael@0: #include "mozilla/LinkedList.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "nsIInlineEventHandlers.h" michael@0: #include "nsWrapperCacheInlines.h" michael@0: #include "nsIIdleObserver.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsIDOMTouchEvent.h" michael@0: #include "mozilla/dom/EventTarget.h" michael@0: #include "Units.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: michael@0: #ifdef MOZ_B2G michael@0: #include "nsIDOMWindowB2G.h" michael@0: #endif // MOZ_B2G michael@0: michael@0: #ifdef MOZ_WEBSPEECH michael@0: #include "nsISpeechSynthesisGetter.h" michael@0: #endif // MOZ_WEBSPEECH michael@0: michael@0: #define DEFAULT_HOME_PAGE "www.mozilla.org" michael@0: #define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage" michael@0: michael@0: // Amount of time allowed between alert/prompt/confirm before enabling michael@0: // the stop dialog checkbox. michael@0: #define DEFAULT_SUCCESSIVE_DIALOG_TIME_LIMIT 3 // 3 sec michael@0: michael@0: // Maximum number of successive dialogs before we prompt users to disable michael@0: // dialogs for this window. michael@0: #define MAX_SUCCESSIVE_DIALOG_COUNT 5 michael@0: michael@0: // Idle fuzz time upper limit michael@0: #define MAX_IDLE_FUZZ_TIME_MS 90000 michael@0: michael@0: // Min idle notification time in seconds. michael@0: #define MIN_IDLE_NOTIFICATION_TIME_S 1 michael@0: michael@0: class nsIArray; michael@0: class nsIBaseWindow; michael@0: class nsIContent; michael@0: class nsICSSDeclaration; michael@0: class nsIDocShellTreeOwner; michael@0: class nsIDOMCrypto; michael@0: class nsIDOMOfflineResourceList; michael@0: class nsIScrollableFrame; michael@0: class nsIControllers; michael@0: class nsIJSID; michael@0: class nsIScriptContext; michael@0: class nsIScriptTimeoutHandler; michael@0: class nsIWebBrowserChrome; michael@0: michael@0: class nsDOMWindowList; michael@0: class nsLocation; michael@0: class nsScreen; michael@0: class nsHistory; michael@0: class nsGlobalWindowObserver; michael@0: class nsGlobalWindow; michael@0: class nsDOMWindowUtils; michael@0: class nsIIdleService; michael@0: struct nsIntSize; michael@0: struct nsRect; michael@0: michael@0: class nsWindowSizes; michael@0: michael@0: namespace mozilla { michael@0: class DOMEventTargetHelper; michael@0: namespace dom { michael@0: class BarProp; michael@0: class Console; michael@0: class External; michael@0: class Function; michael@0: class Gamepad; michael@0: class MediaQueryList; michael@0: class Navigator; michael@0: class OwningExternalOrWindowProxy; michael@0: class Selection; michael@0: class SpeechSynthesis; michael@0: class WakeLock; michael@0: namespace indexedDB { michael@0: class IDBFactory; michael@0: } // namespace indexedDB michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: extern nsresult michael@0: NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, michael@0: bool *aIsInterval, michael@0: int32_t *aInterval, michael@0: nsIScriptTimeoutHandler **aRet); michael@0: michael@0: extern already_AddRefed michael@0: NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, michael@0: mozilla::dom::Function& aFunction, michael@0: const mozilla::dom::Sequence& aArguments, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: extern already_AddRefed michael@0: NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow, michael@0: const nsAString& aExpression, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: /* michael@0: * Timeout struct that holds information about each script michael@0: * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which michael@0: * abstracts the language specific cruft. michael@0: */ michael@0: struct nsTimeout : mozilla::LinkedListElement michael@0: { michael@0: nsTimeout(); michael@0: ~nsTimeout(); michael@0: michael@0: NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTimeout) michael@0: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsTimeout) michael@0: michael@0: nsresult InitTimer(nsTimerCallbackFunc aFunc, uint32_t aDelay) michael@0: { michael@0: return mTimer->InitWithFuncCallback(aFunc, this, aDelay, michael@0: nsITimer::TYPE_ONE_SHOT); michael@0: } michael@0: michael@0: bool HasRefCntOne(); michael@0: michael@0: // Window for which this timeout fires michael@0: nsRefPtr mWindow; michael@0: michael@0: // The actual timer object michael@0: nsCOMPtr mTimer; michael@0: michael@0: // True if the timeout was cleared michael@0: bool mCleared; michael@0: michael@0: // True if this is one of the timeouts that are currently running michael@0: bool mRunning; michael@0: michael@0: // True if this is a repeating/interval timer michael@0: bool mIsInterval; michael@0: michael@0: // Returned as value of setTimeout() michael@0: uint32_t mPublicId; michael@0: michael@0: // Interval in milliseconds michael@0: uint32_t mInterval; michael@0: michael@0: // mWhen and mTimeRemaining can't be in a union, sadly, because they michael@0: // have constructors. michael@0: // Nominal time to run this timeout. Use only when timeouts are not michael@0: // suspended. michael@0: mozilla::TimeStamp mWhen; michael@0: // Remaining time to wait. Used only when timeouts are suspended. michael@0: mozilla::TimeDuration mTimeRemaining; michael@0: michael@0: // Principal with which to execute michael@0: nsCOMPtr mPrincipal; michael@0: michael@0: // stack depth at which timeout is firing michael@0: uint32_t mFiringDepth; michael@0: michael@0: // michael@0: uint32_t mNestingLevel; michael@0: michael@0: // The popup state at timeout creation time if not created from michael@0: // another timeout michael@0: PopupControlState mPopupState; michael@0: michael@0: // The language-specific information about the callback. michael@0: nsCOMPtr mScriptHandler; michael@0: }; michael@0: michael@0: struct IdleObserverHolder michael@0: { michael@0: nsCOMPtr mIdleObserver; michael@0: uint32_t mTimeInS; michael@0: bool mPrevNotificationIdle; michael@0: michael@0: IdleObserverHolder() michael@0: : mTimeInS(0), mPrevNotificationIdle(false) michael@0: { michael@0: MOZ_COUNT_CTOR(IdleObserverHolder); michael@0: } michael@0: michael@0: IdleObserverHolder(const IdleObserverHolder& aOther) michael@0: : mIdleObserver(aOther.mIdleObserver), mTimeInS(aOther.mTimeInS), michael@0: mPrevNotificationIdle(aOther.mPrevNotificationIdle) michael@0: { michael@0: MOZ_COUNT_CTOR(IdleObserverHolder); michael@0: } michael@0: michael@0: bool operator==(const IdleObserverHolder& aOther) const { michael@0: return michael@0: mIdleObserver == aOther.mIdleObserver && michael@0: mTimeInS == aOther.mTimeInS; michael@0: } michael@0: michael@0: ~IdleObserverHolder() michael@0: { michael@0: MOZ_COUNT_DTOR(IdleObserverHolder); michael@0: } michael@0: }; michael@0: michael@0: static inline already_AddRefed michael@0: CreateVoidVariant() michael@0: { michael@0: nsCOMPtr writable = michael@0: do_CreateInstance(NS_VARIANT_CONTRACTID); michael@0: writable->SetAsVoid(); michael@0: return writable.forget(); michael@0: } michael@0: michael@0: // Helper class to manage modal dialog arguments and all their quirks. michael@0: // michael@0: // Given our clunky embedding APIs, modal dialog arguments need to be passed michael@0: // as an nsISupports parameter to WindowWatcher, get stuck inside an array of michael@0: // length 1, and then passed back to the newly-created dialog. michael@0: // michael@0: // However, we need to track both the caller-passed value as well as the michael@0: // caller's, so that we can do an origin check (even for primitives) when the michael@0: // value is accessed. This class encapsulates that magic. michael@0: // michael@0: // We also use the same machinery for |returnValue|, which needs similar origin michael@0: // checks. michael@0: class DialogValueHolder : public nsISupports michael@0: { michael@0: public: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_CLASS(DialogValueHolder) michael@0: michael@0: DialogValueHolder(nsIPrincipal* aSubject, nsIVariant* aValue) michael@0: : mOrigin(aSubject) michael@0: , mValue(aValue) {} michael@0: nsresult Get(nsIPrincipal* aSubject, nsIVariant** aResult) michael@0: { michael@0: nsCOMPtr result; michael@0: if (aSubject->SubsumesConsideringDomain(mOrigin)) { michael@0: result = mValue; michael@0: } else { michael@0: result = CreateVoidVariant(); michael@0: } michael@0: result.forget(aResult); michael@0: return NS_OK; michael@0: } michael@0: void Get(JSContext* aCx, JS::Handle aScope, nsIPrincipal* aSubject, michael@0: JS::MutableHandle aResult, mozilla::ErrorResult& aError) michael@0: { michael@0: if (aSubject->Subsumes(mOrigin)) { michael@0: aError = nsContentUtils::XPConnect()->VariantToJS(aCx, aScope, michael@0: mValue, aResult); michael@0: } else { michael@0: aResult.setUndefined(); michael@0: } michael@0: } michael@0: virtual ~DialogValueHolder() {} michael@0: private: michael@0: nsCOMPtr mOrigin; michael@0: nsCOMPtr mValue; michael@0: }; michael@0: michael@0: //***************************************************************************** michael@0: // nsGlobalWindow: Global Object for Scripting michael@0: //***************************************************************************** michael@0: // Beware that all scriptable interfaces implemented by michael@0: // nsGlobalWindow will be reachable from JS, if you make this class michael@0: // implement new interfaces you better know what you're michael@0: // doing. Security wise this is very sensitive code. -- michael@0: // jst@netscape.com michael@0: michael@0: // nsGlobalWindow inherits PRCList for maintaining a list of all inner michael@0: // windows still in memory for any given outer window. This list is michael@0: // needed to ensure that mOuterWindow doesn't end up dangling. The michael@0: // nature of PRCList means that the window itself is always in the michael@0: // list, and an outer window's list will also contain all inner window michael@0: // objects that are still in memory (and in reality all inner window michael@0: // object's lists also contain its outer and all other inner windows michael@0: // belonging to the same outer window, but that's an unimportant michael@0: // side effect of inheriting PRCList). michael@0: michael@0: class nsGlobalWindow : public mozilla::dom::EventTarget, michael@0: public nsPIDOMWindow, michael@0: public nsIScriptGlobalObject, michael@0: public nsIScriptObjectPrincipal, michael@0: public nsIDOMJSWindow, michael@0: public nsSupportsWeakReference, michael@0: public nsIInterfaceRequestor, michael@0: public PRCListStr, michael@0: public nsIDOMWindowPerformance, michael@0: public nsITouchEventReceiver, michael@0: public nsIInlineEventHandlers michael@0: #ifdef MOZ_B2G michael@0: , public nsIDOMWindowB2G michael@0: #endif // MOZ_B2G michael@0: #ifdef MOZ_WEBSPEECH michael@0: , public nsISpeechSynthesisGetter michael@0: #endif // MOZ_WEBSPEECH michael@0: { michael@0: public: michael@0: typedef mozilla::TimeStamp TimeStamp; michael@0: typedef mozilla::TimeDuration TimeDuration; michael@0: typedef nsDataHashtable WindowByIdTable; michael@0: michael@0: // public methods michael@0: nsPIDOMWindow* GetPrivateParent(); michael@0: // callback for close event michael@0: void ReallyCloseWindow(); michael@0: michael@0: // nsISupports michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: michael@0: // nsWrapperCache michael@0: virtual JSObject *WrapObject(JSContext *cx) MOZ_OVERRIDE michael@0: { michael@0: NS_ASSERTION(IsOuterWindow(), michael@0: "Inner window supports nsWrapperCache, fix WrapObject!"); michael@0: return EnsureInnerWindow() ? GetWrapper() : nullptr; michael@0: } michael@0: michael@0: // nsIGlobalJSObjectHolder michael@0: virtual JSObject *GetGlobalJSObject(); michael@0: michael@0: // nsIScriptGlobalObject michael@0: JSObject *FastGetGlobalJSObject() const michael@0: { michael@0: return GetWrapperPreserveColor(); michael@0: } michael@0: michael@0: void TraceGlobalJSObject(JSTracer* aTrc); michael@0: michael@0: virtual nsresult EnsureScriptEnvironment(); michael@0: michael@0: virtual nsIScriptContext *GetScriptContext(); michael@0: michael@0: void PoisonOuterWindowProxy(JSObject *aObject); michael@0: michael@0: virtual bool IsBlackForCC(bool aTracingNeeded = true); michael@0: michael@0: static JSObject* OuterObject(JSContext* aCx, JS::Handle aObj); michael@0: michael@0: // nsIScriptObjectPrincipal michael@0: virtual nsIPrincipal* GetPrincipal(); michael@0: michael@0: // nsIDOMWindow michael@0: NS_DECL_NSIDOMWINDOW michael@0: michael@0: #ifdef MOZ_B2G michael@0: // nsIDOMWindowB2G michael@0: NS_DECL_NSIDOMWINDOWB2G michael@0: #endif // MOZ_B2G michael@0: michael@0: #ifdef MOZ_WEBSPEECH michael@0: // nsISpeechSynthesisGetter michael@0: NS_DECL_NSISPEECHSYNTHESISGETTER michael@0: #endif // MOZ_WEBSPEECH michael@0: michael@0: // nsIDOMWindowPerformance michael@0: NS_DECL_NSIDOMWINDOWPERFORMANCE michael@0: michael@0: // nsIDOMJSWindow michael@0: NS_DECL_NSIDOMJSWINDOW michael@0: michael@0: // nsIDOMEventTarget michael@0: NS_DECL_NSIDOMEVENTTARGET michael@0: michael@0: virtual mozilla::EventListenerManager* michael@0: GetExistingListenerManager() const MOZ_OVERRIDE; michael@0: michael@0: virtual mozilla::EventListenerManager* michael@0: GetOrCreateListenerManager() MOZ_OVERRIDE; michael@0: michael@0: using mozilla::dom::EventTarget::RemoveEventListener; michael@0: virtual void AddEventListener(const nsAString& aType, michael@0: mozilla::dom::EventListener* aListener, michael@0: bool aUseCapture, michael@0: const mozilla::dom::Nullable& aWantsUntrusted, michael@0: mozilla::ErrorResult& aRv) MOZ_OVERRIDE; michael@0: virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE michael@0: { michael@0: if (IsOuterWindow()) { michael@0: return this; michael@0: } michael@0: michael@0: return GetOuterFromCurrentInner(this); michael@0: } michael@0: michael@0: // nsITouchEventReceiver michael@0: NS_DECL_NSITOUCHEVENTRECEIVER michael@0: michael@0: // nsIInlineEventHandlers michael@0: NS_DECL_NSIINLINEEVENTHANDLERS michael@0: michael@0: // nsPIDOMWindow michael@0: virtual NS_HIDDEN_(nsPIDOMWindow*) GetPrivateRoot(); michael@0: michael@0: // Outer windows only. michael@0: virtual NS_HIDDEN_(void) ActivateOrDeactivate(bool aActivate); michael@0: virtual NS_HIDDEN_(void) SetActive(bool aActive); michael@0: virtual NS_HIDDEN_(void) SetIsBackground(bool aIsBackground); michael@0: virtual NS_HIDDEN_(void) SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler); michael@0: michael@0: virtual NS_HIDDEN_(void) SetInitialPrincipalToSubject(); michael@0: michael@0: virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const; michael@0: virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const; michael@0: virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const; michael@0: michael@0: virtual already_AddRefed SaveWindowState(); michael@0: virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState); michael@0: virtual NS_HIDDEN_(void) SuspendTimeouts(uint32_t aIncrease = 1, michael@0: bool aFreezeChildren = true); michael@0: virtual NS_HIDDEN_(nsresult) ResumeTimeouts(bool aThawChildren = true); michael@0: virtual NS_HIDDEN_(uint32_t) TimeoutSuspendCount(); michael@0: virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents(); michael@0: virtual NS_HIDDEN_(bool) IsFrozen() const michael@0: { michael@0: return mIsFrozen; michael@0: } michael@0: virtual NS_HIDDEN_(bool) IsRunningTimeout() { return mTimeoutFiringDepth > 0; } michael@0: michael@0: virtual NS_HIDDEN_(bool) WouldReuseInnerWindow(nsIDocument *aNewDocument); michael@0: michael@0: virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell); michael@0: virtual void DetachFromDocShell(); michael@0: virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument, michael@0: nsISupports *aState, michael@0: bool aForceReuseInnerWindow); michael@0: void DispatchDOMWindowCreated(); michael@0: virtual NS_HIDDEN_(void) SetOpenerWindow(nsIDOMWindow* aOpener, michael@0: bool aOriginalOpener); michael@0: michael@0: // Outer windows only. michael@0: virtual NS_HIDDEN_(void) EnsureSizeUpToDate(); michael@0: michael@0: virtual NS_HIDDEN_(void) EnterModalState(); michael@0: virtual NS_HIDDEN_(void) LeaveModalState(); michael@0: michael@0: virtual NS_HIDDEN_(bool) CanClose(); michael@0: virtual NS_HIDDEN_(nsresult) ForceClose(); michael@0: michael@0: virtual NS_HIDDEN_(void) MaybeUpdateTouchState(); michael@0: virtual NS_HIDDEN_(void) UpdateTouchState(); michael@0: virtual NS_HIDDEN_(bool) DispatchCustomEvent(const char *aEventName); michael@0: virtual NS_HIDDEN_(bool) DispatchResizeEvent(const nsIntSize& aSize); michael@0: virtual NS_HIDDEN_(void) RefreshCompartmentPrincipal(); michael@0: virtual NS_HIDDEN_(nsresult) SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust); michael@0: michael@0: virtual NS_HIDDEN_(void) SetHasGamepadEventListener(bool aHasGamepad = true); michael@0: michael@0: // nsIInterfaceRequestor michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: michael@0: // WebIDL interface. michael@0: already_AddRefed IndexedGetter(uint32_t aIndex, bool& aFound); michael@0: michael@0: void GetSupportedNames(nsTArray& aNames); michael@0: michael@0: static bool IsChromeWindow(JSContext* /* unused */, JSObject* aObj); michael@0: michael@0: bool IsChrome() const; michael@0: michael@0: bool DoNewResolve(JSContext* aCx, JS::Handle aObj, michael@0: JS::Handle aId, michael@0: JS::MutableHandle aDesc); michael@0: michael@0: void GetOwnPropertyNames(JSContext* aCx, nsTArray& aNames, michael@0: mozilla::ErrorResult& aRv); michael@0: michael@0: // Object Management michael@0: nsGlobalWindow(nsGlobalWindow *aOuterWindow); michael@0: michael@0: static nsGlobalWindow *FromSupports(nsISupports *supports) michael@0: { michael@0: // Make sure this matches the casts we do in QueryInterface(). michael@0: return (nsGlobalWindow *)(mozilla::dom::EventTarget *)supports; michael@0: } michael@0: static nsGlobalWindow *FromWrapper(nsIXPConnectWrappedNative *wrapper) michael@0: { michael@0: return FromSupports(wrapper->Native()); michael@0: } michael@0: michael@0: /** michael@0: * Wrap nsIDOMWindow::GetTop so we can overload the inline GetTop() michael@0: * implementation below. (nsIDOMWindow::GetTop simply calls michael@0: * nsIDOMWindow::GetRealTop().) michael@0: */ michael@0: nsresult GetTop(nsIDOMWindow **aWindow) michael@0: { michael@0: return nsIDOMWindow::GetTop(aWindow); michael@0: } michael@0: michael@0: inline nsGlobalWindow *GetTop() michael@0: { michael@0: nsCOMPtr top; michael@0: GetTop(getter_AddRefs(top)); michael@0: if (top) michael@0: return static_cast(top.get()); michael@0: return nullptr; michael@0: } michael@0: michael@0: inline nsGlobalWindow* GetScriptableTop() michael@0: { michael@0: nsCOMPtr top; michael@0: GetScriptableTop(getter_AddRefs(top)); michael@0: return static_cast(top.get()); michael@0: } michael@0: michael@0: already_AddRefed GetChildWindow(const nsAString& aName); michael@0: michael@0: // These return true if we've reached the state in this top level window michael@0: // where we ask the user if further dialogs should be blocked. michael@0: // michael@0: // DialogsAreBeingAbused must be called on the scriptable top inner window. michael@0: // michael@0: // ShouldPromptToBlockDialogs is implemented in terms of michael@0: // DialogsAreBeingAbused, and will get the scriptable top inner window michael@0: // automatically. michael@0: // Outer windows only. michael@0: bool ShouldPromptToBlockDialogs(); michael@0: // Inner windows only. michael@0: bool DialogsAreBeingAbused(); michael@0: michael@0: // These functions are used for controlling and determining whether dialogs michael@0: // (alert, prompt, confirm) are currently allowed in this window. michael@0: void EnableDialogs(); michael@0: void DisableDialogs(); michael@0: bool AreDialogsEnabled(); michael@0: michael@0: nsIScriptContext *GetContextInternal() michael@0: { michael@0: if (mOuterWindow) { michael@0: return GetOuterWindowInternal()->mContext; michael@0: } michael@0: michael@0: return mContext; michael@0: } michael@0: michael@0: nsGlobalWindow *GetOuterWindowInternal() michael@0: { michael@0: return static_cast(GetOuterWindow()); michael@0: } michael@0: michael@0: nsGlobalWindow *GetCurrentInnerWindowInternal() const michael@0: { michael@0: return static_cast(mInnerWindow); michael@0: } michael@0: michael@0: nsGlobalWindow *EnsureInnerWindowInternal() michael@0: { michael@0: return static_cast(EnsureInnerWindow()); michael@0: } michael@0: michael@0: bool IsCreatingInnerWindow() const michael@0: { michael@0: return mCreatingInnerWindow; michael@0: } michael@0: michael@0: bool IsChromeWindow() const michael@0: { michael@0: return mIsChrome; michael@0: } michael@0: michael@0: using nsPIDOMWindow::IsModalContentWindow; michael@0: static bool IsModalContentWindow(JSContext* aCx, JSObject* aGlobal); michael@0: michael@0: // GetScrollFrame does not flush. Callers should do it themselves as needed, michael@0: // depending on which info they actually want off the scrollable frame. michael@0: nsIScrollableFrame *GetScrollFrame(); michael@0: michael@0: nsresult Observe(nsISupports* aSubject, const char* aTopic, michael@0: const char16_t* aData); michael@0: michael@0: // Outer windows only. michael@0: void UnblockScriptedClosing(); michael@0: michael@0: static void Init(); michael@0: static void ShutDown(); michael@0: static void CleanupCachedXBLHandlers(nsGlobalWindow* aWindow); michael@0: static bool IsCallerChrome(); michael@0: michael@0: static void RunPendingTimeoutsRecursive(nsGlobalWindow *aTopWindow, michael@0: nsGlobalWindow *aWindow); michael@0: michael@0: friend class WindowStateHolder; michael@0: michael@0: NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow, michael@0: nsIDOMEventTarget) michael@0: michael@0: #ifdef DEBUG michael@0: // Call Unlink on this window. This may cause bad things to happen, so use michael@0: // with caution. michael@0: void RiskyUnlink(); michael@0: #endif michael@0: michael@0: virtual NS_HIDDEN_(JSObject*) michael@0: GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey); michael@0: michael@0: virtual NS_HIDDEN_(void) michael@0: CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey, michael@0: JS::Handle aHandler); michael@0: michael@0: virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod); michael@0: virtual void SetReadyForFocus(); michael@0: virtual void PageHidden(); michael@0: virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, nsIURI *aNewURI); michael@0: virtual nsresult DispatchSyncPopState(); michael@0: michael@0: // Inner windows only. michael@0: virtual void EnableDeviceSensor(uint32_t aType); michael@0: virtual void DisableDeviceSensor(uint32_t aType); michael@0: michael@0: virtual void EnableTimeChangeNotifications(); michael@0: virtual void DisableTimeChangeNotifications(); michael@0: michael@0: #ifdef MOZ_B2G michael@0: // Inner windows only. michael@0: virtual void EnableNetworkEvent(uint32_t aType); michael@0: virtual void DisableNetworkEvent(uint32_t aType); michael@0: #endif // MOZ_B2G michael@0: michael@0: virtual nsresult SetArguments(nsIArray *aArguments); michael@0: michael@0: void MaybeForgiveSpamCount(); michael@0: bool IsClosedOrClosing() { michael@0: return (mIsClosed || michael@0: mInClose || michael@0: mHavePendingClose || michael@0: mCleanedUp); michael@0: } michael@0: michael@0: static void FirePopupBlockedEvent(nsIDocument* aDoc, michael@0: nsIDOMWindow *aRequestingWindow, nsIURI *aPopupURI, michael@0: const nsAString &aPopupWindowName, michael@0: const nsAString &aPopupWindowFeatures); michael@0: michael@0: virtual uint32_t GetSerial() { michael@0: return mSerial; michael@0: } michael@0: michael@0: static nsGlobalWindow* GetOuterWindowWithId(uint64_t aWindowID) { michael@0: if (!sWindowsById) { michael@0: return nullptr; michael@0: } michael@0: michael@0: nsGlobalWindow* outerWindow = sWindowsById->Get(aWindowID); michael@0: return outerWindow && !outerWindow->IsInnerWindow() ? outerWindow : nullptr; michael@0: } michael@0: michael@0: static nsGlobalWindow* GetInnerWindowWithId(uint64_t aInnerWindowID) { michael@0: if (!sWindowsById) { michael@0: return nullptr; michael@0: } michael@0: michael@0: nsGlobalWindow* innerWindow = sWindowsById->Get(aInnerWindowID); michael@0: return innerWindow && innerWindow->IsInnerWindow() ? innerWindow : nullptr; michael@0: } michael@0: michael@0: static WindowByIdTable* GetWindowsTable() { michael@0: return sWindowsById; michael@0: } michael@0: michael@0: void AddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const; michael@0: michael@0: void UnmarkGrayTimers(); michael@0: michael@0: void AddEventTargetObject(mozilla::DOMEventTargetHelper* aObject); michael@0: void RemoveEventTargetObject(mozilla::DOMEventTargetHelper* aObject); michael@0: michael@0: void NotifyIdleObserver(IdleObserverHolder* aIdleObserverHolder, michael@0: bool aCallOnidle); michael@0: nsresult HandleIdleActiveEvent(); michael@0: bool ContainsIdleObserver(nsIIdleObserver* aIdleObserver, uint32_t timeInS); michael@0: void HandleIdleObserverCallback(); michael@0: michael@0: void AllowScriptsToClose() michael@0: { michael@0: mAllowScriptsToClose = true; michael@0: } michael@0: michael@0: enum SlowScriptResponse { michael@0: ContinueSlowScript = 0, michael@0: AlwaysContinueSlowScript, michael@0: KillSlowScript michael@0: }; michael@0: SlowScriptResponse ShowSlowScriptDialog(); michael@0: michael@0: #ifdef MOZ_GAMEPAD michael@0: void AddGamepad(uint32_t aIndex, mozilla::dom::Gamepad* aGamepad); michael@0: void RemoveGamepad(uint32_t aIndex); michael@0: void GetGamepads(nsTArray >& aGamepads); michael@0: already_AddRefed GetGamepad(uint32_t aIndex); michael@0: void SetHasSeenGamepadInput(bool aHasSeen); michael@0: bool HasSeenGamepadInput(); michael@0: void SyncGamepadState(); michael@0: static PLDHashOperator EnumGamepadsForSync(const uint32_t& aKey, michael@0: mozilla::dom::Gamepad* aData, michael@0: void* aUserArg); michael@0: static PLDHashOperator EnumGamepadsForGet(const uint32_t& aKey, michael@0: mozilla::dom::Gamepad* aData, michael@0: void* aUserArg); michael@0: #endif michael@0: michael@0: // Enable/disable updates for gamepad input. michael@0: void EnableGamepadUpdates(); michael@0: void DisableGamepadUpdates(); michael@0: michael@0: michael@0: #define EVENT(name_, id_, type_, struct_) \ michael@0: mozilla::dom::EventHandlerNonNull* GetOn##name_() \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetExistingListenerManager(); \ michael@0: return elm ? elm->GetEventHandler(nsGkAtoms::on##name_, EmptyString()) \ michael@0: : nullptr; \ michael@0: } \ michael@0: void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler) \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \ michael@0: if (elm) { \ michael@0: elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler); \ michael@0: } \ michael@0: } michael@0: #define ERROR_EVENT(name_, id_, type_, struct_) \ michael@0: mozilla::dom::OnErrorEventHandlerNonNull* GetOn##name_() \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetExistingListenerManager(); \ michael@0: return elm ? elm->GetOnErrorEventHandler() : nullptr; \ michael@0: } \ michael@0: void SetOn##name_(mozilla::dom::OnErrorEventHandlerNonNull* handler) \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \ michael@0: if (elm) { \ michael@0: elm->SetEventHandler(handler); \ michael@0: } \ michael@0: } michael@0: #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_) \ michael@0: mozilla::dom::OnBeforeUnloadEventHandlerNonNull* GetOn##name_() \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetExistingListenerManager(); \ michael@0: return elm ? elm->GetOnBeforeUnloadEventHandler() : nullptr; \ michael@0: } \ michael@0: void SetOn##name_(mozilla::dom::OnBeforeUnloadEventHandlerNonNull* handler) \ michael@0: { \ michael@0: mozilla::EventListenerManager* elm = GetOrCreateListenerManager(); \ michael@0: if (elm) { \ michael@0: elm->SetEventHandler(handler); \ michael@0: } \ michael@0: } michael@0: #define WINDOW_ONLY_EVENT EVENT michael@0: #define TOUCH_EVENT EVENT michael@0: #include "mozilla/EventNameList.h" michael@0: #undef TOUCH_EVENT michael@0: #undef WINDOW_ONLY_EVENT michael@0: #undef BEFOREUNLOAD_EVENT michael@0: #undef ERROR_EVENT michael@0: #undef EVENT michael@0: michael@0: nsISupports* GetParentObject() michael@0: { michael@0: return nullptr; michael@0: } michael@0: michael@0: static bool WindowOnWebIDL(JSContext* /* unused */, JSObject* aObj); michael@0: michael@0: nsIDOMWindow* GetWindow(mozilla::ErrorResult& aError); michael@0: nsIDOMWindow* GetSelf(mozilla::ErrorResult& aError); michael@0: nsIDocument* GetDocument() michael@0: { michael@0: return GetDoc(); michael@0: } michael@0: void GetName(nsAString& aName, mozilla::ErrorResult& aError); michael@0: void SetName(const nsAString& aName, mozilla::ErrorResult& aError); michael@0: nsIDOMLocation* GetLocation(mozilla::ErrorResult& aError); michael@0: nsHistory* GetHistory(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetLocationbar(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetMenubar(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetPersonalbar(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetScrollbars(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetStatusbar(mozilla::ErrorResult& aError); michael@0: mozilla::dom::BarProp* GetToolbar(mozilla::ErrorResult& aError); michael@0: void GetStatus(nsAString& aStatus, mozilla::ErrorResult& aError); michael@0: void SetStatus(const nsAString& aStatus, mozilla::ErrorResult& aError); michael@0: void Close(mozilla::ErrorResult& aError); michael@0: bool GetClosed(mozilla::ErrorResult& aError); michael@0: void Stop(mozilla::ErrorResult& aError); michael@0: void Focus(mozilla::ErrorResult& aError); michael@0: void Blur(mozilla::ErrorResult& aError); michael@0: already_AddRefed GetFrames(mozilla::ErrorResult& aError); michael@0: uint32_t Length(); michael@0: already_AddRefed GetTop(mozilla::ErrorResult& aError) michael@0: { michael@0: nsCOMPtr top; michael@0: aError = GetScriptableTop(getter_AddRefs(top)); michael@0: return top.forget(); michael@0: } michael@0: protected: michael@0: nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError); michael@0: public: michael@0: void GetOpener(JSContext* aCx, JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError); michael@0: void SetOpener(JSContext* aCx, JS::Handle aOpener, michael@0: mozilla::ErrorResult& aError); michael@0: using nsIDOMWindow::GetParent; michael@0: already_AddRefed GetParent(mozilla::ErrorResult& aError); michael@0: mozilla::dom::Element* GetFrameElement(mozilla::ErrorResult& aError); michael@0: already_AddRefed Open(const nsAString& aUrl, michael@0: const nsAString& aName, michael@0: const nsAString& aOptions, michael@0: mozilla::ErrorResult& aError); michael@0: mozilla::dom::Navigator* GetNavigator(mozilla::ErrorResult& aError); michael@0: nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError); michael@0: michael@0: mozilla::dom::Console* GetConsole(mozilla::ErrorResult& aRv); michael@0: michael@0: void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult, michael@0: mozilla::ErrorResult& aRv); michael@0: already_AddRefed GetExternal(mozilla::ErrorResult& aRv); michael@0: michael@0: protected: michael@0: bool AlertOrConfirm(bool aAlert, const nsAString& aMessage, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: public: michael@0: void Alert(const nsAString& aMessage, mozilla::ErrorResult& aError); michael@0: bool Confirm(const nsAString& aMessage, mozilla::ErrorResult& aError); michael@0: void Prompt(const nsAString& aMessage, const nsAString& aInitial, michael@0: nsAString& aReturn, mozilla::ErrorResult& aError); michael@0: void Print(mozilla::ErrorResult& aError); michael@0: void ShowModalDialog(JSContext* aCx, const nsAString& aUrl, michael@0: JS::Handle aArgument, michael@0: const nsAString& aOptions, michael@0: JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError); michael@0: void PostMessageMoz(JSContext* aCx, JS::Handle aMessage, michael@0: const nsAString& aTargetOrigin, michael@0: const mozilla::dom::Optional >& aTransfer, michael@0: mozilla::ErrorResult& aError); michael@0: int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction, michael@0: int32_t aTimeout, michael@0: const mozilla::dom::Sequence& aArguments, michael@0: mozilla::ErrorResult& aError); michael@0: int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler, michael@0: int32_t aTimeout, michael@0: const mozilla::dom::Sequence& /* unused */, michael@0: mozilla::ErrorResult& aError); michael@0: void ClearTimeout(int32_t aHandle, mozilla::ErrorResult& aError); michael@0: int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction, michael@0: const mozilla::dom::Optional& aTimeout, michael@0: const mozilla::dom::Sequence& aArguments, michael@0: mozilla::ErrorResult& aError); michael@0: int32_t SetInterval(JSContext* aCx, const nsAString& aHandler, michael@0: const mozilla::dom::Optional& aTimeout, michael@0: const mozilla::dom::Sequence& /* unused */, michael@0: mozilla::ErrorResult& aError); michael@0: void ClearInterval(int32_t aHandle, mozilla::ErrorResult& aError); michael@0: void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData, michael@0: mozilla::ErrorResult& aError); michael@0: void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String, michael@0: mozilla::ErrorResult& aError); michael@0: nsIDOMStorage* GetSessionStorage(mozilla::ErrorResult& aError); michael@0: nsIDOMStorage* GetLocalStorage(mozilla::ErrorResult& aError); michael@0: mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError); michael@0: mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError); michael@0: already_AddRefed michael@0: GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt, michael@0: mozilla::ErrorResult& aError); michael@0: already_AddRefed MatchMedia(const nsAString& aQuery, michael@0: mozilla::ErrorResult& aError); michael@0: nsScreen* GetScreen(mozilla::ErrorResult& aError); michael@0: void MoveTo(int32_t aXPos, int32_t aYPos, mozilla::ErrorResult& aError); michael@0: void MoveBy(int32_t aXDif, int32_t aYDif, mozilla::ErrorResult& aError); michael@0: void ResizeTo(int32_t aWidth, int32_t aHeight, michael@0: mozilla::ErrorResult& aError); michael@0: void ResizeBy(int32_t aWidthDif, int32_t aHeightDif, michael@0: mozilla::ErrorResult& aError); michael@0: int32_t GetInnerWidth(mozilla::ErrorResult& aError); michael@0: void SetInnerWidth(int32_t aInnerWidth, mozilla::ErrorResult& aError); michael@0: int32_t GetInnerHeight(mozilla::ErrorResult& aError); michael@0: void SetInnerHeight(int32_t aInnerHeight, mozilla::ErrorResult& aError); michael@0: int32_t GetScrollX(mozilla::ErrorResult& aError); michael@0: int32_t GetPageXOffset(mozilla::ErrorResult& aError) michael@0: { michael@0: return GetScrollX(aError); michael@0: } michael@0: int32_t GetScrollY(mozilla::ErrorResult& aError); michael@0: int32_t GetPageYOffset(mozilla::ErrorResult& aError) michael@0: { michael@0: return GetScrollY(aError); michael@0: } michael@0: int32_t GetScreenX(mozilla::ErrorResult& aError); michael@0: void SetScreenX(int32_t aScreenX, mozilla::ErrorResult& aError); michael@0: int32_t GetScreenY(mozilla::ErrorResult& aError); michael@0: void SetScreenY(int32_t aScreenY, mozilla::ErrorResult& aError); michael@0: int32_t GetOuterWidth(mozilla::ErrorResult& aError); michael@0: void SetOuterWidth(int32_t aOuterWidth, mozilla::ErrorResult& aError); michael@0: int32_t GetOuterHeight(mozilla::ErrorResult& aError); michael@0: void SetOuterHeight(int32_t aOuterHeight, mozilla::ErrorResult& aError); michael@0: int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback, michael@0: mozilla::ErrorResult& aError); michael@0: void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError); michael@0: nsPerformance* GetPerformance(mozilla::ErrorResult& aError); michael@0: nsresult GetFirstPartyIsolationURI(nsIURI** aFirstPartyIsolationURI); michael@0: michael@0: #ifdef MOZ_WEBSPEECH michael@0: mozilla::dom::SpeechSynthesis* michael@0: GetSpeechSynthesis(mozilla::ErrorResult& aError); michael@0: #endif michael@0: already_AddRefed michael@0: GetDefaultComputedStyle(mozilla::dom::Element& aElt, michael@0: const nsAString& aPseudoElt, michael@0: mozilla::ErrorResult& aError); michael@0: mozilla::dom::indexedDB::IDBFactory* michael@0: GetMozIndexedDB(mozilla::ErrorResult& aError) michael@0: { michael@0: return GetIndexedDB(aError); michael@0: } michael@0: int32_t MozRequestAnimationFrame(nsIFrameRequestCallback* aRequestCallback, michael@0: mozilla::ErrorResult& aError); michael@0: void MozCancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError) michael@0: { michael@0: return CancelAnimationFrame(aHandle, aError); michael@0: } michael@0: void MozCancelRequestAnimationFrame(int32_t aHandle, michael@0: mozilla::ErrorResult& aError) michael@0: { michael@0: return CancelAnimationFrame(aHandle, aError); michael@0: } michael@0: int64_t GetMozAnimationStartTime(mozilla::ErrorResult& aError); michael@0: void SizeToContent(mozilla::ErrorResult& aError); michael@0: nsIDOMCrypto* GetCrypto(mozilla::ErrorResult& aError); michael@0: nsIControllers* GetControllers(mozilla::ErrorResult& aError); michael@0: float GetMozInnerScreenX(mozilla::ErrorResult& aError); michael@0: float GetMozInnerScreenY(mozilla::ErrorResult& aError); michael@0: float GetDevicePixelRatio(mozilla::ErrorResult& aError); michael@0: int32_t GetScrollMaxX(mozilla::ErrorResult& aError); michael@0: int32_t GetScrollMaxY(mozilla::ErrorResult& aError); michael@0: bool GetFullScreen(mozilla::ErrorResult& aError); michael@0: void SetFullScreen(bool aFullScreen, mozilla::ErrorResult& aError); michael@0: void Back(mozilla::ErrorResult& aError); michael@0: void Forward(mozilla::ErrorResult& aError); michael@0: void Home(mozilla::ErrorResult& aError); michael@0: bool Find(const nsAString& aString, bool aCaseSensitive, bool aBackwards, michael@0: bool aWrapAround, bool aWholeWord, bool aSearchInFrames, michael@0: bool aShowDialog, mozilla::ErrorResult& aError); michael@0: uint64_t GetMozPaintCount(mozilla::ErrorResult& aError); michael@0: already_AddRefed OpenDialog(JSContext* aCx, michael@0: const nsAString& aUrl, michael@0: const nsAString& aName, michael@0: const nsAString& aOptions, michael@0: const mozilla::dom::Sequence& aExtraArgument, michael@0: mozilla::ErrorResult& aError); michael@0: void GetContent(JSContext* aCx, michael@0: JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError); michael@0: void Get_content(JSContext* aCx, michael@0: JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError) michael@0: { michael@0: if (mDoc) { michael@0: mDoc->WarnOnceAbout(nsIDocument::eWindow_Content); michael@0: } michael@0: GetContent(aCx, aRetval, aError); michael@0: } michael@0: michael@0: // ChromeWindow bits. Do NOT call these unless your window is in michael@0: // fact an nsGlobalChromeWindow. michael@0: uint16_t WindowState(); michael@0: nsIBrowserDOMWindow* GetBrowserDOMWindow(mozilla::ErrorResult& aError); michael@0: void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow, michael@0: mozilla::ErrorResult& aError); michael@0: void GetAttention(mozilla::ErrorResult& aError); michael@0: void GetAttentionWithCycleCount(int32_t aCycleCount, michael@0: mozilla::ErrorResult& aError); michael@0: void SetCursor(const nsAString& aCursor, mozilla::ErrorResult& aError); michael@0: void Maximize(mozilla::ErrorResult& aError); michael@0: void Minimize(mozilla::ErrorResult& aError); michael@0: void Restore(mozilla::ErrorResult& aError); michael@0: void NotifyDefaultButtonLoaded(mozilla::dom::Element& aDefaultButton, michael@0: mozilla::ErrorResult& aError); michael@0: nsIMessageBroadcaster* GetMessageManager(mozilla::ErrorResult& aError); michael@0: void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent, michael@0: mozilla::dom::Element* aPanel, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: void GetDialogArguments(JSContext* aCx, JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError); michael@0: void GetReturnValue(JSContext* aCx, JS::MutableHandle aReturnValue, michael@0: mozilla::ErrorResult& aError); michael@0: void SetReturnValue(JSContext* aCx, JS::Handle aReturnValue, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: void GetInterface(JSContext* aCx, nsIJSID* aIID, michael@0: JS::MutableHandle aRetval, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: protected: michael@0: // Array of idle observers that are notified of idle events. michael@0: nsTObserverArray mIdleObservers; michael@0: michael@0: // Idle timer used for function callbacks to notify idle observers. michael@0: nsCOMPtr mIdleTimer; michael@0: michael@0: // Idle fuzz time added to idle timer callbacks. michael@0: uint32_t mIdleFuzzFactor; michael@0: michael@0: // Index in mArrayIdleObservers michael@0: // Next idle observer to notify user idle status michael@0: int32_t mIdleCallbackIndex; michael@0: michael@0: // If false then the topic is "active" michael@0: // If true then the topic is "idle" michael@0: bool mCurrentlyIdle; michael@0: michael@0: // Set to true when a fuzz time needs to be applied michael@0: // to active notifications to the idle observer. michael@0: bool mAddActiveEventFuzzTime; michael@0: michael@0: nsCOMPtr mIdleService; michael@0: michael@0: nsRefPtr mWakeLock; michael@0: michael@0: static bool sIdleObserversAPIFuzzTimeDisabled; michael@0: michael@0: friend class HashchangeCallback; michael@0: friend class mozilla::dom::BarProp; michael@0: michael@0: // Object Management michael@0: virtual ~nsGlobalWindow(); michael@0: void DropOuterWindowDocs(); michael@0: void CleanUp(); michael@0: void ClearControllers(); michael@0: nsresult FinalClose(); michael@0: michael@0: inline void MaybeClearInnerWindow(nsGlobalWindow* aExpectedInner) michael@0: { michael@0: if(mInnerWindow == aExpectedInner) { michael@0: mInnerWindow = nullptr; michael@0: } michael@0: } michael@0: michael@0: void FreeInnerObjects(); michael@0: JSObject *CallerGlobal(); michael@0: nsGlobalWindow *CallerInnerWindow(); michael@0: michael@0: // Only to be called on an inner window. michael@0: // aDocument must not be null. michael@0: void InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument); michael@0: michael@0: nsresult DefineArgumentsProperty(nsIArray *aArguments); michael@0: michael@0: // Get the parent, returns null if this is a toplevel window michael@0: nsIDOMWindow* GetParentInternal(); michael@0: michael@0: // popup tracking michael@0: bool IsPopupSpamWindow() michael@0: { michael@0: if (IsInnerWindow() && !mOuterWindow) { michael@0: return false; michael@0: } michael@0: michael@0: return GetOuterWindowInternal()->mIsPopupSpam; michael@0: } michael@0: michael@0: void SetPopupSpamWindow(bool aPopup) michael@0: { michael@0: if (IsInnerWindow() && !mOuterWindow) { michael@0: NS_ERROR("SetPopupSpamWindow() called on inner window w/o an outer!"); michael@0: michael@0: return; michael@0: } michael@0: michael@0: GetOuterWindowInternal()->mIsPopupSpam = aPopup; michael@0: } michael@0: michael@0: // Window Control Functions michael@0: michael@0: virtual nsresult michael@0: OpenNoNavigate(const nsAString& aUrl, michael@0: const nsAString& aName, michael@0: const nsAString& aOptions, michael@0: nsIDOMWindow **_retval); michael@0: michael@0: /** michael@0: * @param aUrl the URL we intend to load into the window. If aNavigate is michael@0: * true, we'll actually load this URL into the window. Otherwise, michael@0: * aUrl is advisory; OpenInternal will not load the URL into the michael@0: * new window. michael@0: * michael@0: * @param aName the name to use for the new window michael@0: * michael@0: * @param aOptions the window options to use for the new window michael@0: * michael@0: * @param aDialog true when called from variants of OpenDialog. If this is michael@0: * true, this method will skip popup blocking checks. The aDialog michael@0: * argument is passed on to the window watcher. michael@0: * michael@0: * @param aCalledNoScript true when called via the [noscript] open() michael@0: * and openDialog() methods. When this is true, we do NOT want to use michael@0: * the JS stack for things like caller determination. michael@0: * michael@0: * @param aDoJSFixups true when this is the content-accessible JS version of michael@0: * window opening. When true, popups do not cause us to throw, we save michael@0: * the caller's principal in the new window for later consumption, and michael@0: * we make sure that there is a document in the newly-opened window. michael@0: * Note that this last will only be done if the newly-opened window is michael@0: * non-chrome. michael@0: * michael@0: * @param aNavigate true if we should navigate to the provided URL, false michael@0: * otherwise. When aNavigate is false, we also skip our can-load michael@0: * security check, on the assumption that whoever *actually* loads this michael@0: * page will do their own security check. michael@0: * michael@0: * @param argv The arguments to pass to the new window. The first michael@0: * three args, if present, will be aUrl, aName, and aOptions. So this michael@0: * param only matters if there are more than 3 arguments. michael@0: * michael@0: * @param argc The number of arguments in argv. michael@0: * michael@0: * @param aExtraArgument Another way to pass arguments in. This is mutually michael@0: * exclusive with the argv/argc approach. michael@0: * michael@0: * @param aJSCallerContext The calling script's context. This must be null michael@0: * when aCalledNoScript is true. michael@0: * michael@0: * @param aReturn [out] The window that was opened, if any. michael@0: */ michael@0: NS_HIDDEN_(nsresult) OpenInternal(const nsAString& aUrl, michael@0: const nsAString& aName, michael@0: const nsAString& aOptions, michael@0: bool aDialog, michael@0: bool aContentModal, michael@0: bool aCalledNoScript, michael@0: bool aDoJSFixups, michael@0: bool aNavigate, michael@0: nsIArray *argv, michael@0: nsISupports *aExtraArgument, michael@0: nsIPrincipal *aCalleePrincipal, michael@0: JSContext *aJSCallerContext, michael@0: nsIDOMWindow **aReturn); michael@0: michael@0: // Timeout Functions michael@0: // Language agnostic timeout function (all args passed). michael@0: // |interval| is in milliseconds. michael@0: nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler, michael@0: int32_t interval, michael@0: bool aIsInterval, int32_t *aReturn); michael@0: int32_t SetTimeoutOrInterval(mozilla::dom::Function& aFunction, michael@0: int32_t aTimeout, michael@0: const mozilla::dom::Sequence& aArguments, michael@0: bool aIsInterval, mozilla::ErrorResult& aError); michael@0: int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler, michael@0: int32_t aTimeout, bool aIsInterval, michael@0: mozilla::ErrorResult& aError); michael@0: void ClearTimeoutOrInterval(int32_t aTimerID, michael@0: mozilla::ErrorResult& aError); michael@0: nsresult ClearTimeoutOrInterval(int32_t aTimerID) michael@0: { michael@0: mozilla::ErrorResult rv; michael@0: ClearTimeoutOrInterval(aTimerID, rv); michael@0: return rv.ErrorCode(); michael@0: } michael@0: michael@0: // JS specific timeout functions (JS args grabbed from context). michael@0: nsresult SetTimeoutOrInterval(bool aIsInterval, int32_t* aReturn); michael@0: nsresult ResetTimersForNonBackgroundWindow(); michael@0: michael@0: // The timeout implementation functions. michael@0: void RunTimeout(nsTimeout *aTimeout); michael@0: void RunTimeout() { RunTimeout(nullptr); } michael@0: // Return true if |aTimeout| was cleared while its handler ran. michael@0: bool RunTimeoutHandler(nsTimeout* aTimeout, nsIScriptContext* aScx); michael@0: // Return true if |aTimeout| needs to be reinserted into the timeout list. michael@0: bool RescheduleTimeout(nsTimeout* aTimeout, const TimeStamp& now, michael@0: bool aRunningPendingTimeouts); michael@0: michael@0: void ClearAllTimeouts(); michael@0: // Insert aTimeout into the list, before all timeouts that would michael@0: // fire after it, but no earlier than mTimeoutInsertionPoint, if any. michael@0: void InsertTimeoutIntoList(nsTimeout *aTimeout); michael@0: static void TimerCallback(nsITimer *aTimer, void *aClosure); michael@0: michael@0: // Helper Functions michael@0: already_AddRefed GetTreeOwner(); michael@0: already_AddRefed GetTreeOwnerWindow(); michael@0: already_AddRefed GetWebBrowserChrome(); michael@0: nsresult SecurityCheckURL(const char *aURL); michael@0: michael@0: bool PopupWhitelisted(); michael@0: PopupControlState RevisePopupAbuseLevel(PopupControlState); michael@0: void FireAbuseEvents(bool aBlocked, bool aWindow, michael@0: const nsAString &aPopupURL, michael@0: const nsAString &aPopupWindowName, michael@0: const nsAString &aPopupWindowFeatures); michael@0: void FireOfflineStatusEvent(); michael@0: michael@0: // Inner windows only. michael@0: nsresult ScheduleNextIdleObserverCallback(); michael@0: uint32_t GetFuzzTimeMS(); michael@0: nsresult ScheduleActiveTimerCallback(); michael@0: uint32_t FindInsertionIndex(IdleObserverHolder* aIdleObserver); michael@0: virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserverPtr); michael@0: nsresult FindIndexOfElementToRemove(nsIIdleObserver* aIdleObserver, michael@0: int32_t* aRemoveElementIndex); michael@0: virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserverPtr); michael@0: michael@0: // Inner windows only. michael@0: nsresult FireHashchange(const nsAString &aOldURL, const nsAString &aNewURL); michael@0: michael@0: void FlushPendingNotifications(mozFlushType aType); michael@0: michael@0: // Outer windows only. michael@0: void EnsureReflowFlushAndPaint(); michael@0: void CheckSecurityWidthAndHeight(int32_t* width, int32_t* height); michael@0: void CheckSecurityLeftAndTop(int32_t* left, int32_t* top); michael@0: michael@0: // Outer windows only. michael@0: // Arguments to this function should have values in app units michael@0: void SetCSSViewportWidthAndHeight(nscoord width, nscoord height); michael@0: // Arguments to this function should have values in device pixels michael@0: nsresult SetDocShellWidthAndHeight(int32_t width, int32_t height); michael@0: michael@0: static bool CanSetProperty(const char *aPrefName); michael@0: michael@0: static void MakeScriptDialogTitle(nsAString &aOutTitle); michael@0: michael@0: // Outer windows only. michael@0: bool CanMoveResizeWindows(); michael@0: michael@0: // If aDoFlush is true, we'll flush our own layout; otherwise we'll try to michael@0: // just flush our parent and only flush ourselves if we think we need to. michael@0: mozilla::CSSIntPoint GetScrollXY(bool aDoFlush, mozilla::ErrorResult& aError); michael@0: nsresult GetScrollXY(int32_t* aScrollX, int32_t* aScrollY, bool aDoFlush); michael@0: void GetScrollMaxXY(int32_t* aScrollMaxX, int32_t* aScrollMaxY, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: // Outer windows only. michael@0: nsresult GetInnerSize(mozilla::CSSIntSize& aSize); michael@0: nsIntSize GetOuterSize(mozilla::ErrorResult& aError); michael@0: void SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth, michael@0: mozilla::ErrorResult& aError); michael@0: nsRect GetInnerScreenRect(); michael@0: michael@0: void ScrollTo(const mozilla::CSSIntPoint& aScroll); michael@0: michael@0: bool IsFrame() michael@0: { michael@0: return GetParentInternal() != nullptr; michael@0: } michael@0: michael@0: // Outer windows only. michael@0: // If aLookForCallerOnJSStack is true, this method will look at the JS stack michael@0: // to determine who the caller is. If it's false, it'll use |this| as the michael@0: // caller. michael@0: bool WindowExists(const nsAString& aName, bool aLookForCallerOnJSStack); michael@0: michael@0: already_AddRefed GetMainWidget(); michael@0: nsIWidget* GetNearestWidget(); michael@0: michael@0: void Freeze() michael@0: { michael@0: NS_ASSERTION(!IsFrozen(), "Double-freezing?"); michael@0: mIsFrozen = true; michael@0: NotifyDOMWindowFrozen(this); michael@0: } michael@0: michael@0: void Thaw() michael@0: { michael@0: mIsFrozen = false; michael@0: NotifyDOMWindowThawed(this); michael@0: } michael@0: michael@0: bool IsInModalState(); michael@0: michael@0: // Convenience functions for the many methods that need to scale michael@0: // from device to CSS pixels or vice versa. Note: if a presentation michael@0: // context is not available, they will assume a 1:1 ratio. michael@0: int32_t DevToCSSIntPixels(int32_t px); michael@0: int32_t CSSToDevIntPixels(int32_t px); michael@0: nsIntSize DevToCSSIntPixels(nsIntSize px); michael@0: nsIntSize CSSToDevIntPixels(nsIntSize px); michael@0: michael@0: virtual void SetFocusedNode(nsIContent* aNode, michael@0: uint32_t aFocusMethod = 0, michael@0: bool aNeedsFocus = false); michael@0: michael@0: virtual uint32_t GetFocusMethod(); michael@0: michael@0: virtual bool ShouldShowFocusRing(); michael@0: michael@0: virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators, michael@0: UIStateChangeType aShowFocusRings); michael@0: virtual void GetKeyboardIndicators(bool* aShowAccelerators, michael@0: bool* aShowFocusRings); michael@0: michael@0: // Inner windows only. michael@0: void UpdateCanvasFocus(bool aFocusChanged, nsIContent* aNewContent); michael@0: michael@0: public: michael@0: virtual already_AddRefed GetTopWindowRoot() MOZ_OVERRIDE; michael@0: michael@0: protected: michael@0: static void NotifyDOMWindowDestroyed(nsGlobalWindow* aWindow); michael@0: void NotifyWindowIDDestroyed(const char* aTopic); michael@0: michael@0: static void NotifyDOMWindowFrozen(nsGlobalWindow* aWindow); michael@0: static void NotifyDOMWindowThawed(nsGlobalWindow* aWindow); michael@0: michael@0: void ClearStatus(); michael@0: michael@0: virtual void UpdateParentTarget(); michael@0: michael@0: inline int32_t DOMMinTimeoutValue() const; michael@0: michael@0: nsresult CloneStorageEvent(const nsAString& aType, michael@0: nsCOMPtr& aEvent); michael@0: michael@0: // Outer windows only. michael@0: nsDOMWindowList* GetWindowList(); michael@0: michael@0: // Helper for getComputedStyle and getDefaultComputedStyle michael@0: already_AddRefed michael@0: GetComputedStyleHelper(mozilla::dom::Element& aElt, michael@0: const nsAString& aPseudoElt, michael@0: bool aDefaultStylesOnly, michael@0: mozilla::ErrorResult& aError); michael@0: nsresult GetComputedStyleHelper(nsIDOMElement* aElt, michael@0: const nsAString& aPseudoElt, michael@0: bool aDefaultStylesOnly, michael@0: nsIDOMCSSStyleDeclaration** aReturn); michael@0: michael@0: void PreloadLocalStorage(); michael@0: michael@0: // Returns device pixels. Outer windows only. michael@0: nsIntPoint GetScreenXY(mozilla::ErrorResult& aError); michael@0: michael@0: int32_t RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: nsGlobalWindow* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError); michael@0: michael@0: mozilla::dom::Element* GetRealFrameElement(mozilla::ErrorResult& aError); michael@0: michael@0: void PostMessageMoz(JSContext* aCx, JS::Handle aMessage, michael@0: const nsAString& aTargetOrigin, michael@0: JS::Handle aTransfer, michael@0: mozilla::ErrorResult& aError); michael@0: michael@0: already_AddRefed michael@0: ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument, michael@0: const nsAString& aOptions, mozilla::ErrorResult& aError); michael@0: michael@0: already_AddRefed michael@0: GetContentInternal(mozilla::ErrorResult& aError); michael@0: michael@0: // Ask the user if further dialogs should be blocked, if dialogs are currently michael@0: // being abused. This is used in the cases where we have no modifiable UI to michael@0: // show, in that case we show a separate dialog to ask this question. michael@0: bool ConfirmDialogIfNeeded(); michael@0: michael@0: // When adding new member variables, be careful not to create cycles michael@0: // through JavaScript. If there is any chance that a member variable michael@0: // could own objects that are implemented in JavaScript, then those michael@0: // objects will keep the global object (this object) alive. To prevent michael@0: // these cycles, ownership of such members must be released in michael@0: // |CleanUp| and |DetachFromDocShell|. michael@0: michael@0: // This member is also used on both inner and outer windows, but michael@0: // for slightly different purposes. On inner windows it means the michael@0: // inner window is held onto by session history and should not michael@0: // change. On outer windows it means that the window is in a state michael@0: // where we don't want to force creation of a new inner window since michael@0: // we're in the middle of doing just that. michael@0: bool mIsFrozen : 1; michael@0: michael@0: // These members are only used on outer window objects. Make sure michael@0: // you never set any of these on an inner object! michael@0: bool mFullScreen : 1; michael@0: bool mIsClosed : 1; michael@0: bool mInClose : 1; michael@0: // mHavePendingClose means we've got a termination function set to michael@0: // close us when the JS stops executing or that we have a close michael@0: // event posted. If this is set, just ignore window.close() calls. michael@0: bool mHavePendingClose : 1; michael@0: bool mHadOriginalOpener : 1; michael@0: bool mIsPopupSpam : 1; michael@0: michael@0: // Indicates whether scripts are allowed to close this window. michael@0: bool mBlockScriptedClosingFlag : 1; michael@0: michael@0: // Track what sorts of events we need to fire when thawed michael@0: bool mFireOfflineStatusChangeEventOnThaw : 1; michael@0: bool mNotifyIdleObserversIdleOnThaw : 1; michael@0: bool mNotifyIdleObserversActiveOnThaw : 1; michael@0: michael@0: // Indicates whether we're in the middle of creating an initializing michael@0: // a new inner window object. michael@0: bool mCreatingInnerWindow : 1; michael@0: michael@0: // Fast way to tell if this is a chrome window (without having to QI). michael@0: bool mIsChrome : 1; michael@0: michael@0: // Hack to indicate whether a chrome window needs its message manager michael@0: // to be disconnected, since clean up code is shared in the global michael@0: // window superclass. michael@0: bool mCleanMessageManager : 1; michael@0: michael@0: // Indicates that the current document has never received a document focus michael@0: // event. michael@0: bool mNeedsFocus : 1; michael@0: bool mHasFocus : 1; michael@0: michael@0: // whether to show keyboard accelerators michael@0: bool mShowAccelerators : 1; michael@0: michael@0: // whether to show focus rings michael@0: bool mShowFocusRings : 1; michael@0: michael@0: // when true, show focus rings for the current focused content only. michael@0: // This will be reset when another element is focused michael@0: bool mShowFocusRingForContent : 1; michael@0: michael@0: // true if tab navigation has occurred for this window. Focus rings michael@0: // should be displayed. michael@0: bool mFocusByKeyOccurred : 1; michael@0: michael@0: // Ensure that a call to ResumeTimeouts() after FreeInnerObjects() does nothing. michael@0: // This member is only used by inner windows. michael@0: bool mInnerObjectsFreed : 1; michael@0: michael@0: // Indicates whether this window wants gamepad input events michael@0: bool mHasGamepad : 1; michael@0: #ifdef MOZ_GAMEPAD michael@0: nsRefPtrHashtable mGamepads; michael@0: bool mHasSeenGamepadInput; michael@0: #endif michael@0: michael@0: // whether we've sent the destroy notification for our window id michael@0: bool mNotifiedIDDestroyed : 1; michael@0: // whether scripts may close the window, michael@0: // even if "dom.allow_scripts_to_close_windows" is false. michael@0: bool mAllowScriptsToClose : 1; michael@0: michael@0: nsCOMPtr mContext; michael@0: nsWeakPtr mOpener; michael@0: nsCOMPtr mControllers; michael@0: michael@0: // For |window.arguments|, via |openDialog|. michael@0: nsCOMPtr mArguments; michael@0: michael@0: // For |window.dialogArguments|, via |showModalDialog|. michael@0: nsRefPtr mDialogArguments; michael@0: michael@0: // Only used in the outer. michael@0: nsRefPtr mReturnValue; michael@0: michael@0: nsRefPtr mNavigator; michael@0: nsRefPtr mScreen; michael@0: nsRefPtr mFrames; michael@0: nsRefPtr mMenubar; michael@0: nsRefPtr mToolbar; michael@0: nsRefPtr mLocationbar; michael@0: nsRefPtr mPersonalbar; michael@0: nsRefPtr mStatusbar; michael@0: nsRefPtr mScrollbars; michael@0: nsRefPtr mWindowUtils; michael@0: nsString mStatus; michael@0: nsString mDefaultStatus; michael@0: nsGlobalWindowObserver* mObserver; // Inner windows only. michael@0: nsCOMPtr mCrypto; michael@0: nsRefPtr mConsole; michael@0: // We need to store an nsISupports pointer to this object because the michael@0: // mozilla::dom::External class doesn't exist on b2g and using the type michael@0: // forward declared here means that ~nsGlobalWindow wouldn't compile because michael@0: // it wouldn't see the ~External function's declaration. michael@0: nsCOMPtr mExternal; michael@0: michael@0: nsCOMPtr mLocalStorage; michael@0: nsCOMPtr mSessionStorage; michael@0: michael@0: // These member variable are used only on inner windows. michael@0: nsRefPtr mListenerManager; michael@0: // mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is michael@0: // non-null. In that case, the dummy timeout pointed to by michael@0: // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts michael@0: // that come after it. michael@0: mozilla::LinkedList mTimeouts; michael@0: // If mTimeoutInsertionPoint is non-null, insertions should happen after it. michael@0: // This is a dummy timeout at the moment; if that ever changes, the logic in michael@0: // ResetTimersForNonBackgroundWindow needs to change. michael@0: nsTimeout* mTimeoutInsertionPoint; michael@0: uint32_t mTimeoutPublicIdCounter; michael@0: uint32_t mTimeoutFiringDepth; michael@0: nsRefPtr mLocation; michael@0: nsRefPtr mHistory; michael@0: michael@0: // These member variables are used on both inner and the outer windows. michael@0: nsCOMPtr mDocumentPrincipal; michael@0: michael@0: typedef nsCOMArray nsDOMStorageEventArray; michael@0: nsDOMStorageEventArray mPendingStorageEvents; michael@0: michael@0: uint32_t mTimeoutsSuspendDepth; michael@0: michael@0: // the method that was used to focus mFocusedNode michael@0: uint32_t mFocusMethod; michael@0: michael@0: uint32_t mSerial; michael@0: michael@0: #ifdef DEBUG michael@0: bool mSetOpenerWindowCalled; michael@0: nsCOMPtr mLastOpenedURI; michael@0: #endif michael@0: michael@0: #ifdef MOZ_B2G michael@0: bool mNetworkUploadObserverEnabled; michael@0: bool mNetworkDownloadObserverEnabled; michael@0: #endif // MOZ_B2G michael@0: michael@0: bool mCleanedUp; michael@0: michael@0: nsCOMPtr mApplicationCache; michael@0: michael@0: nsAutoPtr, JSObject*> > mCachedXBLPrototypeHandlers; michael@0: michael@0: // mSuspendedDoc is only set on outer windows. It's useful when we get matched michael@0: // EnterModalState/LeaveModalState calls, in which case the outer window is michael@0: // responsible for unsuspending events on the document. If we don't (for michael@0: // example, if the outer window is closed before the LeaveModalState call), michael@0: // then the inner window whose mDoc is our mSuspendedDoc is responsible for michael@0: // unsuspending it. michael@0: nsCOMPtr mSuspendedDoc; michael@0: michael@0: nsRefPtr mIndexedDB; michael@0: michael@0: // This counts the number of windows that have been opened in rapid succession michael@0: // (i.e. within dom.successive_dialog_time_limit of each other). It is reset michael@0: // to 0 once a dialog is opened after dom.successive_dialog_time_limit seconds michael@0: // have elapsed without any other dialogs. michael@0: uint32_t mDialogAbuseCount; michael@0: michael@0: // This holds the time when the last modal dialog was shown. If more than michael@0: // MAX_DIALOG_LIMIT dialogs are shown within the time span defined by michael@0: // dom.successive_dialog_time_limit, we show a checkbox or confirmation prompt michael@0: // to allow disabling of further dialogs from this window. michael@0: TimeStamp mLastDialogQuitTime; michael@0: michael@0: // This flag keeps track of whether dialogs are michael@0: // currently enabled on this window. michael@0: bool mAreDialogsEnabled; michael@0: michael@0: nsTHashtable > mEventTargetObjects; michael@0: michael@0: nsTArray mEnabledSensors; michael@0: michael@0: #ifdef MOZ_WEBSPEECH michael@0: // mSpeechSynthesis is only used on inner windows. michael@0: nsRefPtr mSpeechSynthesis; michael@0: #endif michael@0: michael@0: friend class nsDOMScriptableHelper; michael@0: friend class nsDOMWindowUtils; michael@0: friend class PostMessageEvent; michael@0: friend class DesktopNotification; michael@0: michael@0: static WindowByIdTable* sWindowsById; michael@0: static bool sWarnedAboutWindowInternal; michael@0: }; michael@0: michael@0: inline nsISupports* michael@0: ToSupports(nsGlobalWindow *p) michael@0: { michael@0: return static_cast(p); michael@0: } michael@0: michael@0: inline nsISupports* michael@0: ToCanonicalSupports(nsGlobalWindow *p) michael@0: { michael@0: return static_cast(p); michael@0: } michael@0: michael@0: /* michael@0: * nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global michael@0: * object created for a Chrome Window only. michael@0: */ michael@0: class nsGlobalChromeWindow : public nsGlobalWindow, michael@0: public nsIDOMChromeWindow michael@0: { michael@0: public: michael@0: // nsISupports michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: // nsIDOMChromeWindow interface michael@0: NS_DECL_NSIDOMCHROMEWINDOW michael@0: michael@0: nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow) michael@0: : nsGlobalWindow(aOuterWindow) michael@0: { michael@0: mIsChrome = true; michael@0: mCleanMessageManager = true; michael@0: } michael@0: michael@0: ~nsGlobalChromeWindow() michael@0: { michael@0: NS_ABORT_IF_FALSE(mCleanMessageManager, michael@0: "chrome windows may always disconnect the msg manager"); michael@0: if (mMessageManager) { michael@0: static_cast( michael@0: mMessageManager.get())->Disconnect(); michael@0: } michael@0: michael@0: mCleanMessageManager = false; michael@0: } michael@0: michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalChromeWindow, michael@0: nsGlobalWindow) michael@0: michael@0: using nsGlobalWindow::GetBrowserDOMWindow; michael@0: using nsGlobalWindow::SetBrowserDOMWindow; michael@0: using nsGlobalWindow::GetAttention; michael@0: using nsGlobalWindow::GetAttentionWithCycleCount; michael@0: using nsGlobalWindow::SetCursor; michael@0: using nsGlobalWindow::Maximize; michael@0: using nsGlobalWindow::Minimize; michael@0: using nsGlobalWindow::Restore; michael@0: using nsGlobalWindow::NotifyDefaultButtonLoaded; michael@0: using nsGlobalWindow::GetMessageManager; michael@0: using nsGlobalWindow::BeginWindowMove; michael@0: michael@0: nsCOMPtr mBrowserDOMWindow; michael@0: nsCOMPtr mMessageManager; michael@0: }; michael@0: michael@0: /* michael@0: * nsGlobalModalWindow inherits from nsGlobalWindow. It is the global michael@0: * object created for a modal content windows only (i.e. not modal michael@0: * chrome dialogs). michael@0: */ michael@0: class nsGlobalModalWindow : public nsGlobalWindow, michael@0: public nsIDOMModalContentWindow michael@0: { michael@0: public: michael@0: nsGlobalModalWindow(nsGlobalWindow *aOuterWindow) michael@0: : nsGlobalWindow(aOuterWindow) michael@0: { michael@0: mIsModalContentWindow = true; michael@0: } michael@0: michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: NS_DECL_NSIDOMMODALCONTENTWINDOW michael@0: }; michael@0: michael@0: /* factory function */ michael@0: inline already_AddRefed michael@0: NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow) michael@0: { michael@0: nsRefPtr global; michael@0: michael@0: if (aIsChrome) { michael@0: global = new nsGlobalChromeWindow(nullptr); michael@0: } else if (aIsModalContentWindow) { michael@0: global = new nsGlobalModalWindow(nullptr); michael@0: } else { michael@0: global = new nsGlobalWindow(nullptr); michael@0: } michael@0: michael@0: return global.forget(); michael@0: } michael@0: michael@0: #endif /* nsGlobalWindow_h___ */