Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: ui/webui/resources/js/cr/ui/focus_manager.js

Issue 418663002: Typecheck JS files for chrome://help before doing import transition (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@json_to_pydict
Patch Set: Resolve 3 comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« compiled_resources.py ('K') | « ui/webui/resources/js/assert.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('cr.ui', function() { 5 cr.define('cr.ui', function() {
6 /** 6 /**
7 * Constructor for FocusManager singleton. Checks focus of elements to ensure 7 * Constructor for FocusManager singleton. Checks focus of elements to ensure
8 * that elements in "background" pages (i.e., those in a dialog that is not 8 * that elements in "background" pages (i.e., those in a dialog that is not
9 * the topmost overlay) do not receive focus. 9 * the topmost overlay) do not receive focus.
10 * @constructor 10 * @constructor
11 */ 11 */
12 function FocusManager() { 12 function FocusManager() {
13 } 13 }
14 14
15 FocusManager.prototype = { 15 FocusManager.prototype = {
16 /** 16 /**
17 * Whether focus is being transferred backward or forward through the DOM. 17 * Whether focus is being transferred backward or forward through the DOM.
18 * @type {boolean} 18 * @type {boolean}
19 * @private 19 * @private
20 */ 20 */
21 focusDirBackwards_: false, 21 focusDirBackwards_: false,
22 22
23 /** 23 /**
24 * Determines whether the |child| is a descendant of |parent| in the page's 24 * Determines whether the |child| is a descendant of |parent| in the page's
25 * DOM. 25 * DOM.
26 * @param {Element} parent The parent element to test. 26 * @param {Node} parent The parent element to test.
27 * @param {Element} child The child element to test. 27 * @param {Node} child The child element to test.
28 * @return {boolean} True if |child| is a descendant of |parent|. 28 * @return {boolean} True if |child| is a descendant of |parent|.
29 * @private 29 * @private
30 */ 30 */
31 isDescendantOf_: function(parent, child) { 31 isDescendantOf_: function(parent, child) {
32 return parent && !(parent === child) && parent.contains(child); 32 return !!parent && !(parent === child) && parent.contains(child);
33 }, 33 },
34 34
35 /** 35 /**
36 * Returns the parent element containing all elements which should be 36 * Returns the parent element containing all elements which should be
37 * allowed to receive focus. 37 * allowed to receive focus.
38 * @return {Element} The element containing focusable elements. 38 * @return {Element} The element containing focusable elements.
39 */ 39 */
40 getFocusParent: function() { 40 getFocusParent: function() {
41 return document.body; 41 return document.body;
42 }, 42 },
43 43
44 /** 44 /**
45 * Returns the elements on the page capable of receiving focus. 45 * Returns the elements on the page capable of receiving focus.
46 * @return {Array.Element} The focusable elements. 46 * @return {Array.<Element>} The focusable elements.
47 */ 47 */
48 getFocusableElements_: function() { 48 getFocusableElements_: function() {
49 var focusableDiv = this.getFocusParent(); 49 var focusableDiv = this.getFocusParent();
50 50
51 // Create a TreeWalker object to traverse the DOM from |focusableDiv|. 51 // Create a TreeWalker object to traverse the DOM from |focusableDiv|.
52 var treeWalker = document.createTreeWalker( 52 var treeWalker = document.createTreeWalker(
53 focusableDiv, 53 focusableDiv,
54 NodeFilter.SHOW_ELEMENT, 54 NodeFilter.SHOW_ELEMENT,
55 { acceptNode: function(node) { 55 /** @type {NodeFilter} */
56 ({
57 acceptNode: function(node) {
56 var style = window.getComputedStyle(node); 58 var style = window.getComputedStyle(node);
57 // Reject all hidden nodes. FILTER_REJECT also rejects these 59 // Reject all hidden nodes. FILTER_REJECT also rejects these
58 // nodes' children, so non-hidden elements that are descendants of 60 // nodes' children, so non-hidden elements that are descendants of
59 // hidden <div>s will correctly be rejected. 61 // hidden <div>s will correctly be rejected.
60 if (node.hidden || style.display == 'none' || 62 if (node.hidden || style.display == 'none' ||
61 style.visibility == 'hidden') { 63 style.visibility == 'hidden') {
62 return NodeFilter.FILTER_REJECT; 64 return NodeFilter.FILTER_REJECT;
63 } 65 }
64 66
65 // Skip nodes that cannot receive focus. FILTER_SKIP does not 67 // Skip nodes that cannot receive focus. FILTER_SKIP does not
66 // cause this node's children also to be skipped. 68 // cause this node's children also to be skipped.
67 if (node.disabled || node.tabIndex < 0) 69 if (node.disabled || node.tabIndex < 0)
68 return NodeFilter.FILTER_SKIP; 70 return NodeFilter.FILTER_SKIP;
69 71
70 // Accept nodes that are non-hidden and focusable. 72 // Accept nodes that are non-hidden and focusable.
71 return NodeFilter.FILTER_ACCEPT; 73 return NodeFilter.FILTER_ACCEPT;
72 } 74 }
73 }, 75 }),
74 false); 76 false);
75 77
76 var focusable = []; 78 var focusable = [];
77 while (treeWalker.nextNode()) 79 while (treeWalker.nextNode())
78 focusable.push(treeWalker.currentNode); 80 focusable.push(treeWalker.currentNode);
79 81
80 return focusable; 82 return focusable;
81 }, 83 },
82 84
83 /** 85 /**
84 * Dispatches an 'elementFocused' event to notify an element that it has 86 * Dispatches an 'elementFocused' event to notify an element that it has
85 * received focus. When focus wraps around within the a page, only the 87 * received focus. When focus wraps around within the a page, only the
86 * element that has focus after the wrapping receives an 'elementFocused' 88 * element that has focus after the wrapping receives an 'elementFocused'
87 * event. This differs from the native 'focus' event which is received by 89 * event. This differs from the native 'focus' event which is received by
88 * an element outside the page first, followed by a 'focus' on an element 90 * an element outside the page first, followed by a 'focus' on an element
89 * within the page after the FocusManager has intervened. 91 * within the page after the FocusManager has intervened.
90 * @param {Element} element The element that has received focus. 92 * @param {EventTarget} element The element that has received focus.
91 * @private 93 * @private
92 */ 94 */
93 dispatchFocusEvent_: function(element) { 95 dispatchFocusEvent_: function(element) {
94 cr.dispatchSimpleEvent(element, 'elementFocused', true, false); 96 cr.dispatchSimpleEvent(element, 'elementFocused', true, false);
95 }, 97 },
96 98
97 /** 99 /**
98 * Attempts to focus the appropriate element in the current dialog. 100 * Attempts to focus the appropriate element in the current dialog.
99 * @private 101 * @private
100 */ 102 */
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 }, 150 },
149 151
150 /** 152 /**
151 * Handler for focus events on the page. 153 * Handler for focus events on the page.
152 * @param {Event} event The focus event. 154 * @param {Event} event The focus event.
153 * @private 155 * @private
154 */ 156 */
155 onDocumentFocus_: function(event) { 157 onDocumentFocus_: function(event) {
156 // If the element being focused is a descendant of the currently visible 158 // If the element being focused is a descendant of the currently visible
157 // page, focus is valid. 159 // page, focus is valid.
158 if (this.isDescendantOf_(this.getFocusParent(), event.target)) { 160 var targetNode = /** @type {Node} */(event.target);
161 if (this.isDescendantOf_(this.getFocusParent(), targetNode)) {
159 this.dispatchFocusEvent_(event.target); 162 this.dispatchFocusEvent_(event.target);
160 return; 163 return;
161 } 164 }
162 165
163 // Focus event handlers for descendant elements might dispatch another 166 // Focus event handlers for descendant elements might dispatch another
164 // focus event. 167 // focus event.
165 event.stopPropagation(); 168 event.stopPropagation();
166 169
167 // The target of the focus event is not in the topmost visible page and 170 // The target of the focus event is not in the topmost visible page and
168 // should not be focused. 171 // should not be focused.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 window.focus(); 230 window.focus();
228 event.preventDefault(); 231 event.preventDefault();
229 } 232 }
230 }, false); 233 }, false);
231 }; 234 };
232 235
233 return { 236 return {
234 FocusManager: FocusManager, 237 FocusManager: FocusManager,
235 }; 238 };
236 }); 239 });
OLDNEW
« compiled_resources.py ('K') | « ui/webui/resources/js/assert.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698