dom/base/nsFocusManager.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsFocusManager_h___
michael@0 7 #define nsFocusManager_h___
michael@0 8
michael@0 9 #include "nsCycleCollectionParticipant.h"
michael@0 10 #include "nsIDocument.h"
michael@0 11 #include "nsIFocusManager.h"
michael@0 12 #include "nsIObserver.h"
michael@0 13 #include "nsIWidget.h"
michael@0 14 #include "nsWeakReference.h"
michael@0 15 #include "mozilla/Attributes.h"
michael@0 16
michael@0 17 #define FOCUSMETHOD_MASK 0xF000
michael@0 18 #define FOCUSMETHODANDRING_MASK 0xF0F000
michael@0 19
michael@0 20 #define FOCUSMANAGER_CONTRACTID "@mozilla.org/focus-manager;1"
michael@0 21
michael@0 22 class nsIContent;
michael@0 23 class nsIDocShellTreeItem;
michael@0 24 class nsPIDOMWindow;
michael@0 25
michael@0 26 struct nsDelayedBlurOrFocusEvent;
michael@0 27
michael@0 28 /**
michael@0 29 * The focus manager keeps track of where the focus is, that is, the node
michael@0 30 * which receives key events.
michael@0 31 */
michael@0 32
michael@0 33 class nsFocusManager MOZ_FINAL : public nsIFocusManager,
michael@0 34 public nsIObserver,
michael@0 35 public nsSupportsWeakReference
michael@0 36 {
michael@0 37 typedef mozilla::widget::InputContextAction InputContextAction;
michael@0 38
michael@0 39 public:
michael@0 40
michael@0 41 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFocusManager, nsIFocusManager)
michael@0 42 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
michael@0 43 NS_DECL_NSIOBSERVER
michael@0 44 NS_DECL_NSIFOCUSMANAGER
michael@0 45
michael@0 46 // called to initialize and stop the focus manager at startup and shutdown
michael@0 47 static nsresult Init();
michael@0 48 static void Shutdown();
michael@0 49
michael@0 50 /**
michael@0 51 * Retrieve the single focus manager.
michael@0 52 */
michael@0 53 static nsFocusManager* GetFocusManager() { return sInstance; }
michael@0 54
michael@0 55 /**
michael@0 56 * A faster version of nsIFocusManager::GetFocusedElement, returning a
michael@0 57 * raw nsIContent pointer (instead of having AddRef-ed nsIDOMElement
michael@0 58 * pointer filled in to an out-parameter).
michael@0 59 */
michael@0 60 nsIContent* GetFocusedContent() { return mFocusedContent; }
michael@0 61
michael@0 62 /**
michael@0 63 * Return a focused window. Version of nsIFocusManager::GetFocusedWindow.
michael@0 64 */
michael@0 65 nsPIDOMWindow* GetFocusedWindow() const { return mFocusedWindow; }
michael@0 66
michael@0 67 /**
michael@0 68 * Return an active window. Version of nsIFocusManager::GetActiveWindow.
michael@0 69 */
michael@0 70 nsPIDOMWindow* GetActiveWindow() const { return mActiveWindow; }
michael@0 71
michael@0 72 /**
michael@0 73 * Called when content has been removed.
michael@0 74 */
michael@0 75 nsresult ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
michael@0 76
michael@0 77 /**
michael@0 78 * Called when mouse button down event handling is started and finished.
michael@0 79 */
michael@0 80 void SetMouseButtonDownHandlingDocument(nsIDocument* aDocument)
michael@0 81 {
michael@0 82 NS_ASSERTION(!aDocument || !mMouseDownEventHandlingDocument,
michael@0 83 "Some mouse button down events are nested?");
michael@0 84 mMouseDownEventHandlingDocument = aDocument;
michael@0 85 }
michael@0 86
michael@0 87 /**
michael@0 88 * Update the caret with current mode (whether in caret browsing mode or not).
michael@0 89 */
michael@0 90 void UpdateCaretForCaretBrowsingMode();
michael@0 91
michael@0 92 /**
michael@0 93 * Returns the content node that would be focused if aWindow was in an
michael@0 94 * active window. This will traverse down the frame hierarchy, starting at
michael@0 95 * the given window aWindow. Sets aFocusedWindow to the window with the
michael@0 96 * document containing aFocusedContent. If no element is focused,
michael@0 97 * aFocusedWindow may be still be set -- this means that the document is
michael@0 98 * focused but no element within it is focused.
michael@0 99 *
michael@0 100 * aWindow and aFocusedWindow must both be non-null.
michael@0 101 */
michael@0 102 static nsIContent* GetFocusedDescendant(nsPIDOMWindow* aWindow, bool aDeep,
michael@0 103 nsPIDOMWindow** aFocusedWindow);
michael@0 104
michael@0 105 /**
michael@0 106 * Returns the content node that focus will be redirected to if aContent was
michael@0 107 * focused. This is used for the special case of certain XUL elements such
michael@0 108 * as textboxes which redirect focus to an anonymous child.
michael@0 109 *
michael@0 110 * aContent must be non-null.
michael@0 111 *
michael@0 112 * XXXndeakin this should be removed eventually but I want to do that as
michael@0 113 * followup work.
michael@0 114 */
michael@0 115 static nsIContent* GetRedirectedFocus(nsIContent* aContent);
michael@0 116
michael@0 117 /**
michael@0 118 * Returns an InputContextAction cause for aFlags.
michael@0 119 */
michael@0 120 static InputContextAction::Cause GetFocusMoveActionCause(uint32_t aFlags);
michael@0 121
michael@0 122 static bool sMouseFocusesFormControl;
michael@0 123
michael@0 124 static void MarkUncollectableForCCGeneration(uint32_t aGeneration);
michael@0 125 protected:
michael@0 126
michael@0 127 nsFocusManager();
michael@0 128 ~nsFocusManager();
michael@0 129
michael@0 130 /**
michael@0 131 * Ensure that the widget associated with the currently focused window is
michael@0 132 * focused at the widget level.
michael@0 133 */
michael@0 134 void EnsureCurrentWidgetFocused();
michael@0 135
michael@0 136 /**
michael@0 137 * Blur whatever is currently focused and focus aNewContent. aFlags is a
michael@0 138 * bitmask of the flags defined in nsIFocusManager. If aFocusChanged is
michael@0 139 * true, then the focus has actually shifted and the caret position will be
michael@0 140 * updated to the new focus, aNewContent will be scrolled into view (unless
michael@0 141 * a flag disables this) and the focus method for the window will be updated.
michael@0 142 * If aAdjustWidget is false, don't change the widget focus state.
michael@0 143 *
michael@0 144 * All actual focus changes must use this method to do so. (as opposed
michael@0 145 * to those that update the focus in an inactive window for instance).
michael@0 146 */
michael@0 147 void SetFocusInner(nsIContent* aNewContent, int32_t aFlags,
michael@0 148 bool aFocusChanged, bool aAdjustWidget);
michael@0 149
michael@0 150 /**
michael@0 151 * Returns true if aPossibleAncestor is the same as aWindow or an
michael@0 152 * ancestor of aWindow.
michael@0 153 */
michael@0 154 bool IsSameOrAncestor(nsPIDOMWindow* aPossibleAncestor,
michael@0 155 nsPIDOMWindow* aWindow);
michael@0 156
michael@0 157 /**
michael@0 158 * Returns the window that is the lowest common ancestor of both aWindow1
michael@0 159 * and aWindow2, or null if they share no common ancestor.
michael@0 160 */
michael@0 161 already_AddRefed<nsPIDOMWindow> GetCommonAncestor(nsPIDOMWindow* aWindow1,
michael@0 162 nsPIDOMWindow* aWindow2);
michael@0 163
michael@0 164 /**
michael@0 165 * When aNewWindow is focused, adjust the ancestors of aNewWindow so that they
michael@0 166 * also have their corresponding frames focused. Thus, one can start at
michael@0 167 * the active top-level window and navigate down the currently focused
michael@0 168 * elements for each frame in the tree to get to aNewWindow.
michael@0 169 */
michael@0 170 void AdjustWindowFocus(nsPIDOMWindow* aNewWindow, bool aCheckPermission);
michael@0 171
michael@0 172 /**
michael@0 173 * Returns true if aWindow is visible.
michael@0 174 */
michael@0 175 bool IsWindowVisible(nsPIDOMWindow* aWindow);
michael@0 176
michael@0 177 /**
michael@0 178 * Returns true if aContent is a root element and not focusable.
michael@0 179 * I.e., even if aContent is editable root element, this returns true when
michael@0 180 * the document is in designMode.
michael@0 181 *
michael@0 182 * @param aContent must not be null and must be in a document.
michael@0 183 */
michael@0 184 bool IsNonFocusableRoot(nsIContent* aContent);
michael@0 185
michael@0 186 /**
michael@0 187 * Checks and returns aContent if it may be focused, another content node if
michael@0 188 * the focus should be retargeted at another node, or null if the node
michael@0 189 * cannot be focused. aFlags are the flags passed to SetFocus and similar
michael@0 190 * methods.
michael@0 191 *
michael@0 192 * An element is focusable if it is in a document, the document isn't in
michael@0 193 * print preview mode and the element has an nsIFrame where the
michael@0 194 * CheckIfFocusable method returns true. For <area> elements, there is no
michael@0 195 * frame, so only the IsFocusable method on the content node must be
michael@0 196 * true.
michael@0 197 */
michael@0 198 nsIContent* CheckIfFocusable(nsIContent* aContent, uint32_t aFlags);
michael@0 199
michael@0 200 /**
michael@0 201 * Blurs the currently focused element. Returns false if another element was
michael@0 202 * focused as a result. This would mean that the caller should not proceed
michael@0 203 * with a pending call to Focus. Normally, true would be returned.
michael@0 204 *
michael@0 205 * The currently focused element within aWindowToClear will be cleared.
michael@0 206 * aWindowToClear may be null, which means that no window is cleared. This
michael@0 207 * will be the case, for example, when lowering a window, as we want to fire
michael@0 208 * a blur, but not actually change what element would be focused, so that
michael@0 209 * the same element will be focused again when the window is raised.
michael@0 210 *
michael@0 211 * aAncestorWindowToFocus should be set to the common ancestor of the window
michael@0 212 * that is being blurred and the window that is going to focused, when
michael@0 213 * switching focus to a sibling window.
michael@0 214 *
michael@0 215 * aIsLeavingDocument should be set to true if the document/window is being
michael@0 216 * blurred as well. Document/window blur events will be fired. It should be
michael@0 217 * false if an element is the same document is about to be focused.
michael@0 218 *
michael@0 219 * If aAdjustWidget is false, don't change the widget focus state.
michael@0 220 */
michael@0 221 bool Blur(nsPIDOMWindow* aWindowToClear,
michael@0 222 nsPIDOMWindow* aAncestorWindowToFocus,
michael@0 223 bool aIsLeavingDocument,
michael@0 224 bool aAdjustWidget);
michael@0 225
michael@0 226 /**
michael@0 227 * Focus an element in the active window and child frame.
michael@0 228 *
michael@0 229 * aWindow is the window containing the element aContent to focus.
michael@0 230 *
michael@0 231 * aFlags is the flags passed to the various focus methods in
michael@0 232 * nsIFocusManager.
michael@0 233 *
michael@0 234 * aIsNewDocument should be true if a new document is being focused.
michael@0 235 * Document/window focus events will be fired.
michael@0 236 *
michael@0 237 * aFocusChanged should be true if a new content node is being focused, so
michael@0 238 * the focused content will be scrolled into view and the caret position
michael@0 239 * will be updated. If false is passed, then a window is simply being
michael@0 240 * refocused, for instance, due to a window being raised, or a tab is being
michael@0 241 * switched to.
michael@0 242 *
michael@0 243 * If aFocusChanged is true, then the focus has moved to a new location.
michael@0 244 * Otherwise, the focus is just being updated because the window was
michael@0 245 * raised.
michael@0 246 *
michael@0 247 * aWindowRaised should be true if the window is being raised. In this case,
michael@0 248 * command updaters will not be called.
michael@0 249 *
michael@0 250 * If aAdjustWidget is false, don't change the widget focus state.
michael@0 251 */
michael@0 252 void Focus(nsPIDOMWindow* aWindow,
michael@0 253 nsIContent* aContent,
michael@0 254 uint32_t aFlags,
michael@0 255 bool aIsNewDocument,
michael@0 256 bool aFocusChanged,
michael@0 257 bool aWindowRaised,
michael@0 258 bool aAdjustWidget);
michael@0 259
michael@0 260 /**
michael@0 261 * Fires a focus or blur event at aTarget.
michael@0 262 *
michael@0 263 * aType should be either NS_FOCUS_CONTENT or NS_BLUR_CONTENT. For blur
michael@0 264 * events, aFocusMethod should normally be non-zero.
michael@0 265 *
michael@0 266 * aWindowRaised should only be true if called from WindowRaised.
michael@0 267 */
michael@0 268 void SendFocusOrBlurEvent(uint32_t aType,
michael@0 269 nsIPresShell* aPresShell,
michael@0 270 nsIDocument* aDocument,
michael@0 271 nsISupports* aTarget,
michael@0 272 uint32_t aFocusMethod,
michael@0 273 bool aWindowRaised,
michael@0 274 bool aIsRefocus = false);
michael@0 275
michael@0 276 /**
michael@0 277 * Scrolls aContent into view unless the FLAG_NOSCROLL flag is set.
michael@0 278 */
michael@0 279 void ScrollIntoView(nsIPresShell* aPresShell,
michael@0 280 nsIContent* aContent,
michael@0 281 uint32_t aFlags);
michael@0 282
michael@0 283 /**
michael@0 284 * Raises the top-level window aWindow at the widget level.
michael@0 285 */
michael@0 286 void RaiseWindow(nsPIDOMWindow* aWindow);
michael@0 287
michael@0 288 /**
michael@0 289 * Updates the caret positon and visibility to match the focus.
michael@0 290 *
michael@0 291 * aMoveCaretToFocus should be true to move the caret to aContent.
michael@0 292 *
michael@0 293 * aUpdateVisibility should be true to update whether the caret is
michael@0 294 * visible or not.
michael@0 295 */
michael@0 296 void UpdateCaret(bool aMoveCaretToFocus,
michael@0 297 bool aUpdateVisibility,
michael@0 298 nsIContent* aContent);
michael@0 299
michael@0 300 /**
michael@0 301 * Helper method to move the caret to the focused element aContent.
michael@0 302 */
michael@0 303 void MoveCaretToFocus(nsIPresShell* aPresShell, nsIContent* aContent);
michael@0 304
michael@0 305 /**
michael@0 306 * Makes the caret visible or not, depending on aVisible.
michael@0 307 */
michael@0 308 nsresult SetCaretVisible(nsIPresShell* aPresShell,
michael@0 309 bool aVisible,
michael@0 310 nsIContent* aContent);
michael@0 311
michael@0 312
michael@0 313 // the remaining functions are used for tab key and document-navigation
michael@0 314
michael@0 315 /**
michael@0 316 * Retrieves the start and end points of the current selection for
michael@0 317 * aDocument and stores them in aStartContent and aEndContent.
michael@0 318 */
michael@0 319 nsresult GetSelectionLocation(nsIDocument* aDocument,
michael@0 320 nsIPresShell* aPresShell,
michael@0 321 nsIContent **aStartContent,
michael@0 322 nsIContent **aEndContent);
michael@0 323
michael@0 324 /**
michael@0 325 * Helper function for MoveFocus which determines the next element
michael@0 326 * to move the focus to and returns it in aNextContent.
michael@0 327 *
michael@0 328 * aWindow is the window to adjust the focus within, and aStart is
michael@0 329 * the element to start navigation from. For tab key navigation,
michael@0 330 * this should be the currently focused element.
michael@0 331 *
michael@0 332 * aType is the type passed to MoveFocus. If aNoParentTraversal is set,
michael@0 333 * navigation is not done to parent documents and iteration returns to the
michael@0 334 * beginning (or end) of the starting document.
michael@0 335 */
michael@0 336 nsresult DetermineElementToMoveFocus(nsPIDOMWindow* aWindow,
michael@0 337 nsIContent* aStart,
michael@0 338 int32_t aType, bool aNoParentTraversal,
michael@0 339 nsIContent** aNextContent);
michael@0 340
michael@0 341 /**
michael@0 342 * Retrieve the next tabbable element within a document, using focusability
michael@0 343 * and tabindex to determine the tab order. The element is returned in
michael@0 344 * aResultContent.
michael@0 345 *
michael@0 346 * aRootContent is the root node -- nodes above this will not be examined.
michael@0 347 * Typically this will be the root node of a document, but could also be
michael@0 348 * a popup node.
michael@0 349 *
michael@0 350 * aOriginalStartContent is the content which was originally the starting
michael@0 351 * node, in the case of recursive or looping calls.
michael@0 352 *
michael@0 353 * aStartContent is the starting point for this call of this method.
michael@0 354 * If aStartContent doesn't have visual representation, the next content
michael@0 355 * object, which does have a primary frame, will be used as a start.
michael@0 356 * If that content object is focusable, the method may return it.
michael@0 357 *
michael@0 358 * aForward should be true for forward navigation or false for backward
michael@0 359 * navigation.
michael@0 360 *
michael@0 361 * aCurrentTabIndex is the current tabindex.
michael@0 362 *
michael@0 363 * aIgnoreTabIndex to ignore the current tabindex and find the element
michael@0 364 * irrespective or the tab index. This will be true when a selection is
michael@0 365 * active, since we just want to focus the next element in tree order
michael@0 366 * from where the selection is. Similarly, if the starting element isn't
michael@0 367 * focusable, since it doesn't really have a defined tab index.
michael@0 368 */
michael@0 369 nsresult GetNextTabbableContent(nsIPresShell* aPresShell,
michael@0 370 nsIContent* aRootContent,
michael@0 371 nsIContent* aOriginalStartContent,
michael@0 372 nsIContent* aStartContent,
michael@0 373 bool aForward,
michael@0 374 int32_t aCurrentTabIndex,
michael@0 375 bool aIgnoreTabIndex,
michael@0 376 nsIContent** aResultContent);
michael@0 377
michael@0 378 /**
michael@0 379 * Get the next tabbable image map area and returns it.
michael@0 380 *
michael@0 381 * aForward should be true for forward navigation or false for backward
michael@0 382 * navigation.
michael@0 383 *
michael@0 384 * aCurrentTabIndex is the current tabindex.
michael@0 385 *
michael@0 386 * aImageContent is the image.
michael@0 387 *
michael@0 388 * aStartContent is the current image map area.
michael@0 389 */
michael@0 390 nsIContent* GetNextTabbableMapArea(bool aForward,
michael@0 391 int32_t aCurrentTabIndex,
michael@0 392 nsIContent* aImageContent,
michael@0 393 nsIContent* aStartContent);
michael@0 394
michael@0 395 /**
michael@0 396 * Return the next valid tabindex value after aCurrentTabIndex, if aForward
michael@0 397 * is true, or the previous tabindex value if aForward is false. aParent is
michael@0 398 * the node from which to start looking for tab indicies.
michael@0 399 */
michael@0 400 int32_t GetNextTabIndex(nsIContent* aParent,
michael@0 401 int32_t aCurrentTabIndex,
michael@0 402 bool aForward);
michael@0 403
michael@0 404 /**
michael@0 405 * Retrieves and returns the root node from aDocument to be focused. Will
michael@0 406 * return null if the root node cannot be focused. There are several reasons
michael@0 407 * for this:
michael@0 408 *
michael@0 409 * - if aIsForDocNavigation is true, and aWindow is in an <iframe>.
michael@0 410 * - if aIsForDocNavigation is false, and aWindow is a chrome shell.
michael@0 411 * - if aCheckVisibility is true and the aWindow is not visible.
michael@0 412 * - if aDocument is a frameset document.
michael@0 413 */
michael@0 414 nsIContent* GetRootForFocus(nsPIDOMWindow* aWindow,
michael@0 415 nsIDocument* aDocument,
michael@0 416 bool aIsForDocNavigation,
michael@0 417 bool aCheckVisibility);
michael@0 418
michael@0 419 /**
michael@0 420 * Get the last docshell child of aItem and return it in aResult.
michael@0 421 */
michael@0 422 void GetLastDocShell(nsIDocShellTreeItem* aItem,
michael@0 423 nsIDocShellTreeItem** aResult);
michael@0 424
michael@0 425 /**
michael@0 426 * Get the next docshell child of aItem and return it in aResult.
michael@0 427 */
michael@0 428 void GetNextDocShell(nsIDocShellTreeItem* aItem,
michael@0 429 nsIDocShellTreeItem** aResult);
michael@0 430
michael@0 431 /**
michael@0 432 * Get the previous docshell child of aItem and return it in aResult.
michael@0 433 */
michael@0 434 void GetPreviousDocShell(nsIDocShellTreeItem* aItem,
michael@0 435 nsIDocShellTreeItem** aResult);
michael@0 436
michael@0 437 /**
michael@0 438 * Determine the first panel with focusable content in document tab order
michael@0 439 * from the given document. aForward indicates the direction to scan. If
michael@0 440 * aCurrentPopup is set to a panel, the next or previous popup after
michael@0 441 * aCurrentPopup after it is used. If aCurrentPopup is null, then the first
michael@0 442 * or last popup is used. If a panel has no focusable content, it is skipped.
michael@0 443 * Null is returned if no panel is open or no open panel contains a focusable
michael@0 444 * element.
michael@0 445 */
michael@0 446 nsIContent* GetNextTabbablePanel(nsIDocument* aDocument, nsIFrame* aCurrentPopup, bool aForward);
michael@0 447
michael@0 448 /**
michael@0 449 * Get the tabbable next document from aStartContent or, if null, the
michael@0 450 * currently focused frame if aForward is true, or the previously tabbable
michael@0 451 * document if aForward is false. If this document is a chrome or frameset
michael@0 452 * document, returns the first focusable element within this document,
michael@0 453 * otherwise, returns the root node of the document.
michael@0 454 *
michael@0 455 *
michael@0 456 * Panels with focusable content are also placed in the cycling order, just
michael@0 457 * after the document containing that panel.
michael@0 458 *
michael@0 459 * This method would be used for document navigation, which is typically
michael@0 460 * invoked by pressing F6.
michael@0 461 */
michael@0 462 nsIContent* GetNextTabbableDocument(nsIContent* aStartContent, bool aForward);
michael@0 463
michael@0 464 /**
michael@0 465 * Retreives a focusable element within the current selection of aWindow.
michael@0 466 * Currently, this only detects links.
michael@0 467 *
michael@0 468 * This is used when MoveFocus is called with a type of MOVEFOCUS_CARET,
michael@0 469 * which is used, for example, to focus links as the caret is moved over
michael@0 470 * them.
michael@0 471 */
michael@0 472 void GetFocusInSelection(nsPIDOMWindow* aWindow,
michael@0 473 nsIContent* aStartSelection,
michael@0 474 nsIContent* aEndSelection,
michael@0 475 nsIContent** aFocusedContent);
michael@0 476
michael@0 477 private:
michael@0 478 // Notify that the focus state of aContent has changed. Note that
michael@0 479 // we need to pass in whether the window should show a focus ring
michael@0 480 // before the SetFocusedNode call on it happened when losing focus
michael@0 481 // and after the SetFocusedNode call when gaining focus, which is
michael@0 482 // why that information needs to be an explicit argument instead of
michael@0 483 // just passing in the window and asking it whether it should show
michael@0 484 // focus rings: in the losing focus case that information could be
michael@0 485 // wrong..
michael@0 486 static void NotifyFocusStateChange(nsIContent* aContent,
michael@0 487 bool aWindowShouldShowFocusRing,
michael@0 488 bool aGettingFocus);
michael@0 489
michael@0 490 void SetFocusedWindowInternal(nsPIDOMWindow* aWindow);
michael@0 491
michael@0 492 // the currently active and front-most top-most window
michael@0 493 nsCOMPtr<nsPIDOMWindow> mActiveWindow;
michael@0 494
michael@0 495 // the child or top-level window that is currently focused. This window will
michael@0 496 // either be the same window as mActiveWindow or a descendant of it.
michael@0 497 // Except during shutdown use SetFocusedWindowInternal to set mFocusedWindow!
michael@0 498 nsCOMPtr<nsPIDOMWindow> mFocusedWindow;
michael@0 499
michael@0 500 // the currently focused content, which is always inside mFocusedWindow. This
michael@0 501 // is a cached copy of the mFocusedWindow's current content. This may be null
michael@0 502 // if no content is focused.
michael@0 503 nsCOMPtr<nsIContent> mFocusedContent;
michael@0 504
michael@0 505 // these fields store a content node temporarily while it is being focused
michael@0 506 // or blurred to ensure that a recursive call doesn't refire the same event.
michael@0 507 // They will always be cleared afterwards.
michael@0 508 nsCOMPtr<nsIContent> mFirstBlurEvent;
michael@0 509 nsCOMPtr<nsIContent> mFirstFocusEvent;
michael@0 510
michael@0 511 // keep track of a window while it is being lowered
michael@0 512 nsCOMPtr<nsPIDOMWindow> mWindowBeingLowered;
michael@0 513
michael@0 514 // synchronized actions cannot be interrupted with events, so queue these up
michael@0 515 // and fire them later.
michael@0 516 nsTArray<nsDelayedBlurOrFocusEvent> mDelayedBlurFocusEvents;
michael@0 517
michael@0 518 // A document which is handling a mouse button down event.
michael@0 519 // When a mouse down event process is finished, ESM sets focus to the target
michael@0 520 // content. Therefore, while DOM event handlers are handling mouse down
michael@0 521 // events, the handlers should be able to steal focus from any elements even
michael@0 522 // if focus is in chrome content. So, if this isn't nullptr and the caller
michael@0 523 // can access the document node, the caller should succeed in moving focus.
michael@0 524 nsCOMPtr<nsIDocument> mMouseDownEventHandlingDocument;
michael@0 525
michael@0 526 static bool sTestMode;
michael@0 527
michael@0 528 // the single focus manager
michael@0 529 static nsFocusManager* sInstance;
michael@0 530 };
michael@0 531
michael@0 532 nsresult
michael@0 533 NS_NewFocusManager(nsIFocusManager** aResult);
michael@0 534
michael@0 535 #endif

mercurial