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 goog.provide('AutomationUtil.Dir'); | 10 goog.provide('AutomationUtil.Dir'); |
(...skipping 12 matching lines...) Expand all Loading... |
23 AutomationUtil.Dir = { | 23 AutomationUtil.Dir = { |
24 // Search from left to right. | 24 // Search from left to right. |
25 FORWARD: 'forward', | 25 FORWARD: 'forward', |
26 | 26 |
27 // Search from right to left. | 27 // Search from right to left. |
28 BACKWARD: 'backward' | 28 BACKWARD: 'backward' |
29 }; | 29 }; |
30 | 30 |
31 | 31 |
32 goog.scope(function() { | 32 goog.scope(function() { |
| 33 var AutomationNode = chrome.automation.AutomationNode; |
33 var Dir = AutomationUtil.Dir; | 34 var Dir = AutomationUtil.Dir; |
34 | 35 |
35 /** | 36 /** |
36 * Find a node in subtree of |cur| satisfying |pred| using pre-order traversal. | 37 * Find a node in subtree of |cur| satisfying |pred| using pre-order traversal. |
37 * @param {chrome.automation.AutomationNode} cur Node to begin the search from. | 38 * @param {AutomationNode} cur Node to begin the search from. |
38 * @param {Dir} dir | 39 * @param {Dir} dir |
39 * @param {AutomationPredicate.Unary} pred A predicate to apply | 40 * @param {AutomationPredicate.Unary} pred A predicate to apply |
40 * to a candidate node. | 41 * to a candidate node. |
41 * @return {chrome.automation.AutomationNode} | 42 * @return {AutomationNode} |
42 */ | 43 */ |
43 AutomationUtil.findNodePre = function(cur, dir, pred) { | 44 AutomationUtil.findNodePre = function(cur, dir, pred) { |
44 if (pred(cur)) | 45 if (pred(cur)) |
45 return cur; | 46 return cur; |
46 | 47 |
47 var child = dir == Dir.BACKWARD ? cur.lastChild() : cur.firstChild(); | 48 var child = dir == Dir.BACKWARD ? cur.lastChild() : cur.firstChild(); |
48 while (child) { | 49 while (child) { |
49 var ret = AutomationUtil.findNodePre(child, dir, pred); | 50 var ret = AutomationUtil.findNodePre(child, dir, pred); |
50 if (ret) | 51 if (ret) |
51 return ret; | 52 return ret; |
52 child = dir == Dir.BACKWARD ? | 53 child = dir == Dir.BACKWARD ? |
53 child.previousSibling() : child.nextSibling(); | 54 child.previousSibling() : child.nextSibling(); |
54 } | 55 } |
55 }; | 56 }; |
56 | 57 |
57 /** | 58 /** |
58 * Find a node in subtree of |cur| satisfying |pred| using post-order traversal. | 59 * Find a node in subtree of |cur| satisfying |pred| using post-order traversal. |
59 * @param {chrome.automation.AutomationNode} cur Node to begin the search from. | 60 * @param {AutomationNode} cur Node to begin the search from. |
60 * @param {Dir} dir | 61 * @param {Dir} dir |
61 * @param {AutomationPredicate.Unary} pred A predicate to apply | 62 * @param {AutomationPredicate.Unary} pred A predicate to apply |
62 * to a candidate node. | 63 * to a candidate node. |
63 * @return {chrome.automation.AutomationNode} | 64 * @return {AutomationNode} |
64 */ | 65 */ |
65 AutomationUtil.findNodePost = function(cur, dir, pred) { | 66 AutomationUtil.findNodePost = function(cur, dir, pred) { |
66 var child = dir == Dir.BACKWARD ? cur.lastChild() : cur.firstChild(); | 67 var child = dir == Dir.BACKWARD ? cur.lastChild() : cur.firstChild(); |
67 while (child) { | 68 while (child) { |
68 var ret = AutomationUtil.findNodePost(child, dir, pred); | 69 var ret = AutomationUtil.findNodePost(child, dir, pred); |
69 if (ret) | 70 if (ret) |
70 return ret; | 71 return ret; |
71 child = dir == Dir.BACKWARD ? | 72 child = dir == Dir.BACKWARD ? |
72 child.previousSibling() : child.nextSibling(); | 73 child.previousSibling() : child.nextSibling(); |
73 } | 74 } |
74 | 75 |
75 if (pred(cur)) | 76 if (pred(cur)) |
76 return cur; | 77 return cur; |
77 }; | 78 }; |
78 | 79 |
79 /** | 80 /** |
80 * Find the next node in the given direction that is either an immediate sibling | 81 * Find the next node in the given direction that is either an immediate sibling |
81 * or a sibling of an ancestor. | 82 * or a sibling of an ancestor. |
82 * @param {chrome.automation.AutomationNode} cur Node to start search from. | 83 * @param {AutomationNode} cur Node to start search from. |
83 * @param {Dir} dir | 84 * @param {Dir} dir |
84 * @return {chrome.automation.AutomationNode} | 85 * @return {AutomationNode} |
85 */ | 86 */ |
86 AutomationUtil.findNextSubtree = function(cur, dir) { | 87 AutomationUtil.findNextSubtree = function(cur, dir) { |
87 while (cur) { | 88 while (cur) { |
88 var next = dir == Dir.BACKWARD ? | 89 var next = dir == Dir.BACKWARD ? |
89 cur.previousSibling() : cur.nextSibling(); | 90 cur.previousSibling() : cur.nextSibling(); |
90 if (next) | 91 if (next) |
91 return next; | 92 return next; |
92 cur = cur.parent(); | 93 cur = cur.parent(); |
93 } | 94 } |
94 }; | 95 }; |
95 | 96 |
96 /** | 97 /** |
97 * Find the next node in the given direction in depth first order. | 98 * Find the next node in the given direction in depth first order. |
98 * @param {chrome.automation.AutomationNode} cur Node to begin the search from. | 99 * @param {AutomationNode} cur Node to begin the search from. |
99 * @param {Dir} dir | 100 * @param {Dir} dir |
100 * @param {AutomationPredicate.Unary} pred A predicate to apply | 101 * @param {AutomationPredicate.Unary} pred A predicate to apply |
101 * to a candidate node. | 102 * to a candidate node. |
102 * @return {chrome.automation.AutomationNode} | 103 * @return {AutomationNode} |
103 */ | 104 */ |
104 AutomationUtil.findNextNode = function(cur, dir, pred) { | 105 AutomationUtil.findNextNode = function(cur, dir, pred) { |
105 var next = cur; | 106 var next = cur; |
106 do { | 107 do { |
107 if (!(next = AutomationUtil.findNextSubtree(cur, dir))) | 108 if (!(next = AutomationUtil.findNextSubtree(cur, dir))) |
108 return null; | 109 return null; |
109 cur = next; | 110 cur = next; |
110 next = AutomationUtil.findNodePre(next, dir, pred); | 111 next = AutomationUtil.findNodePre(next, dir, pred); |
111 } while (!next); | 112 } while (!next); |
112 return next; | 113 return next; |
113 }; | 114 }; |
114 | 115 |
115 /** | 116 /** |
116 * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply | 117 * Given nodes a_1, ..., a_n starting at |cur| in pre order traversal, apply |
117 * |pred| to a_i and a_(i - 1) until |pred| is satisfied. Returns a_(i - 1) or | 118 * |pred| to a_i and a_(i - 1) until |pred| is satisfied. Returns a_(i - 1) or |
118 * a_i (depending on opt_options.before) or null if no match was found. | 119 * a_i (depending on opt_options.before) or null if no match was found. |
119 * @param {chrome.automation.AutomationNode} cur | 120 * @param {AutomationNode} cur |
120 * @param {Dir} dir | 121 * @param {Dir} dir |
121 * @param {AutomationPredicate.Binary} pred | 122 * @param {AutomationPredicate.Binary} pred |
122 * @param {{filter: (AutomationPredicate.Unary|undefined), | 123 * @param {{filter: (AutomationPredicate.Unary|undefined), |
123 * before: boolean?}=} opt_options | 124 * before: boolean?}=} opt_options |
124 * filter - Filters which candidate nodes to | 125 * filter - Filters which candidate nodes to |
125 * consider. Defaults to leaf nodes only. | 126 * consider. Defaults to leaf nodes only. |
126 * before - True to return a_(i - | 127 * before - True to return a_(i - |
127 * 1); a_i otherwise. Defaults to false. | 128 * 1); a_i otherwise. Defaults to false. |
128 * @return {chrome.automation.AutomationNode} | 129 * @return {AutomationNode} |
129 */ | 130 */ |
130 AutomationUtil.findNodeUntil = function(cur, dir, pred, opt_options) { | 131 AutomationUtil.findNodeUntil = function(cur, dir, pred, opt_options) { |
131 opt_options = | 132 opt_options = |
132 opt_options || {filter: AutomationPredicate.leaf, before: false}; | 133 opt_options || {filter: AutomationPredicate.leaf, before: false}; |
133 if (!opt_options.filter) | 134 if (!opt_options.filter) |
134 opt_options.filter = AutomationPredicate.leaf; | 135 opt_options.filter = AutomationPredicate.leaf; |
135 | 136 |
136 var before = null; | 137 var before = null; |
137 var after = null; | 138 var after = null; |
138 var prev = cur; | 139 var prev = cur; |
139 AutomationUtil.findNextNode(cur, | 140 AutomationUtil.findNextNode(cur, |
140 dir, | 141 dir, |
141 function(candidate) { | 142 function(candidate) { |
142 if (!opt_options.filter(candidate)) | 143 if (!opt_options.filter(candidate)) |
143 return false; | 144 return false; |
144 | 145 |
145 var satisfied = pred(prev, candidate); | 146 var satisfied = pred(prev, candidate); |
146 | 147 |
147 prev = candidate; | 148 prev = candidate; |
148 if (!satisfied) | 149 if (!satisfied) |
149 before = candidate; | 150 before = candidate; |
150 else | 151 else |
151 after = candidate; | 152 after = candidate; |
152 return satisfied; | 153 return satisfied; |
153 }); | 154 }); |
154 return opt_options.before ? before : after; | 155 return opt_options.before ? before : after; |
155 }; | 156 }; |
156 | 157 |
157 }); // goog.scope | 158 }); // goog.scope |
OLD | NEW |