Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=2 sw=2 et tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | |
michael@0 | 8 | #ifndef nsPIDOMWindow_h__ |
michael@0 | 9 | #define nsPIDOMWindow_h__ |
michael@0 | 10 | |
michael@0 | 11 | #include "nsIDOMWindow.h" |
michael@0 | 12 | |
michael@0 | 13 | #include "nsCOMPtr.h" |
michael@0 | 14 | #include "nsAutoPtr.h" |
michael@0 | 15 | #include "nsTArray.h" |
michael@0 | 16 | #include "mozilla/dom/EventTarget.h" |
michael@0 | 17 | #include "js/TypeDecls.h" |
michael@0 | 18 | |
michael@0 | 19 | #define DOM_WINDOW_DESTROYED_TOPIC "dom-window-destroyed" |
michael@0 | 20 | #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen" |
michael@0 | 21 | #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed" |
michael@0 | 22 | |
michael@0 | 23 | class nsIArray; |
michael@0 | 24 | class nsIContent; |
michael@0 | 25 | class nsIDocShell; |
michael@0 | 26 | class nsIDocument; |
michael@0 | 27 | class nsIIdleObserver; |
michael@0 | 28 | class nsIPrincipal; |
michael@0 | 29 | class nsIScriptTimeoutHandler; |
michael@0 | 30 | class nsIURI; |
michael@0 | 31 | class nsPerformance; |
michael@0 | 32 | class nsPIWindowRoot; |
michael@0 | 33 | class nsXBLPrototypeHandler; |
michael@0 | 34 | struct nsTimeout; |
michael@0 | 35 | |
michael@0 | 36 | namespace mozilla { |
michael@0 | 37 | namespace dom { |
michael@0 | 38 | class AudioContext; |
michael@0 | 39 | class Element; |
michael@0 | 40 | } |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | // Popup control state enum. The values in this enum must go from most |
michael@0 | 44 | // permissive to least permissive so that it's safe to push state in |
michael@0 | 45 | // all situations. Pushing popup state onto the stack never makes the |
michael@0 | 46 | // current popup state less permissive (see |
michael@0 | 47 | // nsGlobalWindow::PushPopupControlState()). |
michael@0 | 48 | enum PopupControlState { |
michael@0 | 49 | openAllowed = 0, // open that window without worries |
michael@0 | 50 | openControlled, // it's a popup, but allow it |
michael@0 | 51 | openAbused, // it's a popup. disallow it, but allow domain override. |
michael@0 | 52 | openOverridden // disallow window open |
michael@0 | 53 | }; |
michael@0 | 54 | |
michael@0 | 55 | enum UIStateChangeType |
michael@0 | 56 | { |
michael@0 | 57 | UIStateChangeType_NoChange, |
michael@0 | 58 | UIStateChangeType_Set, |
michael@0 | 59 | UIStateChangeType_Clear |
michael@0 | 60 | }; |
michael@0 | 61 | |
michael@0 | 62 | #define NS_PIDOMWINDOW_IID \ |
michael@0 | 63 | { 0xf26953de, 0xa799, 0x4a92, \ |
michael@0 | 64 | { 0x87, 0x49, 0x7c, 0x37, 0xe5, 0x90, 0x3f, 0x37 } } |
michael@0 | 65 | |
michael@0 | 66 | class nsPIDOMWindow : public nsIDOMWindowInternal |
michael@0 | 67 | { |
michael@0 | 68 | public: |
michael@0 | 69 | NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID) |
michael@0 | 70 | |
michael@0 | 71 | virtual nsPIDOMWindow* GetPrivateRoot() = 0; |
michael@0 | 72 | |
michael@0 | 73 | // Outer windows only. |
michael@0 | 74 | virtual void ActivateOrDeactivate(bool aActivate) = 0; |
michael@0 | 75 | |
michael@0 | 76 | // this is called GetTopWindowRoot to avoid conflicts with nsIDOMWindow::GetWindowRoot |
michael@0 | 77 | virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() = 0; |
michael@0 | 78 | |
michael@0 | 79 | // Inner windows only. |
michael@0 | 80 | virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0; |
michael@0 | 81 | virtual nsresult UnregisterIdleObserver(nsIIdleObserver* aIdleObserver) = 0; |
michael@0 | 82 | |
michael@0 | 83 | // Outer windows only. |
michael@0 | 84 | virtual void SetActive(bool aActive) |
michael@0 | 85 | { |
michael@0 | 86 | MOZ_ASSERT(IsOuterWindow()); |
michael@0 | 87 | mIsActive = aActive; |
michael@0 | 88 | } |
michael@0 | 89 | bool IsActive() |
michael@0 | 90 | { |
michael@0 | 91 | MOZ_ASSERT(IsOuterWindow()); |
michael@0 | 92 | return mIsActive; |
michael@0 | 93 | } |
michael@0 | 94 | |
michael@0 | 95 | // Outer windows only. |
michael@0 | 96 | virtual void SetIsBackground(bool aIsBackground) |
michael@0 | 97 | { |
michael@0 | 98 | MOZ_ASSERT(IsOuterWindow()); |
michael@0 | 99 | mIsBackground = aIsBackground; |
michael@0 | 100 | } |
michael@0 | 101 | bool IsBackground() |
michael@0 | 102 | { |
michael@0 | 103 | MOZ_ASSERT(IsOuterWindow()); |
michael@0 | 104 | return mIsBackground; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | mozilla::dom::EventTarget* GetChromeEventHandler() const |
michael@0 | 108 | { |
michael@0 | 109 | return mChromeEventHandler; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | // Outer windows only. |
michael@0 | 113 | virtual void SetChromeEventHandler(mozilla::dom::EventTarget* aChromeEventHandler) = 0; |
michael@0 | 114 | |
michael@0 | 115 | mozilla::dom::EventTarget* GetParentTarget() |
michael@0 | 116 | { |
michael@0 | 117 | if (!mParentTarget) { |
michael@0 | 118 | UpdateParentTarget(); |
michael@0 | 119 | } |
michael@0 | 120 | return mParentTarget; |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | bool HasMutationListeners(uint32_t aMutationEventType) const |
michael@0 | 124 | { |
michael@0 | 125 | const nsPIDOMWindow *win; |
michael@0 | 126 | |
michael@0 | 127 | if (IsOuterWindow()) { |
michael@0 | 128 | win = GetCurrentInnerWindow(); |
michael@0 | 129 | |
michael@0 | 130 | if (!win) { |
michael@0 | 131 | NS_ERROR("No current inner window available!"); |
michael@0 | 132 | |
michael@0 | 133 | return false; |
michael@0 | 134 | } |
michael@0 | 135 | } else { |
michael@0 | 136 | if (!mOuterWindow) { |
michael@0 | 137 | NS_ERROR("HasMutationListeners() called on orphan inner window!"); |
michael@0 | 138 | |
michael@0 | 139 | return false; |
michael@0 | 140 | } |
michael@0 | 141 | |
michael@0 | 142 | win = this; |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | return (win->mMutationBits & aMutationEventType) != 0; |
michael@0 | 146 | } |
michael@0 | 147 | |
michael@0 | 148 | void SetMutationListeners(uint32_t aType) |
michael@0 | 149 | { |
michael@0 | 150 | nsPIDOMWindow *win; |
michael@0 | 151 | |
michael@0 | 152 | if (IsOuterWindow()) { |
michael@0 | 153 | win = GetCurrentInnerWindow(); |
michael@0 | 154 | |
michael@0 | 155 | if (!win) { |
michael@0 | 156 | NS_ERROR("No inner window available to set mutation bits on!"); |
michael@0 | 157 | |
michael@0 | 158 | return; |
michael@0 | 159 | } |
michael@0 | 160 | } else { |
michael@0 | 161 | if (!mOuterWindow) { |
michael@0 | 162 | NS_ERROR("HasMutationListeners() called on orphan inner window!"); |
michael@0 | 163 | |
michael@0 | 164 | return; |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | win = this; |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | win->mMutationBits |= aType; |
michael@0 | 171 | } |
michael@0 | 172 | |
michael@0 | 173 | virtual void MaybeUpdateTouchState() {} |
michael@0 | 174 | virtual void UpdateTouchState() {} |
michael@0 | 175 | |
michael@0 | 176 | nsIDocument* GetExtantDoc() const |
michael@0 | 177 | { |
michael@0 | 178 | return mDoc; |
michael@0 | 179 | } |
michael@0 | 180 | nsIURI* GetDocumentURI() const; |
michael@0 | 181 | nsIURI* GetDocBaseURI() const; |
michael@0 | 182 | |
michael@0 | 183 | nsIDocument* GetDoc() |
michael@0 | 184 | { |
michael@0 | 185 | if (!mDoc) { |
michael@0 | 186 | MaybeCreateDoc(); |
michael@0 | 187 | } |
michael@0 | 188 | return mDoc; |
michael@0 | 189 | } |
michael@0 | 190 | |
michael@0 | 191 | virtual NS_HIDDEN_(bool) IsRunningTimeout() = 0; |
michael@0 | 192 | |
michael@0 | 193 | // Audio API |
michael@0 | 194 | bool GetAudioMuted() const; |
michael@0 | 195 | void SetAudioMuted(bool aMuted); |
michael@0 | 196 | |
michael@0 | 197 | float GetAudioVolume() const; |
michael@0 | 198 | nsresult SetAudioVolume(float aVolume); |
michael@0 | 199 | |
michael@0 | 200 | float GetAudioGlobalVolume(); |
michael@0 | 201 | |
michael@0 | 202 | protected: |
michael@0 | 203 | // Lazily instantiate an about:blank document if necessary, and if |
michael@0 | 204 | // we have what it takes to do so. |
michael@0 | 205 | void MaybeCreateDoc(); |
michael@0 | 206 | |
michael@0 | 207 | float GetAudioGlobalVolumeInternal(float aVolume); |
michael@0 | 208 | void RefreshMediaElements(); |
michael@0 | 209 | |
michael@0 | 210 | public: |
michael@0 | 211 | // Internal getter/setter for the frame element, this version of the |
michael@0 | 212 | // getter crosses chrome boundaries whereas the public scriptable |
michael@0 | 213 | // one doesn't for security reasons. |
michael@0 | 214 | mozilla::dom::Element* GetFrameElementInternal() const; |
michael@0 | 215 | void SetFrameElementInternal(mozilla::dom::Element* aFrameElement); |
michael@0 | 216 | |
michael@0 | 217 | bool IsLoadingOrRunningTimeout() const |
michael@0 | 218 | { |
michael@0 | 219 | const nsPIDOMWindow *win = GetCurrentInnerWindow(); |
michael@0 | 220 | |
michael@0 | 221 | if (!win) { |
michael@0 | 222 | win = this; |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | return !win->mIsDocumentLoaded || win->mRunningTimeout; |
michael@0 | 226 | } |
michael@0 | 227 | |
michael@0 | 228 | // Check whether a document is currently loading |
michael@0 | 229 | bool IsLoading() const |
michael@0 | 230 | { |
michael@0 | 231 | const nsPIDOMWindow *win; |
michael@0 | 232 | |
michael@0 | 233 | if (IsOuterWindow()) { |
michael@0 | 234 | win = GetCurrentInnerWindow(); |
michael@0 | 235 | |
michael@0 | 236 | if (!win) { |
michael@0 | 237 | NS_ERROR("No current inner window available!"); |
michael@0 | 238 | |
michael@0 | 239 | return false; |
michael@0 | 240 | } |
michael@0 | 241 | } else { |
michael@0 | 242 | if (!mOuterWindow) { |
michael@0 | 243 | NS_ERROR("IsLoading() called on orphan inner window!"); |
michael@0 | 244 | |
michael@0 | 245 | return false; |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | win = this; |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | return !win->mIsDocumentLoaded; |
michael@0 | 252 | } |
michael@0 | 253 | |
michael@0 | 254 | bool IsHandlingResizeEvent() const |
michael@0 | 255 | { |
michael@0 | 256 | const nsPIDOMWindow *win; |
michael@0 | 257 | |
michael@0 | 258 | if (IsOuterWindow()) { |
michael@0 | 259 | win = GetCurrentInnerWindow(); |
michael@0 | 260 | |
michael@0 | 261 | if (!win) { |
michael@0 | 262 | NS_ERROR("No current inner window available!"); |
michael@0 | 263 | |
michael@0 | 264 | return false; |
michael@0 | 265 | } |
michael@0 | 266 | } else { |
michael@0 | 267 | if (!mOuterWindow) { |
michael@0 | 268 | NS_ERROR("IsHandlingResizeEvent() called on orphan inner window!"); |
michael@0 | 269 | |
michael@0 | 270 | return false; |
michael@0 | 271 | } |
michael@0 | 272 | |
michael@0 | 273 | win = this; |
michael@0 | 274 | } |
michael@0 | 275 | |
michael@0 | 276 | return win->mIsHandlingResizeEvent; |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | // Set the window up with an about:blank document with the current subject |
michael@0 | 280 | // principal. |
michael@0 | 281 | virtual void SetInitialPrincipalToSubject() = 0; |
michael@0 | 282 | |
michael@0 | 283 | virtual PopupControlState PushPopupControlState(PopupControlState aState, |
michael@0 | 284 | bool aForce) const = 0; |
michael@0 | 285 | virtual void PopPopupControlState(PopupControlState state) const = 0; |
michael@0 | 286 | virtual PopupControlState GetPopupControlState() const = 0; |
michael@0 | 287 | |
michael@0 | 288 | // Returns an object containing the window's state. This also suspends |
michael@0 | 289 | // all running timeouts in the window. |
michael@0 | 290 | virtual already_AddRefed<nsISupports> SaveWindowState() = 0; |
michael@0 | 291 | |
michael@0 | 292 | // Restore the window state from aState. |
michael@0 | 293 | virtual nsresult RestoreWindowState(nsISupports *aState) = 0; |
michael@0 | 294 | |
michael@0 | 295 | // Suspend timeouts in this window and in child windows. |
michael@0 | 296 | virtual void SuspendTimeouts(uint32_t aIncrease = 1, |
michael@0 | 297 | bool aFreezeChildren = true) = 0; |
michael@0 | 298 | |
michael@0 | 299 | // Resume suspended timeouts in this window and in child windows. |
michael@0 | 300 | virtual nsresult ResumeTimeouts(bool aThawChildren = true) = 0; |
michael@0 | 301 | |
michael@0 | 302 | virtual uint32_t TimeoutSuspendCount() = 0; |
michael@0 | 303 | |
michael@0 | 304 | // Fire any DOM notification events related to things that happened while |
michael@0 | 305 | // the window was frozen. |
michael@0 | 306 | virtual nsresult FireDelayedDOMEvents() = 0; |
michael@0 | 307 | |
michael@0 | 308 | virtual bool IsFrozen() const = 0; |
michael@0 | 309 | |
michael@0 | 310 | // Add a timeout to this window. |
michael@0 | 311 | virtual nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler, |
michael@0 | 312 | int32_t interval, |
michael@0 | 313 | bool aIsInterval, int32_t *aReturn) = 0; |
michael@0 | 314 | |
michael@0 | 315 | // Clear a timeout from this window. |
michael@0 | 316 | virtual nsresult ClearTimeoutOrInterval(int32_t aTimerID) = 0; |
michael@0 | 317 | |
michael@0 | 318 | nsPIDOMWindow *GetOuterWindow() |
michael@0 | 319 | { |
michael@0 | 320 | return mIsInnerWindow ? mOuterWindow.get() : this; |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | nsPIDOMWindow *GetCurrentInnerWindow() const |
michael@0 | 324 | { |
michael@0 | 325 | return mInnerWindow; |
michael@0 | 326 | } |
michael@0 | 327 | |
michael@0 | 328 | nsPIDOMWindow *EnsureInnerWindow() |
michael@0 | 329 | { |
michael@0 | 330 | NS_ASSERTION(IsOuterWindow(), "EnsureInnerWindow called on inner window"); |
michael@0 | 331 | // GetDoc forces inner window creation if there isn't one already |
michael@0 | 332 | GetDoc(); |
michael@0 | 333 | return GetCurrentInnerWindow(); |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | bool IsInnerWindow() const |
michael@0 | 337 | { |
michael@0 | 338 | return mIsInnerWindow; |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | // Returns true if this object has an outer window and it is the current inner |
michael@0 | 342 | // window of that outer. Only call this on inner windows. |
michael@0 | 343 | bool IsCurrentInnerWindow() const |
michael@0 | 344 | { |
michael@0 | 345 | MOZ_ASSERT(IsInnerWindow(), |
michael@0 | 346 | "It doesn't make sense to call this on outer windows."); |
michael@0 | 347 | return mOuterWindow && mOuterWindow->GetCurrentInnerWindow() == this; |
michael@0 | 348 | } |
michael@0 | 349 | |
michael@0 | 350 | // Returns true if the document of this window is the active document. This |
michael@0 | 351 | // is not identical to IsCurrentInnerWindow() because document.open() will |
michael@0 | 352 | // keep the same document active but create a new window. |
michael@0 | 353 | bool HasActiveDocument() |
michael@0 | 354 | { |
michael@0 | 355 | MOZ_ASSERT(IsInnerWindow()); |
michael@0 | 356 | return IsCurrentInnerWindow() || |
michael@0 | 357 | (mOuterWindow && |
michael@0 | 358 | mOuterWindow->GetCurrentInnerWindow() && |
michael@0 | 359 | mOuterWindow->GetCurrentInnerWindow()->GetDoc() == mDoc); |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | bool IsOuterWindow() const |
michael@0 | 363 | { |
michael@0 | 364 | return !IsInnerWindow(); |
michael@0 | 365 | } |
michael@0 | 366 | |
michael@0 | 367 | virtual bool WouldReuseInnerWindow(nsIDocument *aNewDocument) = 0; |
michael@0 | 368 | |
michael@0 | 369 | /** |
michael@0 | 370 | * Get the docshell in this window. |
michael@0 | 371 | */ |
michael@0 | 372 | nsIDocShell *GetDocShell() |
michael@0 | 373 | { |
michael@0 | 374 | if (mOuterWindow) { |
michael@0 | 375 | return mOuterWindow->mDocShell; |
michael@0 | 376 | } |
michael@0 | 377 | |
michael@0 | 378 | return mDocShell; |
michael@0 | 379 | } |
michael@0 | 380 | |
michael@0 | 381 | /** |
michael@0 | 382 | * Set the docshell in the window. Must not be called with a null docshell |
michael@0 | 383 | * (use DetachFromDocShell for that). |
michael@0 | 384 | */ |
michael@0 | 385 | virtual void SetDocShell(nsIDocShell *aDocShell) = 0; |
michael@0 | 386 | |
michael@0 | 387 | /** |
michael@0 | 388 | * Detach an outer window from its docshell. |
michael@0 | 389 | */ |
michael@0 | 390 | virtual void DetachFromDocShell() = 0; |
michael@0 | 391 | |
michael@0 | 392 | /** |
michael@0 | 393 | * Set a new document in the window. Calling this method will in |
michael@0 | 394 | * most cases create a new inner window. If this method is called on |
michael@0 | 395 | * an inner window the call will be forewarded to the outer window, |
michael@0 | 396 | * if the inner window is not the current inner window an |
michael@0 | 397 | * NS_ERROR_NOT_AVAILABLE error code will be returned. This may be |
michael@0 | 398 | * called with a pointer to the current document, in that case the |
michael@0 | 399 | * document remains unchanged, but a new inner window will be |
michael@0 | 400 | * created. |
michael@0 | 401 | * |
michael@0 | 402 | * aDocument must not be null. |
michael@0 | 403 | */ |
michael@0 | 404 | virtual nsresult SetNewDocument(nsIDocument *aDocument, |
michael@0 | 405 | nsISupports *aState, |
michael@0 | 406 | bool aForceReuseInnerWindow) = 0; |
michael@0 | 407 | |
michael@0 | 408 | /** |
michael@0 | 409 | * Set the opener window. aOriginalOpener is true if and only if this is the |
michael@0 | 410 | * original opener for the window. That is, it can only be true at most once |
michael@0 | 411 | * during the life cycle of a window, and then only the first time |
michael@0 | 412 | * SetOpenerWindow is called. It might never be true, of course, if the |
michael@0 | 413 | * window does not have an opener when it's created. |
michael@0 | 414 | */ |
michael@0 | 415 | virtual void SetOpenerWindow(nsIDOMWindow* aOpener, |
michael@0 | 416 | bool aOriginalOpener) = 0; |
michael@0 | 417 | |
michael@0 | 418 | virtual void EnsureSizeUpToDate() = 0; |
michael@0 | 419 | |
michael@0 | 420 | /** |
michael@0 | 421 | * Callback for notifying a window about a modal dialog being |
michael@0 | 422 | * opened/closed with the window as a parent. |
michael@0 | 423 | */ |
michael@0 | 424 | virtual void EnterModalState() = 0; |
michael@0 | 425 | virtual void LeaveModalState() = 0; |
michael@0 | 426 | |
michael@0 | 427 | virtual bool CanClose() = 0; |
michael@0 | 428 | virtual nsresult ForceClose() = 0; |
michael@0 | 429 | |
michael@0 | 430 | bool IsModalContentWindow() const |
michael@0 | 431 | { |
michael@0 | 432 | return mIsModalContentWindow; |
michael@0 | 433 | } |
michael@0 | 434 | |
michael@0 | 435 | /** |
michael@0 | 436 | * Call this to indicate that some node (this window, its document, |
michael@0 | 437 | * or content in that document) has a paint event listener. |
michael@0 | 438 | */ |
michael@0 | 439 | void SetHasPaintEventListeners() |
michael@0 | 440 | { |
michael@0 | 441 | mMayHavePaintEventListener = true; |
michael@0 | 442 | } |
michael@0 | 443 | |
michael@0 | 444 | /** |
michael@0 | 445 | * Call this to check whether some node (this window, its document, |
michael@0 | 446 | * or content in that document) has a paint event listener. |
michael@0 | 447 | */ |
michael@0 | 448 | bool HasPaintEventListeners() |
michael@0 | 449 | { |
michael@0 | 450 | return mMayHavePaintEventListener; |
michael@0 | 451 | } |
michael@0 | 452 | |
michael@0 | 453 | /** |
michael@0 | 454 | * Call this to indicate that some node (this window, its document, |
michael@0 | 455 | * or content in that document) has a touch event listener. |
michael@0 | 456 | */ |
michael@0 | 457 | void SetHasTouchEventListeners() |
michael@0 | 458 | { |
michael@0 | 459 | mMayHaveTouchEventListener = true; |
michael@0 | 460 | MaybeUpdateTouchState(); |
michael@0 | 461 | } |
michael@0 | 462 | |
michael@0 | 463 | bool HasTouchEventListeners() |
michael@0 | 464 | { |
michael@0 | 465 | return mMayHaveTouchEventListener; |
michael@0 | 466 | } |
michael@0 | 467 | |
michael@0 | 468 | /** |
michael@0 | 469 | * Moves the top-level window into fullscreen mode if aIsFullScreen is true, |
michael@0 | 470 | * otherwise exits fullscreen. If aRequireTrust is true, this method only |
michael@0 | 471 | * changes window state in a context trusted for write. |
michael@0 | 472 | */ |
michael@0 | 473 | virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust) = 0; |
michael@0 | 474 | |
michael@0 | 475 | /** |
michael@0 | 476 | * Call this to check whether some node (this window, its document, |
michael@0 | 477 | * or content in that document) has a mouseenter/leave event listener. |
michael@0 | 478 | */ |
michael@0 | 479 | bool HasMouseEnterLeaveEventListeners() |
michael@0 | 480 | { |
michael@0 | 481 | return mMayHaveMouseEnterLeaveEventListener; |
michael@0 | 482 | } |
michael@0 | 483 | |
michael@0 | 484 | /** |
michael@0 | 485 | * Call this to indicate that some node (this window, its document, |
michael@0 | 486 | * or content in that document) has a mouseenter/leave event listener. |
michael@0 | 487 | */ |
michael@0 | 488 | void SetHasMouseEnterLeaveEventListeners() |
michael@0 | 489 | { |
michael@0 | 490 | mMayHaveMouseEnterLeaveEventListener = true; |
michael@0 | 491 | } |
michael@0 | 492 | |
michael@0 | 493 | /** |
michael@0 | 494 | * Call this to check whether some node (this window, its document, |
michael@0 | 495 | * or content in that document) has a Pointerenter/leave event listener. |
michael@0 | 496 | */ |
michael@0 | 497 | bool HasPointerEnterLeaveEventListeners() |
michael@0 | 498 | { |
michael@0 | 499 | return mMayHavePointerEnterLeaveEventListener; |
michael@0 | 500 | } |
michael@0 | 501 | |
michael@0 | 502 | /** |
michael@0 | 503 | * Call this to indicate that some node (this window, its document, |
michael@0 | 504 | * or content in that document) has a Pointerenter/leave event listener. |
michael@0 | 505 | */ |
michael@0 | 506 | void SetHasPointerEnterLeaveEventListeners() |
michael@0 | 507 | { |
michael@0 | 508 | mMayHavePointerEnterLeaveEventListener = true; |
michael@0 | 509 | } |
michael@0 | 510 | |
michael@0 | 511 | |
michael@0 | 512 | virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0; |
michael@0 | 513 | virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey, |
michael@0 | 514 | JS::Handle<JSObject*> aHandler) = 0; |
michael@0 | 515 | |
michael@0 | 516 | /* |
michael@0 | 517 | * Get and set the currently focused element within the document. If |
michael@0 | 518 | * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a |
michael@0 | 519 | * document focus event is needed. |
michael@0 | 520 | * |
michael@0 | 521 | * DO NOT CALL EITHER OF THESE METHODS DIRECTLY. USE THE FOCUS MANAGER |
michael@0 | 522 | * INSTEAD. |
michael@0 | 523 | */ |
michael@0 | 524 | nsIContent* GetFocusedNode() |
michael@0 | 525 | { |
michael@0 | 526 | if (IsOuterWindow()) { |
michael@0 | 527 | return mInnerWindow ? mInnerWindow->mFocusedNode.get() : nullptr; |
michael@0 | 528 | } |
michael@0 | 529 | return mFocusedNode; |
michael@0 | 530 | } |
michael@0 | 531 | virtual void SetFocusedNode(nsIContent* aNode, |
michael@0 | 532 | uint32_t aFocusMethod = 0, |
michael@0 | 533 | bool aNeedsFocus = false) = 0; |
michael@0 | 534 | |
michael@0 | 535 | /** |
michael@0 | 536 | * Retrieves the method that was used to focus the current node. |
michael@0 | 537 | */ |
michael@0 | 538 | virtual uint32_t GetFocusMethod() = 0; |
michael@0 | 539 | |
michael@0 | 540 | /* |
michael@0 | 541 | * Tells the window that it now has focus or has lost focus, based on the |
michael@0 | 542 | * state of aFocus. If this method returns true, then the document loaded |
michael@0 | 543 | * in the window has never received a focus event and expects to receive |
michael@0 | 544 | * one. If false is returned, the document has received a focus event before |
michael@0 | 545 | * and should only receive one if the window is being focused. |
michael@0 | 546 | * |
michael@0 | 547 | * aFocusMethod may be set to one of the focus method constants in |
michael@0 | 548 | * nsIFocusManager to indicate how focus was set. |
michael@0 | 549 | */ |
michael@0 | 550 | virtual bool TakeFocus(bool aFocus, uint32_t aFocusMethod) = 0; |
michael@0 | 551 | |
michael@0 | 552 | /** |
michael@0 | 553 | * Indicates that the window may now accept a document focus event. This |
michael@0 | 554 | * should be called once a document has been loaded into the window. |
michael@0 | 555 | */ |
michael@0 | 556 | virtual void SetReadyForFocus() = 0; |
michael@0 | 557 | |
michael@0 | 558 | /** |
michael@0 | 559 | * Whether the focused content within the window should show a focus ring. |
michael@0 | 560 | */ |
michael@0 | 561 | virtual bool ShouldShowFocusRing() = 0; |
michael@0 | 562 | |
michael@0 | 563 | /** |
michael@0 | 564 | * Set the keyboard indicator state for accelerators and focus rings. |
michael@0 | 565 | */ |
michael@0 | 566 | virtual void SetKeyboardIndicators(UIStateChangeType aShowAccelerators, |
michael@0 | 567 | UIStateChangeType aShowFocusRings) = 0; |
michael@0 | 568 | |
michael@0 | 569 | /** |
michael@0 | 570 | * Get the keyboard indicator state for accelerators and focus rings. |
michael@0 | 571 | */ |
michael@0 | 572 | virtual void GetKeyboardIndicators(bool* aShowAccelerators, |
michael@0 | 573 | bool* aShowFocusRings) = 0; |
michael@0 | 574 | |
michael@0 | 575 | /** |
michael@0 | 576 | * Indicates that the page in the window has been hidden. This is used to |
michael@0 | 577 | * reset the focus state. |
michael@0 | 578 | */ |
michael@0 | 579 | virtual void PageHidden() = 0; |
michael@0 | 580 | |
michael@0 | 581 | /** |
michael@0 | 582 | * Instructs this window to asynchronously dispatch a hashchange event. This |
michael@0 | 583 | * method must be called on an inner window. |
michael@0 | 584 | */ |
michael@0 | 585 | virtual nsresult DispatchAsyncHashchange(nsIURI *aOldURI, |
michael@0 | 586 | nsIURI *aNewURI) = 0; |
michael@0 | 587 | |
michael@0 | 588 | /** |
michael@0 | 589 | * Instructs this window to synchronously dispatch a popState event. |
michael@0 | 590 | */ |
michael@0 | 591 | virtual nsresult DispatchSyncPopState() = 0; |
michael@0 | 592 | |
michael@0 | 593 | /** |
michael@0 | 594 | * Tell this window that it should listen for sensor changes of the given |
michael@0 | 595 | * type. |
michael@0 | 596 | * |
michael@0 | 597 | * Inner windows only. |
michael@0 | 598 | */ |
michael@0 | 599 | virtual void EnableDeviceSensor(uint32_t aType) = 0; |
michael@0 | 600 | |
michael@0 | 601 | /** |
michael@0 | 602 | * Tell this window that it should remove itself from sensor change |
michael@0 | 603 | * notifications. |
michael@0 | 604 | * |
michael@0 | 605 | * Inner windows only. |
michael@0 | 606 | */ |
michael@0 | 607 | virtual void DisableDeviceSensor(uint32_t aType) = 0; |
michael@0 | 608 | |
michael@0 | 609 | virtual void EnableTimeChangeNotifications() = 0; |
michael@0 | 610 | virtual void DisableTimeChangeNotifications() = 0; |
michael@0 | 611 | |
michael@0 | 612 | #ifdef MOZ_B2G |
michael@0 | 613 | /** |
michael@0 | 614 | * Tell the window that it should start to listen to the network event of the |
michael@0 | 615 | * given aType. |
michael@0 | 616 | * |
michael@0 | 617 | * Inner windows only. |
michael@0 | 618 | */ |
michael@0 | 619 | virtual void EnableNetworkEvent(uint32_t aType) = 0; |
michael@0 | 620 | |
michael@0 | 621 | /** |
michael@0 | 622 | * Tell the window that it should stop to listen to the network event of the |
michael@0 | 623 | * given aType. |
michael@0 | 624 | * |
michael@0 | 625 | * Inner windows only. |
michael@0 | 626 | */ |
michael@0 | 627 | virtual void DisableNetworkEvent(uint32_t aType) = 0; |
michael@0 | 628 | #endif // MOZ_B2G |
michael@0 | 629 | |
michael@0 | 630 | /** |
michael@0 | 631 | * Tell this window that there is an observer for gamepad input |
michael@0 | 632 | */ |
michael@0 | 633 | virtual void SetHasGamepadEventListener(bool aHasGamepad = true) = 0; |
michael@0 | 634 | |
michael@0 | 635 | /** |
michael@0 | 636 | * Set a arguments for this window. This will be set on the window |
michael@0 | 637 | * right away (if there's an existing document) and it will also be |
michael@0 | 638 | * installed on the window when the next document is loaded. |
michael@0 | 639 | * |
michael@0 | 640 | * This function serves double-duty for passing both |arguments| and |
michael@0 | 641 | * |dialogArguments| back from nsWindowWatcher to nsGlobalWindow. For the |
michael@0 | 642 | * latter, the array is an array of length 0 whose only element is a |
michael@0 | 643 | * DialogArgumentsHolder representing the JS value passed to showModalDialog. |
michael@0 | 644 | */ |
michael@0 | 645 | virtual nsresult SetArguments(nsIArray *aArguments) = 0; |
michael@0 | 646 | |
michael@0 | 647 | /** |
michael@0 | 648 | * NOTE! This function *will* be called on multiple threads so the |
michael@0 | 649 | * implementation must not do any AddRef/Release or other actions that will |
michael@0 | 650 | * mutate internal state. |
michael@0 | 651 | */ |
michael@0 | 652 | virtual uint32_t GetSerial() = 0; |
michael@0 | 653 | |
michael@0 | 654 | /** |
michael@0 | 655 | * Return the window id of this window |
michael@0 | 656 | */ |
michael@0 | 657 | uint64_t WindowID() const { return mWindowID; } |
michael@0 | 658 | |
michael@0 | 659 | /** |
michael@0 | 660 | * Dispatch a custom event with name aEventName targeted at this window. |
michael@0 | 661 | * Returns whether the default action should be performed. |
michael@0 | 662 | */ |
michael@0 | 663 | virtual bool DispatchCustomEvent(const char *aEventName) = 0; |
michael@0 | 664 | |
michael@0 | 665 | /** |
michael@0 | 666 | * Notify the active inner window that the document principal may have changed |
michael@0 | 667 | * and that the compartment principal needs to be updated. |
michael@0 | 668 | */ |
michael@0 | 669 | virtual void RefreshCompartmentPrincipal() = 0; |
michael@0 | 670 | |
michael@0 | 671 | /** |
michael@0 | 672 | * Like nsIDOMWindow::Open, except that we don't navigate to the given URL. |
michael@0 | 673 | */ |
michael@0 | 674 | virtual nsresult |
michael@0 | 675 | OpenNoNavigate(const nsAString& aUrl, const nsAString& aName, |
michael@0 | 676 | const nsAString& aOptions, nsIDOMWindow **_retval) = 0; |
michael@0 | 677 | |
michael@0 | 678 | void AddAudioContext(mozilla::dom::AudioContext* aAudioContext); |
michael@0 | 679 | void RemoveAudioContext(mozilla::dom::AudioContext* aAudioContext); |
michael@0 | 680 | void MuteAudioContexts(); |
michael@0 | 681 | void UnmuteAudioContexts(); |
michael@0 | 682 | |
michael@0 | 683 | // Given an inner window, return its outer if the inner is the current inner. |
michael@0 | 684 | // Otherwise (argument null or not an inner or not current) return null. |
michael@0 | 685 | static nsPIDOMWindow* GetOuterFromCurrentInner(nsPIDOMWindow* aInner) |
michael@0 | 686 | { |
michael@0 | 687 | if (!aInner) { |
michael@0 | 688 | return nullptr; |
michael@0 | 689 | } |
michael@0 | 690 | |
michael@0 | 691 | nsPIDOMWindow* outer = aInner->GetOuterWindow(); |
michael@0 | 692 | if (!outer || outer->GetCurrentInnerWindow() != aInner) { |
michael@0 | 693 | return nullptr; |
michael@0 | 694 | } |
michael@0 | 695 | |
michael@0 | 696 | return outer; |
michael@0 | 697 | } |
michael@0 | 698 | |
michael@0 | 699 | // WebIDL-ish APIs |
michael@0 | 700 | nsPerformance* GetPerformance(); |
michael@0 | 701 | |
michael@0 | 702 | void MarkUncollectableForCCGeneration(uint32_t aGeneration) |
michael@0 | 703 | { |
michael@0 | 704 | mMarkedCCGeneration = aGeneration; |
michael@0 | 705 | } |
michael@0 | 706 | |
michael@0 | 707 | uint32_t GetMarkedCCGeneration() |
michael@0 | 708 | { |
michael@0 | 709 | return mMarkedCCGeneration; |
michael@0 | 710 | } |
michael@0 | 711 | protected: |
michael@0 | 712 | // The nsPIDOMWindow constructor. The aOuterWindow argument should |
michael@0 | 713 | // be null if and only if the created window itself is an outer |
michael@0 | 714 | // window. In all other cases aOuterWindow should be the outer |
michael@0 | 715 | // window for the inner window that is being created. |
michael@0 | 716 | nsPIDOMWindow(nsPIDOMWindow *aOuterWindow); |
michael@0 | 717 | |
michael@0 | 718 | ~nsPIDOMWindow(); |
michael@0 | 719 | |
michael@0 | 720 | void SetChromeEventHandlerInternal(mozilla::dom::EventTarget* aChromeEventHandler) { |
michael@0 | 721 | mChromeEventHandler = aChromeEventHandler; |
michael@0 | 722 | // mParentTarget will be set when the next event is dispatched. |
michael@0 | 723 | mParentTarget = nullptr; |
michael@0 | 724 | } |
michael@0 | 725 | |
michael@0 | 726 | virtual void UpdateParentTarget() = 0; |
michael@0 | 727 | |
michael@0 | 728 | // Helper for creating performance objects. |
michael@0 | 729 | void CreatePerformanceObjectIfNeeded(); |
michael@0 | 730 | |
michael@0 | 731 | // These two variables are special in that they're set to the same |
michael@0 | 732 | // value on both the outer window and the current inner window. Make |
michael@0 | 733 | // sure you keep them in sync! |
michael@0 | 734 | nsCOMPtr<mozilla::dom::EventTarget> mChromeEventHandler; // strong |
michael@0 | 735 | nsCOMPtr<nsIDocument> mDoc; // strong |
michael@0 | 736 | // Cache the URI when mDoc is cleared. |
michael@0 | 737 | nsCOMPtr<nsIURI> mDocumentURI; // strong |
michael@0 | 738 | nsCOMPtr<nsIURI> mDocBaseURI; // strong |
michael@0 | 739 | |
michael@0 | 740 | nsCOMPtr<mozilla::dom::EventTarget> mParentTarget; // strong |
michael@0 | 741 | |
michael@0 | 742 | // These members are only used on outer windows. |
michael@0 | 743 | nsCOMPtr<mozilla::dom::Element> mFrameElement; |
michael@0 | 744 | nsIDocShell *mDocShell; // Weak Reference |
michael@0 | 745 | |
michael@0 | 746 | // mPerformance is only used on inner windows. |
michael@0 | 747 | nsRefPtr<nsPerformance> mPerformance; |
michael@0 | 748 | |
michael@0 | 749 | uint32_t mModalStateDepth; |
michael@0 | 750 | |
michael@0 | 751 | // These variables are only used on inner windows. |
michael@0 | 752 | nsTimeout *mRunningTimeout; |
michael@0 | 753 | |
michael@0 | 754 | uint32_t mMutationBits; |
michael@0 | 755 | |
michael@0 | 756 | bool mIsDocumentLoaded; |
michael@0 | 757 | bool mIsHandlingResizeEvent; |
michael@0 | 758 | bool mIsInnerWindow; |
michael@0 | 759 | bool mMayHavePaintEventListener; |
michael@0 | 760 | bool mMayHaveTouchEventListener; |
michael@0 | 761 | bool mMayHaveMouseEnterLeaveEventListener; |
michael@0 | 762 | bool mMayHavePointerEnterLeaveEventListener; |
michael@0 | 763 | |
michael@0 | 764 | // This variable is used on both inner and outer windows (and they |
michael@0 | 765 | // should match). |
michael@0 | 766 | bool mIsModalContentWindow; |
michael@0 | 767 | |
michael@0 | 768 | // Tracks activation state that's used for :-moz-window-inactive. |
michael@0 | 769 | // Only used on outer windows. |
michael@0 | 770 | bool mIsActive; |
michael@0 | 771 | |
michael@0 | 772 | // Tracks whether our docshell is active. If it is, mIsBackground |
michael@0 | 773 | // is false. Too bad we have so many different concepts of |
michael@0 | 774 | // "active". Only used on outer windows. |
michael@0 | 775 | bool mIsBackground; |
michael@0 | 776 | |
michael@0 | 777 | bool mAudioMuted; |
michael@0 | 778 | float mAudioVolume; |
michael@0 | 779 | |
michael@0 | 780 | // And these are the references between inner and outer windows. |
michael@0 | 781 | nsPIDOMWindow *mInnerWindow; |
michael@0 | 782 | nsCOMPtr<nsPIDOMWindow> mOuterWindow; |
michael@0 | 783 | |
michael@0 | 784 | // the element within the document that is currently focused when this |
michael@0 | 785 | // window is active |
michael@0 | 786 | nsCOMPtr<nsIContent> mFocusedNode; |
michael@0 | 787 | |
michael@0 | 788 | // The AudioContexts created for the current document, if any. |
michael@0 | 789 | nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak |
michael@0 | 790 | |
michael@0 | 791 | // A unique (as long as our 64-bit counter doesn't roll over) id for |
michael@0 | 792 | // this window. |
michael@0 | 793 | uint64_t mWindowID; |
michael@0 | 794 | |
michael@0 | 795 | // This is only used by the inner window. Set to true once we've sent |
michael@0 | 796 | // the (chrome|content)-document-global-created notification. |
michael@0 | 797 | bool mHasNotifiedGlobalCreated; |
michael@0 | 798 | |
michael@0 | 799 | uint32_t mMarkedCCGeneration; |
michael@0 | 800 | }; |
michael@0 | 801 | |
michael@0 | 802 | |
michael@0 | 803 | NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindow, NS_PIDOMWINDOW_IID) |
michael@0 | 804 | |
michael@0 | 805 | #ifdef MOZILLA_INTERNAL_API |
michael@0 | 806 | PopupControlState |
michael@0 | 807 | PushPopupControlState(PopupControlState aState, bool aForce); |
michael@0 | 808 | |
michael@0 | 809 | void |
michael@0 | 810 | PopPopupControlState(PopupControlState aState); |
michael@0 | 811 | |
michael@0 | 812 | #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherInternal |
michael@0 | 813 | #else |
michael@0 | 814 | #define NS_AUTO_POPUP_STATE_PUSHER nsAutoPopupStatePusherExternal |
michael@0 | 815 | #endif |
michael@0 | 816 | |
michael@0 | 817 | // Helper class that helps with pushing and popping popup control |
michael@0 | 818 | // state. Note that this class looks different from within code that's |
michael@0 | 819 | // part of the layout library than it does in code outside the layout |
michael@0 | 820 | // library. We give the two object layouts different names so the symbols |
michael@0 | 821 | // don't conflict, but code should always use the name |
michael@0 | 822 | // |nsAutoPopupStatePusher|. |
michael@0 | 823 | class NS_AUTO_POPUP_STATE_PUSHER |
michael@0 | 824 | { |
michael@0 | 825 | public: |
michael@0 | 826 | #ifdef MOZILLA_INTERNAL_API |
michael@0 | 827 | NS_AUTO_POPUP_STATE_PUSHER(PopupControlState aState, bool aForce = false) |
michael@0 | 828 | : mOldState(::PushPopupControlState(aState, aForce)) |
michael@0 | 829 | { |
michael@0 | 830 | } |
michael@0 | 831 | |
michael@0 | 832 | ~NS_AUTO_POPUP_STATE_PUSHER() |
michael@0 | 833 | { |
michael@0 | 834 | PopPopupControlState(mOldState); |
michael@0 | 835 | } |
michael@0 | 836 | #else |
michael@0 | 837 | NS_AUTO_POPUP_STATE_PUSHER(nsPIDOMWindow *aWindow, PopupControlState aState) |
michael@0 | 838 | : mWindow(aWindow), mOldState(openAbused) |
michael@0 | 839 | { |
michael@0 | 840 | if (aWindow) { |
michael@0 | 841 | mOldState = aWindow->PushPopupControlState(aState, false); |
michael@0 | 842 | } |
michael@0 | 843 | } |
michael@0 | 844 | |
michael@0 | 845 | ~NS_AUTO_POPUP_STATE_PUSHER() |
michael@0 | 846 | { |
michael@0 | 847 | if (mWindow) { |
michael@0 | 848 | mWindow->PopPopupControlState(mOldState); |
michael@0 | 849 | } |
michael@0 | 850 | } |
michael@0 | 851 | #endif |
michael@0 | 852 | |
michael@0 | 853 | protected: |
michael@0 | 854 | #ifndef MOZILLA_INTERNAL_API |
michael@0 | 855 | nsCOMPtr<nsPIDOMWindow> mWindow; |
michael@0 | 856 | #endif |
michael@0 | 857 | PopupControlState mOldState; |
michael@0 | 858 | |
michael@0 | 859 | private: |
michael@0 | 860 | // Hide so that this class can only be stack-allocated |
michael@0 | 861 | static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nullptr; } |
michael@0 | 862 | static void operator delete(void* /*memory*/) {} |
michael@0 | 863 | }; |
michael@0 | 864 | |
michael@0 | 865 | #define nsAutoPopupStatePusher NS_AUTO_POPUP_STATE_PUSHER |
michael@0 | 866 | |
michael@0 | 867 | #endif // nsPIDOMWindow_h__ |