OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 /** | 5 /** |
6 * Class to manage interactions with the accessibility tree, including moving | 6 * Class to manage interactions with the accessibility tree, including moving |
7 * to and selecting nodes. | 7 * to and selecting nodes. |
8 * | 8 * |
9 * @constructor | 9 * @constructor |
10 * @param {!chrome.automation.AutomationNode} desktop | 10 * @param {!chrome.automation.AutomationNode} desktop |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 this.init_(); | 50 this.init_(); |
51 } | 51 } |
52 | 52 |
53 /** | 53 /** |
54 * Highlight colors for the focus ring to distinguish between different types | 54 * Highlight colors for the focus ring to distinguish between different types |
55 * of nodes. | 55 * of nodes. |
56 * | 56 * |
57 * @const | 57 * @const |
58 */ | 58 */ |
59 AutomationManager.Color = { | 59 AutomationManager.Color = { |
60 SCOPE: '#de742f', // dark orange | 60 SCOPE: '#de742f', // dark orange |
61 GROUP: '#ffbb33', // light orange | 61 GROUP: '#ffbb33', // light orange |
62 LEAF: '#78e428' //light green | 62 LEAF: '#78e428' // light green |
63 }; | 63 }; |
64 | 64 |
65 AutomationManager.prototype = { | 65 AutomationManager.prototype = { |
66 /** | 66 /** |
67 * Set this.node_, this.root_, and this.desktop_ to the desktop node, and | 67 * Set this.node_, this.root_, and this.desktop_ to the desktop node, and |
68 * creates an initial tree walker. | 68 * creates an initial tree walker. |
69 * | 69 * |
70 * @private | 70 * @private |
71 */ | 71 */ |
72 init_: function() { | 72 init_: function() { |
73 console.log('AutomationNode for desktop is loaded'); | 73 console.log('AutomationNode for desktop is loaded'); |
74 this.printNode_(this.node_); | 74 this.printNode_(this.node_); |
75 | 75 |
76 this.desktop_.addEventListener( | 76 this.desktop_.addEventListener( |
77 chrome.automation.EventType.FOCUS, | 77 chrome.automation.EventType.FOCUS, this.handleFocusChange_.bind(this), |
78 this.handleFocusChange_.bind(this), | |
79 false); | 78 false); |
80 | 79 |
81 // TODO(elichtenberg): Eventually use a more specific filter than | 80 // TODO(elichtenberg): Eventually use a more specific filter than |
82 // ALL_TREE_CHANGES. | 81 // ALL_TREE_CHANGES. |
83 chrome.automation.addTreeChangeObserver( | 82 chrome.automation.addTreeChangeObserver( |
84 chrome.automation.TreeChangeObserverFilter.ALL_TREE_CHANGES, | 83 chrome.automation.TreeChangeObserverFilter.ALL_TREE_CHANGES, |
85 this.handleNodeRemoved_.bind(this)); | 84 this.handleNodeRemoved_.bind(this)); |
86 }, | 85 }, |
87 | 86 |
88 /** | 87 /** |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 handleNodeRemoved_: function(treeChange) { | 151 handleNodeRemoved_: function(treeChange) { |
153 // TODO(elichtenberg): Only listen to NODE_REMOVED callbacks. Don't need | 152 // TODO(elichtenberg): Only listen to NODE_REMOVED callbacks. Don't need |
154 // any others. | 153 // any others. |
155 if (treeChange.type !== chrome.automation.TreeChangeType.NODE_REMOVED) | 154 if (treeChange.type !== chrome.automation.TreeChangeType.NODE_REMOVED) |
156 return; | 155 return; |
157 | 156 |
158 // TODO(elichtenberg): Currently not getting NODE_REMOVED event when whole | 157 // TODO(elichtenberg): Currently not getting NODE_REMOVED event when whole |
159 // tree is deleted. Once fixed, can delete this. Should only need to check | 158 // tree is deleted. Once fixed, can delete this. Should only need to check |
160 // if target is current node. | 159 // if target is current node. |
161 let removedByRWA = | 160 let removedByRWA = |
162 treeChange.target.role === chrome.automation.RoleType.ROOT_WEB_AREA | 161 treeChange.target.role === chrome.automation.RoleType.ROOT_WEB_AREA && |
163 && !this.node_.role; | 162 !this.node_.role; |
164 | 163 |
165 if (!removedByRWA && treeChange.target !== this.node_) | 164 if (!removedByRWA && treeChange.target !== this.node_) |
166 return; | 165 return; |
167 | 166 |
168 console.log('Node removed'); | 167 console.log('Node removed'); |
169 chrome.accessibilityPrivate.setFocusRing([]); | 168 chrome.accessibilityPrivate.setFocusRing([]); |
170 | 169 |
171 // Current node not invalid until after treeChange callback, so move to | 170 // Current node not invalid until after treeChange callback, so move to |
172 // valid node after callback. Delay added to prevent moving to another | 171 // valid node after callback. Delay added to prevent moving to another |
173 // node about to be made invalid. If already at a valid node (e.g., user | 172 // node about to be made invalid. If already at a valid node (e.g., user |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 * @param {!chrome.automation.AutomationNode} scope | 292 * @param {!chrome.automation.AutomationNode} scope |
294 * @param {!chrome.automation.AutomationNode=} opt_start | 293 * @param {!chrome.automation.AutomationNode=} opt_start |
295 * @private | 294 * @private |
296 * @return {!AutomationTreeWalker} | 295 * @return {!AutomationTreeWalker} |
297 */ | 296 */ |
298 createTreeWalker_: function(scope, opt_start) { | 297 createTreeWalker_: function(scope, opt_start) { |
299 // If no explicit start node, start walking the tree from |scope|. | 298 // If no explicit start node, start walking the tree from |scope|. |
300 let start = opt_start || scope; | 299 let start = opt_start || scope; |
301 | 300 |
302 let leafPred = function(node) { | 301 let leafPred = function(node) { |
303 return (node !== scope && AutomationPredicate.isSubtreeLeaf(node, scope)) | 302 return (node !== scope && |
304 || !AutomationPredicate.isInterestingSubtree(node); | 303 AutomationPredicate.isSubtreeLeaf(node, scope)) || |
| 304 !AutomationPredicate.isInterestingSubtree(node); |
305 }; | 305 }; |
306 let visitPred = function(node) { | 306 let visitPred = function(node) { |
307 // Avoid visiting the top-level root node (i.e., the desktop node). | 307 // Avoid visiting the top-level root node (i.e., the desktop node). |
308 return node !== this.desktop_ | 308 return node !== this.desktop_ && |
309 && AutomationPredicate.isSubtreeLeaf(node, scope); | 309 AutomationPredicate.isSubtreeLeaf(node, scope); |
310 }.bind(this); | 310 }.bind(this); |
311 | 311 |
312 let restrictions = { | 312 let restrictions = {leaf: leafPred, visit: visitPred}; |
313 leaf: leafPred, | |
314 visit: visitPred | |
315 }; | |
316 return new AutomationTreeWalker(start, scope, restrictions); | 313 return new AutomationTreeWalker(start, scope, restrictions); |
317 }, | 314 }, |
318 | 315 |
319 // TODO(elichtenberg): Move print functions to a custom logger class. Only | 316 // TODO(elichtenberg): Move print functions to a custom logger class. Only |
320 // log when debuggingEnabled is true. | 317 // log when debuggingEnabled is true. |
321 /** | 318 /** |
322 * Print out details about a node. | 319 * Print out details about a node. |
323 * | 320 * |
324 * @param {chrome.automation.AutomationNode} node | 321 * @param {chrome.automation.AutomationNode} node |
325 * @private | 322 * @private |
326 */ | 323 */ |
327 printNode_: function(node) { | 324 printNode_: function(node) { |
328 if (node) { | 325 if (node) { |
329 console.log('Name = ' + node.name); | 326 console.log('Name = ' + node.name); |
330 console.log('Role = ' + node.role); | 327 console.log('Role = ' + node.role); |
331 console.log('Root role = ' + node.root.role); | 328 console.log('Root role = ' + node.root.role); |
332 if (!node.parent) | 329 if (!node.parent) |
333 console.log('At index ' + node.indexInParent + ', has no parent'); | 330 console.log('At index ' + node.indexInParent + ', has no parent'); |
334 else { | 331 else { |
335 let numSiblings = node.parent.children.length; | 332 let numSiblings = node.parent.children.length; |
336 console.log( | 333 console.log( |
337 'At index ' + node.indexInParent + ', there are ' | 334 'At index ' + node.indexInParent + ', there are ' + numSiblings + |
338 + numSiblings + ' siblings'); | 335 ' siblings'); |
339 } | 336 } |
340 console.log('Has ' + node.children.length + ' children'); | 337 console.log('Has ' + node.children.length + ' children'); |
341 } else { | 338 } else { |
342 console.log('Node is null'); | 339 console.log('Node is null'); |
343 } | 340 } |
344 console.log(node); | 341 console.log(node); |
345 console.log('\n'); | 342 console.log('\n'); |
346 }, | 343 }, |
347 | 344 |
348 /** | 345 /** |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 */ | 383 */ |
387 debugMoveToParent: function() { | 384 debugMoveToParent: function() { |
388 let parent = this.treeWalker_.debugMoveToParent(this.node_); | 385 let parent = this.treeWalker_.debugMoveToParent(this.node_); |
389 if (parent) { | 386 if (parent) { |
390 this.node_ = parent; | 387 this.node_ = parent; |
391 this.printNode_(this.node_); | 388 this.printNode_(this.node_); |
392 chrome.accessibilityPrivate.setFocusRing([this.node_.location]); | 389 chrome.accessibilityPrivate.setFocusRing([this.node_.location]); |
393 } | 390 } |
394 } | 391 } |
395 }; | 392 }; |
OLD | NEW |