OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 * @fileoverview ChromeVox utilities for the automation extension API. | 6 * @fileoverview ChromeVox utilities for the automation extension API. |
7 */ | 7 */ |
8 | 8 |
9 goog.provide('AutomationUtil'); | 9 goog.provide('AutomationUtil'); |
10 | 10 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 } | 70 } |
71 | 71 |
72 if (pred(cur)) | 72 if (pred(cur)) |
73 return cur; | 73 return cur; |
74 | 74 |
75 return null; | 75 return null; |
76 }; | 76 }; |
77 | 77 |
78 /** | 78 /** |
79 * Find the next node in the given direction in depth first order. | 79 * Find the next node in the given direction in depth first order. |
| 80 * |
| 81 * Let D be the dfs linearization of |cur.root|. Then, let F be the list after |
| 82 * applying |pred| as a filter to D. This method will return the directed next |
| 83 * node of |cur| in F. |
| 84 * The restrictions option will further filter F. For example, |
| 85 * |skipInitialSubtree| will remove any |pred| matches in the subtree of |cur| |
| 86 * from F. |
80 * @param {!AutomationNode} cur Node to begin the search from. | 87 * @param {!AutomationNode} cur Node to begin the search from. |
81 * @param {Dir} dir | 88 * @param {Dir} dir |
82 * @param {AutomationPredicate.Unary} pred A predicate to apply | 89 * @param {AutomationPredicate.Unary} pred A predicate to apply |
83 * to a candidate node. | 90 * to a candidate node. |
84 * @param {AutomationTreeWalkerRestriction=} opt_restrictions |leaf|, |root|, | 91 * @param {AutomationTreeWalkerRestriction=} opt_restrictions |leaf|, |root|, |
85 * and |skipInitialSubtree| are valid restrictions used when finding the | 92 * |skipInitialAncestry|, and |skipInitialSubtree| are valid restrictions |
86 * next node. If not supplied, the leaf predicate returns true for nodes | 93 * used when finding the next node. |
87 * matched by |pred| or |AutomationPredicate.container|. This is typically | 94 * By default: |
88 * desirable in most situations. | 95 * the root predicate ges set to |AutomationPredicate.root|. |
89 * If not supplied, the root predicate gets set to | 96 * |skipInitialSubtree| is false if |cur| is a container or matches |
90 * |AutomationUtil.isTraversalRoot|. | 97 * |pred|. This alleviates the caller from syncing forwards. |
| 98 * Leaves are nodes matched by |prred| which are not also containers. |
| 99 * This takes care of syncing backwards. |
91 * @return {AutomationNode} | 100 * @return {AutomationNode} |
92 */ | 101 */ |
93 AutomationUtil.findNextNode = function(cur, dir, pred, opt_restrictions) { | 102 AutomationUtil.findNextNode = function(cur, dir, pred, opt_restrictions) { |
94 var restrictions = {}; | 103 var restrictions = {}; |
95 opt_restrictions = opt_restrictions || {leaf: undefined, | 104 opt_restrictions = opt_restrictions || {leaf: undefined, |
96 root: undefined, | 105 root: undefined, |
97 visit: undefined, | 106 visit: undefined, |
98 skipInitialSubtree: !AutomationPredicate.container(cur)}; | 107 skipInitialSubtree: !AutomationPredicate.container(cur) && pred(cur)}; |
| 108 |
| 109 restrictions.root = opt_restrictions.root || AutomationPredicate.root; |
99 restrictions.leaf = opt_restrictions.leaf || function(node) { | 110 restrictions.leaf = opt_restrictions.leaf || function(node) { |
100 // Treat nodes matched by |pred| as leaves except for containers. | 111 // Treat nodes matched by |pred| as leaves except for containers. |
101 return !AutomationPredicate.container(node) && pred(node); | 112 return !AutomationPredicate.container(node) && pred(node); |
102 }; | 113 }; |
103 | 114 |
104 restrictions.root = opt_restrictions.root || AutomationUtil.isTraversalRoot; | |
105 restrictions.skipInitialSubtree = opt_restrictions.skipInitialSubtree; | 115 restrictions.skipInitialSubtree = opt_restrictions.skipInitialSubtree; |
106 restrictions.skipInitialAncestry = opt_restrictions.skipInitialAncestry; | 116 restrictions.skipInitialAncestry = opt_restrictions.skipInitialAncestry; |
107 | 117 |
108 restrictions.visit = function(node) { | 118 restrictions.visit = function(node) { |
109 if (pred(node) && !AutomationPredicate.shouldIgnoreLeaf(node)) | 119 return pred(node) && !AutomationPredicate.shouldIgnoreNode(node); |
110 return true; | |
111 if (AutomationPredicate.container(node)) | |
112 return true; | |
113 }; | 120 }; |
114 | 121 |
115 var walker = new AutomationTreeWalker(cur, dir, restrictions); | 122 var walker = new AutomationTreeWalker(cur, dir, restrictions); |
116 return walker.next().node; | 123 return walker.next().node; |
117 }; | 124 }; |
118 | 125 |
119 /** | 126 /** |
120 * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply | 127 * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply |
121 * |pred| to a_i and a_(i - 1) until |pred| is satisfied. Returns a_(i - 1) or | 128 * |pred| to a_i and a_(i - 1) until |pred| is satisfied. Returns a_(i - 1) or |
122 * a_i (depending on opt_before) or null if no match was found. | 129 * a_i (depending on opt_before) or null if no match was found. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 AutomationUtil.isInSameTree = function(a, b) { | 226 AutomationUtil.isInSameTree = function(a, b) { |
220 if (!a || !b) | 227 if (!a || !b) |
221 return true; | 228 return true; |
222 | 229 |
223 // Given two non-desktop roots, consider them in the "same" tree. | 230 // Given two non-desktop roots, consider them in the "same" tree. |
224 return a.root === b.root || | 231 return a.root === b.root || |
225 (a.root.role == b.root.role && a.root.role == RoleType.rootWebArea); | 232 (a.root.role == b.root.role && a.root.role == RoleType.rootWebArea); |
226 }; | 233 }; |
227 | 234 |
228 /** | 235 /** |
229 * Returns whether the given node should not be crossed when performing | |
230 * traversals up the ancestry chain. | |
231 * @param {AutomationNode} node | |
232 * @return {boolean} | |
233 */ | |
234 AutomationUtil.isTraversalRoot = function(node) { | |
235 switch (node.role) { | |
236 case RoleType.dialog: | |
237 case RoleType.window: | |
238 return true; | |
239 case RoleType.toolbar: | |
240 return node.root.role == RoleType.desktop; | |
241 case RoleType.rootWebArea: | |
242 return !node.parent || node.parent.root.role == RoleType.desktop; | |
243 default: | |
244 return false; | |
245 } | |
246 }; | |
247 | |
248 /** | |
249 * Determines whether the two given nodes come from the same webpage. | 236 * Determines whether the two given nodes come from the same webpage. |
250 * @param {AutomationNode} a | 237 * @param {AutomationNode} a |
251 * @param {AutomationNode} b | 238 * @param {AutomationNode} b |
252 * @return {boolean} | 239 * @return {boolean} |
253 */ | 240 */ |
254 AutomationUtil.isInSameWebpage = function(a, b) { | 241 AutomationUtil.isInSameWebpage = function(a, b) { |
255 if (!a || !b) | 242 if (!a || !b) |
256 return false; | 243 return false; |
257 | 244 |
258 a = a.root; | 245 a = a.root; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 child = child.nextSibling; | 285 child = child.nextSibling; |
299 } | 286 } |
300 | 287 |
301 if (point.x <= (loc.left + loc.width) && point.x >= loc.left && | 288 if (point.x <= (loc.left + loc.width) && point.x >= loc.left && |
302 point.y <= (loc.top + loc.height) && point.y >= loc.top) | 289 point.y <= (loc.top + loc.height) && point.y >= loc.top) |
303 return node; | 290 return node; |
304 return null; | 291 return null; |
305 }; | 292 }; |
306 | 293 |
307 }); // goog.scope | 294 }); // goog.scope |
OLD | NEW |