| 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 |