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: michael@0: #ifndef nsPIDOMWindow_h__ michael@0: #define nsPIDOMWindow_h__ michael@0: michael@0: #include "nsIDOMWindow.h" michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsTArray.h" michael@0: #include "mozilla/dom/EventTarget.h" michael@0: #include "js/TypeDecls.h" michael@0: michael@0: #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed" michael@0: #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen" michael@0: #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed" michael@0: michael@0: class nsIArray; michael@0: class nsIContent; michael@0: class nsIDocShell; michael@0: class nsIDocument; michael@0: class nsIIdleObserver; michael@0: class nsIPrincipal; michael@0: class nsIScriptTimeoutHandler; michael@0: class nsIURI; michael@0: class nsPerformance; michael@0: class nsPIWindowRoot; michael@0: class nsXBLPrototypeHandler; michael@0: struct nsTimeout; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class AudioContext; michael@0: class Element; michael@0: } michael@0: } michael@0: michael@0: // Popup control state enum. The values in this enum must go from most michael@0: // permissive to least permissive so that it's safe to push state in michael@0: // all situations. Pushing popup state onto the stack never makes the michael@0: // current popup state less permissive (see michael@0: // nsGlobalWindow::PushPopupControlState()). michael@0: enum PopupControlState { michael@0: openAllowed = 0, // open that window without worries michael@0: openControlled, // it's a popup, but allow it michael@0: openAbused, // it's a popup. disallow it, but allow domain override. michael@0: openOverridden // disallow window open michael@0: }; michael@0: michael@0: enum UIStateChangeType michael@0: { michael@0: UIStateChangeType_NoChange, michael@0: UIStateChangeType_Set, michael@0: UIStateChangeType_Clear michael@0: }; michael@0: michael@0: #define NS_PIDOMWINDOW_IID \ michael@0: { 0xf26953de, 0xa799, 0x4a92, \ michael@0: { 0x87, 0x49, 0x7c, 0x37, 0xe5, 0x90, 0x3f, 0x37 } } michael@0: michael@0: class nsPIDOMWindow : public nsIDOMWindowInternal michael@0: { michael@0: public: michael@0: NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID) michael@0: michael@0: virtual nsPIDOMWindow* GetPrivateRoot() = 0; michael@0: michael@0: // Outer windows only. michael@0: virtual void ActivateOrDeactivate(bool aActivate) = 0; michael@0: michael@0: // this is called GetTopWindowRoot to avoid conflicts with nsIDOMWindow::GetWindowRoot michael@0: virtual already_AddRefed GetTopWindowRoot() = 0; michael@0: michael@0: // Inner windows only. michael@0: virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0; michael@0: virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0; michael@0: michael@0: // Outer windows only. michael@0: virtual void SetActive(bool aActive) michael@0: { michael@0: MOZ_ASSERT(IsOuterWindow()); michael@0: mIsActive = aActive; michael@0: } michael@0: bool IsActive() michael@0: { michael@0: MOZ_ASSERT(IsOuterWindow()); michael@0: return mIsActive; michael@0: } michael@0: michael@0: // Outer windows only. michael@0: virtual void SetIsBackground(bool aIsBackground) michael@0: { michael@0: MOZ_ASSERT(IsOuterWindow()); michael@0: mIsBackground = aIsBackground; michael@0: } michael@0: bool IsBackground() michael@0: { michael@0: MOZ_ASSERT(IsOuterWindow()); michael@0: return mIsBackground; michael@0: } michael@0: michael@0: mozilla::dom::EventTarget* GetChromeEventHandler() const michael@0: { michael@0: return mChromeEventHandler; michael@0: } michael@0: michael@0: // Outer windows only. michael@0: virtual void SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler) = 0; michael@0: michael@0: mozilla::dom::EventTarget* GetParentTarget() michael@0: { michael@0: if (!mParentTarget) { michael@0: UpdateParentTarget(); michael@0: } michael@0: return mParentTarget; michael@0: } michael@0: michael@0: bool HasMutationListeners(uint32_t aMutationEventType) const michael@0: { michael@0: const nsPIDOMWindow *win; michael@0: michael@0: if (IsOuterWindow()) { michael@0: win = GetCurrentInnerWindow(); michael@0: michael@0: if (!win) { michael@0: NS_ERROR("No current inner window available!"); michael@0: michael@0: return false; michael@0: } michael@0: } else { michael@0: if (!mOuterWindow) { michael@0: NS_ERROR("HasMutationListeners() called on orphan inner window!"); michael@0: michael@0: return false; michael@0: } michael@0: michael@0: win = this; michael@0: } michael@0: michael@0: return (win->mMutationBits & aMutationEventType) != 0; michael@0: } michael@0: michael@0: void SetMutationListeners(uint32_t aType) michael@0: { michael@0: nsPIDOMWindow *win; michael@0: michael@0: if (IsOuterWindow()) { michael@0: win = GetCurrentInnerWindow(); michael@0: michael@0: if (!win) { michael@0: NS_ERROR("No inner window available to set mutation bits on!"); michael@0: michael@0: return; michael@0: } michael@0: } else { michael@0: if (!mOuterWindow) { michael@0: NS_ERROR("HasMutationListeners() called on orphan inner window!"); michael@0: michael@0: return; michael@0: } michael@0: michael@0: win = this; michael@0: } michael@0: michael@0: win->mMutationBits |= aType; michael@0: } michael@0: michael@0: virtual void MaybeUpdateTouchState() {} michael@0: virtual void UpdateTouchState() {} michael@0: michael@0: nsIDocument* GetExtantDoc() const michael@0: { michael@0: return mDoc; michael@0: } michael@0: nsIURI* GetDocumentURI() const; michael@0: nsIURI* GetDocBaseURI() const; michael@0: michael@0: nsIDocument* GetDoc() michael@0: { michael@0: if (!mDoc) { michael@0: MaybeCreateDoc(); michael@0: } michael@0: return mDoc; michael@0: } michael@0: michael@0: virtual NS_HIDDEN_(bool) IsRunningTimeout() = 0; michael@0: michael@0: // Audio API michael@0: bool GetAudioMuted() const; michael@0: void SetAudioMuted(bool aMuted); michael@0: michael@0: float GetAudioVolume() const; michael@0: nsresult SetAudioVolume(float aVolume); michael@0: michael@0: float GetAudioGlobalVolume(); michael@0: michael@0: protected: michael@0: // Lazily instantiate an about:blank document if necessary, and if michael@0: // we have what it takes to do so. michael@0: void MaybeCreateDoc(); michael@0: michael@0: float GetAudioGlobalVolumeInternal(float aVolume); michael@0: void RefreshMediaElements(); michael@0: michael@0: public: michael@0: // Internal getter/setter for the frame element, this version of the michael@0: // getter crosses chrome boundaries whereas the public scriptable michael@0: // one doesn't for security reasons. michael@0: mozilla::dom::Element* GetFrameElementInternal() const; michael@0: void SetFrameElementInternal(mozilla::dom::Element* aFrameElement); michael@0: michael@0: bool IsLoadingOrRunningTimeout() const michael@0: { michael@0: const nsPIDOMWindow *win = GetCurrentInnerWindow(); michael@0: michael@0: if (!win) { michael@0: win = this; michael@0: } michael@0: michael@0: return !win->mIsDocumentLoaded || win->mRunningTimeout; michael@0: } michael@0: michael@0: // Check whether a document is currently loading michael@0: bool IsLoading() const michael@0: { michael@0: const nsPIDOMWindow *win; michael@0: michael@0: if (IsOuterWindow()) { michael@0: win = GetCurrentInnerWindow(); michael@0: michael@0: if (!win) { michael@0: NS_ERROR("No current inner window available!"); michael@0: michael@0: return false; michael@0: } michael@0: } else { michael@0: if (!mOuterWindow) { michael@0: NS_ERROR("IsLoading() called on orphan inner window!"); michael@0: michael@0: return false; michael@0: } michael@0: michael@0: win = this; michael@0: } michael@0: michael@0: return !win->mIsDocumentLoaded; michael@0: } michael@0: michael@0: bool IsHandlingResizeEvent() const michael@0: { michael@0: const nsPIDOMWindow *win; michael@0: michael@0: if (IsOuterWindow()) { michael@0: win = GetCurrentInnerWindow(); michael@0: michael@0: if (!win) { michael@0: NS_ERROR("No current inner window available!"); michael@0: michael@0: return false; michael@0: } michael@0: } else { michael@0: if (!mOuterWindow) { michael@0: NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!"); michael@0: michael@0: return false; michael@0: } michael@0: michael@0: win = this; michael@0: } michael@0: michael@0: return win->mIsHandlingResizeEvent; michael@0: } michael@0: michael@0: // Set the window up with an about:blank document with the current subject michael@0: // principal. michael@0: virtual void SetInitialPrincipalToSubject() = 0; michael@0: michael@0: virtual PopupControlState PushPopupControlState(PopupControlState aState, michael@0: bool aForce) const = 0; michael@0: virtual void PopPopupControlState(PopupControlState state) const = 0; michael@0: virtual PopupControlState GetPopupControlState() const = 0; michael@0: michael@0: // Returns an object containing the window's state. This also suspends michael@0: // all running timeouts in the window. michael@0: virtual already_AddRefed SaveWindowState() = 0; michael@0: michael@0: // Restore the window state from aState. michael@0: virtual nsresult RestoreWindowState(nsISupports *aState) = 0; michael@0: michael@0: // Suspend timeouts in this window and in child windows. michael@0: virtual void SuspendTimeouts(uint32_t aIncrease = 1, michael@0: bool aFreezeChildren = true) = 0; michael@0: michael@0: // Resume suspended timeouts in this window and in child windows. michael@0: virtual nsresult ResumeTimeouts(bool aThawChildren = true) = 0; michael@0: michael@0: virtual uint32_t TimeoutSuspendCount() = 0; michael@0: michael@0: // Fire any DOM notification events related to things that happened while michael@0: // the window was frozen. michael@0: virtual nsresult FireDelayedDOMEvents() = 0; michael@0: michael@0: virtual bool IsFrozen() const = 0; michael@0: michael@0: // Add a timeout to this window. michael@0: virtual nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler, michael@0: int32_t interval, michael@0: bool aIsInterval, int32_t *aReturn) = 0; michael@0: michael@0: // Clear a timeout from this window. michael@0: virtual nsresult ClearTimeoutOrInterval(int32_t aTimerID) = 0; michael@0: michael@0: nsPIDOMWindow *GetOuterWindow() michael@0: { michael@0: return mIsInnerWindow ? mOuterWindow.get() : this; michael@0: } michael@0: michael@0: nsPIDOMWindow *GetCurrentInnerWindow() const michael@0: { michael@0: return mInnerWindow; michael@0: } michael@0: michael@0: nsPIDOMWindow *EnsureInnerWindow() michael@0: { michael@0: NS_ASSERTION(IsOuterWindow(), "EnsureInnerWindow called on inner window"); michael@0: // GetDoc forces inner window creation if there isn't one already michael@0: GetDoc(); michael@0: return GetCurrentInnerWindow(); michael@0: } michael@0: michael@0: bool IsInnerWindow() const michael@0: { michael@0: return mIsInnerWindow; michael@0: } michael@0: michael@0: // Returns true if this object has an outer window and it is the current inner michael@0: // window of that outer. Only call this on inner windows. michael@0: bool IsCurrentInnerWindow() const michael@0: { michael@0: MOZ_ASSERT(IsInnerWindow(), michael@0: "It doesn't make sense to call this on outer windows."); michael@0: return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this; michael@0: } michael@0: michael@0: // Returns true if the document of this window is the active document. This michael@0: // is not identical to IsCurrentInnerWindow() because document.open() will michael@0: // keep the same document active but create a new window. michael@0: bool HasActiveDocument() michael@0: { michael@0: MOZ_ASSERT(IsInnerWindow()); michael@0: return IsCurrentInnerWindow() || michael@0: (mOuterWindow && michael@0: mOuterWindow->GetCurrentInnerWindow() && michael@0: mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc); michael@0: } michael@0: michael@0: bool IsOuterWindow() const michael@0: { michael@0: return !IsInnerWindow(); michael@0: } michael@0: michael@0: virtual bool WouldReuseInnerWindow(nsIDocument *aNewDocument) = 0; michael@0: michael@0: /** michael@0: * Get the docshell in this window. michael@0: */ michael@0: nsIDocShell *GetDocShell() michael@0: { michael@0: if (mOuterWindow) { michael@0: return mOuterWindow->mDocShell; michael@0: } michael@0: michael@0: return mDocShell; michael@0: } michael@0: michael@0: /** michael@0: * Set the docshell in the window. Must not be called with a null docshell michael@0: * (use DetachFromDocShell for that). michael@0: */ michael@0: virtual void SetDocShell(nsIDocShell *aDocShell) = 0; michael@0: michael@0: /** michael@0: * Detach an outer window from its docshell. michael@0: */ michael@0: virtual void DetachFromDocShell() = 0; michael@0: michael@0: /** michael@0: * Set a new document in the window. Calling this method will in michael@0: * most cases create a new inner window. If this method is called on michael@0: * an inner window the call will be forewarded to the outer window, michael@0: * if the inner window is not the current inner window an michael@0: * NS_ERROR_NOT_AVAILABLE error code will be returned. This may be michael@0: * called with a pointer to the current document, in that case the michael@0: * document remains unchanged, but a new inner window will be michael@0: * created. michael@0: * michael@0: * aDocument must not be null. michael@0: */ michael@0: virtual nsresult SetNewDocument(nsIDocument *aDocument, michael@0: nsISupports *aState, michael@0: bool aForceReuseInnerWindow) = 0; michael@0: michael@0: /** michael@0: * Set the opener window. aOriginalOpener is true if and only if this is the michael@0: * original opener for the window. That is, it can only be true at most once michael@0: * during the life cycle of a window, and then only the first time michael@0: * SetOpenerWindow is called. It might never be true, of course, if the michael@0: * window does not have an opener when it's created. michael@0: */ michael@0: virtual void SetOpenerWindow(nsIDOMWindow* aOpener, michael@0: bool aOriginalOpener) = 0; michael@0: michael@0: virtual void EnsureSizeUpToDate() = 0; michael@0: michael@0: /** michael@0: * Callback for notifying a window about a modal dialog being michael@0: * opened/closed with the window as a parent. michael@0: */ michael@0: virtual void EnterModalState() = 0; michael@0: virtual void LeaveModalState() = 0; michael@0: michael@0: virtual bool CanClose() = 0; michael@0: virtual nsresult ForceClose() = 0; michael@0: michael@0: bool IsModalContentWindow() const michael@0: { michael@0: return mIsModalContentWindow; michael@0: } michael@0: michael@0: /** michael@0: * Call this to indicate that some node (this window, its document, michael@0: * or content in that document) has a paint event listener. michael@0: */ michael@0: void SetHasPaintEventListeners() michael@0: { michael@0: mMayHavePaintEventListener = true; michael@0: } michael@0: michael@0: /** michael@0: * Call this to check whether some node (this window, its document, michael@0: * or content in that document) has a paint event listener. michael@0: */ michael@0: bool HasPaintEventListeners() michael@0: { michael@0: return mMayHavePaintEventListener; michael@0: } michael@0: michael@0: /** michael@0: * Call this to indicate that some node (this window, its document, michael@0: * or content in that document) has a touch event listener. michael@0: */ michael@0: void SetHasTouchEventListeners() michael@0: { michael@0: mMayHaveTouchEventListener = true; michael@0: MaybeUpdateTouchState(); michael@0: } michael@0: michael@0: bool HasTouchEventListeners() michael@0: { michael@0: return mMayHaveTouchEventListener; michael@0: } michael@0: michael@0: /** michael@0: * Moves the top-level window into fullscreen mode if aIsFullScreen is true, michael@0: * otherwise exits fullscreen. If aRequireTrust is true, this method only michael@0: * changes window state in a context trusted for write. michael@0: */ michael@0: virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust) = 0; michael@0: michael@0: /** michael@0: * Call this to check whether some node (this window, its document, michael@0: * or content in that document) has a mouseenter/leave event listener. michael@0: */ michael@0: bool HasMouseEnterLeaveEventListeners() michael@0: { michael@0: return mMayHaveMouseEnterLeaveEventListener; michael@0: } michael@0: michael@0: /** michael@0: * Call this to indicate that some node (this window, its document, michael@0: * or content in that document) has a mouseenter/leave event listener. michael@0: */ michael@0: void SetHasMouseEnterLeaveEventListeners() michael@0: { michael@0: mMayHaveMouseEnterLeaveEventListener = true; michael@0: } michael@0: michael@0: /** michael@0: * Call this to check whether some node (this window, its document, michael@0: * or content in that document) has a Pointerenter/leave event listener. michael@0: */ michael@0: bool HasPointerEnterLeaveEventListeners() michael@0: { michael@0: return mMayHavePointerEnterLeaveEventListener; michael@0: } michael@0: michael@0: /** michael@0: * Call this to indicate that some node (this window, its document, michael@0: * or content in that document) has a Pointerenter/leave event listener. michael@0: */ michael@0: void SetHasPointerEnterLeaveEventListeners() michael@0: { michael@0: mMayHavePointerEnterLeaveEventListener = true; michael@0: } michael@0: michael@0: michael@0: virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0; michael@0: virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey, michael@0: JS::Handle aHandler) = 0; michael@0: michael@0: /* michael@0: * Get and set the currently focused element within the document. If michael@0: * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a michael@0: * document focus event is needed. michael@0: * michael@0: * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER michael@0: * INSTEAD. michael@0: */ michael@0: nsIContent* GetFocusedNode() michael@0: { michael@0: if (IsOuterWindow()) { michael@0: return mInnerWindow ? mInnerWindow->mFocusedNode.get() : nullptr; michael@0: } michael@0: return mFocusedNode; michael@0: } michael@0: virtual void SetFocusedNode(nsIContent* aNode, michael@0: uint32_t aFocusMethod = 0, michael@0: bool aNeedsFocus = false) = 0; michael@0: michael@0: /** michael@0: * Retrieves the method that was used to focus the current node. michael@0: */ michael@0: virtual uint32_t GetFocusMethod() = 0; michael@0: michael@0: /* michael@0: * Tells the window that it now has focus or has lost focus, based on the michael@0: * state of aFocus. If this method returns true, then the document loaded michael@0: * in the window has never received a focus event and expects to receive michael@0: * one. If false is returned, the document has received a focus event before michael@0: * and should only receive one if the window is being focused. michael@0: * michael@0: * aFocusMethod may be set to one of the focus method constants in michael@0: * nsIFocusManager to indicate how focus was set. michael@0: */ michael@0: virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0; michael@0: michael@0: /** michael@0: * Indicates that the window may now accept a document focus event. This michael@0: * should be called once a document has been loaded into the window. michael@0: */ michael@0: virtual void SetReadyForFocus() = 0; michael@0: michael@0: /** michael@0: * Whether the focused content within the window should show a focus ring. michael@0: */ michael@0: virtual bool ShouldShowFocusRing() = 0; michael@0: michael@0: /** michael@0: * Set the keyboard indicator state for accelerators and focus rings. michael@0: */ michael@0: virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators, michael@0: UIStateChangeType aShowFocusRings) = 0; michael@0: michael@0: /** michael@0: * Get the keyboard indicator state for accelerators and focus rings. michael@0: */ michael@0: virtual void GetKeyboardIndicators(bool* aShowAccelerators, michael@0: bool* aShowFocusRings) = 0; michael@0: michael@0: /** michael@0: * Indicates that the page in the window has been hidden. This is used to michael@0: * reset the focus state. michael@0: */ michael@0: virtual void PageHidden() = 0; michael@0: michael@0: /** michael@0: * Instructs this window to asynchronously dispatch a hashchange event. This michael@0: * method must be called on an inner window. michael@0: */ michael@0: virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, michael@0: nsIURI *aNewURI) = 0; michael@0: michael@0: /** michael@0: * Instructs this window to synchronously dispatch a popState event. michael@0: */ michael@0: virtual nsresult DispatchSyncPopState() = 0; michael@0: michael@0: /** michael@0: * Tell this window that it should listen for sensor changes of the given michael@0: * type. michael@0: * michael@0: * Inner windows only. michael@0: */ michael@0: virtual void EnableDeviceSensor(uint32_t aType) = 0; michael@0: michael@0: /** michael@0: * Tell this window that it should remove itself from sensor change michael@0: * notifications. michael@0: * michael@0: * Inner windows only. michael@0: */ michael@0: virtual void DisableDeviceSensor(uint32_t aType) = 0; michael@0: michael@0: virtual void EnableTimeChangeNotifications() = 0; michael@0: virtual void DisableTimeChangeNotifications() = 0; michael@0: michael@0: #ifdef MOZ_B2G michael@0: /** michael@0: * Tell the window that it should start to listen to the network event of the michael@0: * given aType. michael@0: * michael@0: * Inner windows only. michael@0: */ michael@0: virtual void EnableNetworkEvent(uint32_t aType) = 0; michael@0: michael@0: /** michael@0: * Tell the window that it should stop to listen to the network event of the michael@0: * given aType. michael@0: * michael@0: * Inner windows only. michael@0: */ michael@0: virtual void DisableNetworkEvent(uint32_t aType) = 0; michael@0: #endif // MOZ_B2G michael@0: michael@0: /** michael@0: * Tell this window that there is an observer for gamepad input michael@0: */ michael@0: virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0; michael@0: michael@0: /** michael@0: * Set a arguments for this window. This will be set on the window michael@0: * right away (if there's an existing document) and it will also be michael@0: * installed on the window when the next document is loaded. michael@0: * michael@0: * This function serves double-duty for passing both |arguments| and michael@0: * |dialogArguments| back from nsWindowWatcher to nsGlobalWindow. For the michael@0: * latter, the array is an array of length 0 whose only element is a michael@0: * DialogArgumentsHolder representing the JS value passed to showModalDialog. michael@0: */ michael@0: virtual nsresult SetArguments(nsIArray *aArguments) = 0; michael@0: michael@0: /** michael@0: * NOTE! This function *will* be called on multiple threads so the michael@0: * implementation must not do any AddRef/Release or other actions that will michael@0: * mutate internal state. michael@0: */ michael@0: virtual uint32_t GetSerial() = 0; michael@0: michael@0: /** michael@0: * Return the window id of this window michael@0: */ michael@0: uint64_t WindowID() const { return mWindowID; } michael@0: michael@0: /** michael@0: * Dispatch a custom event with name aEventName targeted at this window. michael@0: * Returns whether the default action should be performed. michael@0: */ michael@0: virtual bool DispatchCustomEvent(const char *aEventName) = 0; michael@0: michael@0: /** michael@0: * Notify the active inner window that the document principal may have changed michael@0: * and that the compartment principal needs to be updated. michael@0: */ michael@0: virtual void RefreshCompartmentPrincipal() = 0; michael@0: michael@0: /** michael@0: * Like nsIDOMWindow::Open, except that we don't navigate to the given URL. michael@0: */ michael@0: virtual nsresult michael@0: OpenNoNavigate(const nsAString& aUrl, const nsAString& aName, michael@0: const nsAString& aOptions, nsIDOMWindow **_retval) = 0; michael@0: michael@0: void AddAudioContext(mozilla::dom::AudioContext* aAudioContext); michael@0: void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext); michael@0: void MuteAudioContexts(); michael@0: void UnmuteAudioContexts(); michael@0: michael@0: // Given an inner window, return its outer if the inner is the current inner. michael@0: // Otherwise (argument null or not an inner or not current) return null. michael@0: static nsPIDOMWindow* GetOuterFromCurrentInner(nsPIDOMWindow* aInner) michael@0: { michael@0: if (!aInner) { michael@0: return nullptr; michael@0: } michael@0: michael@0: nsPIDOMWindow* outer = aInner->GetOuterWindow(); michael@0: if (!outer || outer->GetCurrentInnerWindow() != aInner) { michael@0: return nullptr; michael@0: } michael@0: michael@0: return outer; michael@0: } michael@0: michael@0: // WebIDL-ish APIs michael@0: nsPerformance* GetPerformance(); michael@0: michael@0: void MarkUncollectableForCCGeneration(uint32_t aGeneration) michael@0: { michael@0: mMarkedCCGeneration = aGeneration; michael@0: } michael@0: michael@0: uint32_t GetMarkedCCGeneration() michael@0: { michael@0: return mMarkedCCGeneration; michael@0: } michael@0: protected: michael@0: // The nsPIDOMWindow constructor. The aOuterWindow argument should michael@0: // be null if and only if the created window itself is an outer michael@0: // window. In all other cases aOuterWindow should be the outer michael@0: // window for the inner window that is being created. michael@0: nsPIDOMWindow(nsPIDOMWindow *aOuterWindow); michael@0: michael@0: ~nsPIDOMWindow(); michael@0: michael@0: void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler) { michael@0: mChromeEventHandler = aChromeEventHandler; michael@0: // mParentTarget will be set when the next event is dispatched. michael@0: mParentTarget = nullptr; michael@0: } michael@0: michael@0: virtual void UpdateParentTarget() = 0; michael@0: michael@0: // Helper for creating performance objects. michael@0: void CreatePerformanceObjectIfNeeded(); michael@0: michael@0: // These two variables are special in that they're set to the same michael@0: // value on both the outer window and the current inner window. Make michael@0: // sure you keep them in sync! michael@0: nsCOMPtr mChromeEventHandler; // strong michael@0: nsCOMPtr mDoc; // strong michael@0: // Cache the URI when mDoc is cleared. michael@0: nsCOMPtr mDocumentURI; // strong michael@0: nsCOMPtr mDocBaseURI; // strong michael@0: michael@0: nsCOMPtr mParentTarget; // strong michael@0: michael@0: // These members are only used on outer windows. michael@0: nsCOMPtr mFrameElement; michael@0: nsIDocShell *mDocShell; // Weak Reference michael@0: michael@0: // mPerformance is only used on inner windows. michael@0: nsRefPtr mPerformance; michael@0: michael@0: uint32_t mModalStateDepth; michael@0: michael@0: // These variables are only used on inner windows. michael@0: nsTimeout *mRunningTimeout; michael@0: michael@0: uint32_t mMutationBits; michael@0: michael@0: bool mIsDocumentLoaded; michael@0: bool mIsHandlingResizeEvent; michael@0: bool mIsInnerWindow; michael@0: bool mMayHavePaintEventListener; michael@0: bool mMayHaveTouchEventListener; michael@0: bool mMayHaveMouseEnterLeaveEventListener; michael@0: bool mMayHavePointerEnterLeaveEventListener; michael@0: michael@0: // This variable is used on both inner and outer windows (and they michael@0: // should match). michael@0: bool mIsModalContentWindow; michael@0: michael@0: // Tracks activation state that's used for :-moz-window-inactive. michael@0: // Only used on outer windows. michael@0: bool mIsActive; michael@0: michael@0: // Tracks whether our docshell is active. If it is, mIsBackground michael@0: // is false. Too bad we have so many different concepts of michael@0: // "active". Only used on outer windows. michael@0: bool mIsBackground; michael@0: michael@0: bool mAudioMuted; michael@0: float mAudioVolume; michael@0: michael@0: // And these are the references between inner and outer windows. michael@0: nsPIDOMWindow *mInnerWindow; michael@0: nsCOMPtr mOuterWindow; michael@0: michael@0: // the element within the document that is currently focused when this michael@0: // window is active michael@0: nsCOMPtr mFocusedNode; michael@0: michael@0: // The AudioContexts created for the current document, if any. michael@0: nsTArray mAudioContexts; // Weak michael@0: michael@0: // A unique (as long as our 64-bit counter doesn't roll over) id for michael@0: // this window. michael@0: uint64_t mWindowID; michael@0: michael@0: // This is only used by the inner window. Set to true once we've sent michael@0: // the (chrome|content)-document-global-created notification. michael@0: bool mHasNotifiedGlobalCreated; michael@0: michael@0: uint32_t mMarkedCCGeneration; michael@0: }; michael@0: michael@0: michael@0: NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindow, NS_PIDOMWINDOW_IID) michael@0: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: PopupControlState michael@0: PushPopupControlState(PopupControlState aState, bool aForce); michael@0: michael@0: void michael@0: PopPopupControlState(PopupControlState aState); michael@0: michael@0: #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherInternal michael@0: #else michael@0: #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherExternal michael@0: #endif michael@0: michael@0: // Helper class that helps with pushing and popping popup control michael@0: // state. Note that this class looks different from within code that's michael@0: // part of the layout library than it does in code outside the layout michael@0: // library. We give the two object layouts different names so the symbols michael@0: // don't conflict, but code should always use the name michael@0: // |nsAutoPopupStatePusher|. michael@0: class NS_AUTO_POPUP_STATE_PUSHER michael@0: { michael@0: public: michael@0: #ifdef MOZILLA_INTERNAL_API michael@0: NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false) michael@0: : mOldState(::PushPopupControlState(aState, aForce)) michael@0: { michael@0: } michael@0: michael@0: ~NS_AUTO_POPUP_STATE_PUSHER() michael@0: { michael@0: PopPopupControlState(mOldState); michael@0: } michael@0: #else michael@0: NS_AUTO_POPUP_STATE_PUSHER(nsPIDOMWindow *aWindow, PopupControlState aState) michael@0: : mWindow(aWindow), mOldState(openAbused) michael@0: { michael@0: if (aWindow) { michael@0: mOldState = aWindow->PushPopupControlState(aState, false); michael@0: } michael@0: } michael@0: michael@0: ~NS_AUTO_POPUP_STATE_PUSHER() michael@0: { michael@0: if (mWindow) { michael@0: mWindow->PopPopupControlState(mOldState); michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: protected: michael@0: #ifndef MOZILLA_INTERNAL_API michael@0: nsCOMPtr mWindow; michael@0: #endif michael@0: PopupControlState mOldState; michael@0: michael@0: private: michael@0: // Hide so that this class can only be stack-allocated michael@0: static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nullptr; } michael@0: static void operator delete(void* /*memory*/) {} michael@0: }; michael@0: michael@0: #define nsAutoPopupStatePusher NS_AUTO_POPUP_STATE_PUSHER michael@0: michael@0: #endif // nsPIDOMWindow_h__