| 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 predicates for the automation extension API. | 6 * @fileoverview ChromeVox predicates for the automation extension API. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 goog.provide('AutomationPredicate'); | 9 goog.provide('AutomationPredicate'); |
| 10 goog.provide('AutomationPredicate.Binary'); | 10 goog.provide('AutomationPredicate.Binary'); |
| 11 goog.provide('AutomationPredicate.Unary'); | 11 goog.provide('AutomationPredicate.Unary'); |
| 12 | 12 |
| 13 goog.require('constants'); | 13 goog.require('constants'); |
| 14 | 14 |
| 15 goog.scope(function() { | 15 goog.scope(function() { |
| 16 var AutomationNode = chrome.automation.AutomationNode; | 16 var AutomationNode = chrome.automation.AutomationNode; |
| 17 var Dir = constants.Dir; | 17 var Dir = constants.Dir; |
| 18 var Role = chrome.automation.RoleType; | 18 var Role = chrome.automation.RoleType; |
| 19 var State = chrome.automation.StateType; | |
| 20 | 19 |
| 21 /** | 20 /** |
| 22 * @constructor | 21 * @constructor |
| 23 */ | 22 */ |
| 24 AutomationPredicate = function() {}; | 23 AutomationPredicate = function() {}; |
| 25 | 24 |
| 26 /** | 25 /** |
| 27 * @typedef {function(!AutomationNode) : boolean} | 26 * @typedef {function(!AutomationNode) : boolean} |
| 28 */ | 27 */ |
| 29 AutomationPredicate.Unary; | 28 AutomationPredicate.Unary; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 52 var anyRole = params.anyRole || []; | 51 var anyRole = params.anyRole || []; |
| 53 var anyPredicate = params.anyPredicate || []; | 52 var anyPredicate = params.anyPredicate || []; |
| 54 return function(node) { | 53 return function(node) { |
| 55 return anyRole.some(function(role) { return role == node.role; }) || | 54 return anyRole.some(function(role) { return role == node.role; }) || |
| 56 anyPredicate.some(function(p) { return p(node); }); | 55 anyPredicate.some(function(p) { return p(node); }); |
| 57 }; | 56 }; |
| 58 }; | 57 }; |
| 59 | 58 |
| 60 /** @type {AutomationPredicate.Unary} */ | 59 /** @type {AutomationPredicate.Unary} */ |
| 61 AutomationPredicate.checkBox = | 60 AutomationPredicate.checkBox = |
| 62 AutomationPredicate.roles([Role.CHECK_BOX, Role.SWITCH]); | 61 AutomationPredicate.roles([Role.checkBox, Role.switch]); |
| 63 /** @type {AutomationPredicate.Unary} */ | 62 /** @type {AutomationPredicate.Unary} */ |
| 64 AutomationPredicate.comboBox = AutomationPredicate.roles( | 63 AutomationPredicate.comboBox = AutomationPredicate.roles( |
| 65 [Role.COMBO_BOX, Role.POP_UP_BUTTON, Role.MENU_LIST_POPUP]); | 64 [Role.comboBox, Role.popUpButton, Role.menuListPopup]); |
| 66 /** @type {AutomationPredicate.Unary} */ | 65 /** @type {AutomationPredicate.Unary} */ |
| 67 AutomationPredicate.heading = AutomationPredicate.roles([Role.HEADING]); | 66 AutomationPredicate.heading = AutomationPredicate.roles([Role.heading]); |
| 68 /** @type {AutomationPredicate.Unary} */ | 67 /** @type {AutomationPredicate.Unary} */ |
| 69 AutomationPredicate.inlineTextBox = | 68 AutomationPredicate.inlineTextBox = |
| 70 AutomationPredicate.roles([Role.INLINE_TEXT_BOX]); | 69 AutomationPredicate.roles([Role.inlineTextBox]); |
| 71 /** @type {AutomationPredicate.Unary} */ | 70 /** @type {AutomationPredicate.Unary} */ |
| 72 AutomationPredicate.link = AutomationPredicate.roles([Role.LINK]); | 71 AutomationPredicate.link = AutomationPredicate.roles([Role.link]); |
| 73 /** @type {AutomationPredicate.Unary} */ | 72 /** @type {AutomationPredicate.Unary} */ |
| 74 AutomationPredicate.row = AutomationPredicate.roles([Role.ROW]); | 73 AutomationPredicate.row = AutomationPredicate.roles([Role.row]); |
| 75 /** @type {AutomationPredicate.Unary} */ | 74 /** @type {AutomationPredicate.Unary} */ |
| 76 AutomationPredicate.table = AutomationPredicate.roles([Role.GRID, Role.TABLE]); | 75 AutomationPredicate.table = AutomationPredicate.roles([Role.grid, Role.table]); |
| 77 | 76 |
| 78 /** | 77 /** |
| 79 * @param {!AutomationNode} node | 78 * @param {!AutomationNode} node |
| 80 * @return {boolean} | 79 * @return {boolean} |
| 81 */ | 80 */ |
| 82 AutomationPredicate.button = function(node) { | 81 AutomationPredicate.button = function(node) { |
| 83 return /button/i.test(node.role); | 82 return /button/i.test(node.role); |
| 84 }; | 83 }; |
| 85 | 84 |
| 86 /** | 85 /** |
| 87 * @param {!AutomationNode} node | 86 * @param {!AutomationNode} node |
| 88 * @return {boolean} | 87 * @return {boolean} |
| 89 */ | 88 */ |
| 90 AutomationPredicate.editText = function(node) { | 89 AutomationPredicate.editText = function(node) { |
| 91 return node.state.editable && | 90 return node.state.editable && |
| 92 node.parent && | 91 node.parent && |
| 93 !node.parent.state.editable; | 92 !node.parent.state.editable; |
| 94 }; | 93 }; |
| 95 | 94 |
| 96 /** @type {AutomationPredicate.Unary} */ | 95 /** @type {AutomationPredicate.Unary} */ |
| 97 AutomationPredicate.formField = AutomationPredicate.match({ | 96 AutomationPredicate.formField = AutomationPredicate.match({ |
| 98 anyPredicate: [ | 97 anyPredicate: [ |
| 99 AutomationPredicate.button, | 98 AutomationPredicate.button, |
| 100 AutomationPredicate.comboBox, | 99 AutomationPredicate.comboBox, |
| 101 AutomationPredicate.editText | 100 AutomationPredicate.editText |
| 102 ], | 101 ], |
| 103 anyRole: [ | 102 anyRole: [ |
| 104 Role.CHECK_BOX, | 103 Role.checkBox, |
| 105 Role.COLOR_WELL, | 104 Role.colorWell, |
| 106 Role.LIST_BOX, | 105 Role.listBox, |
| 107 Role.SLIDER, | 106 Role.slider, |
| 108 Role.SWITCH, | 107 Role.switch, |
| 109 Role.TAB, | 108 Role.tab, |
| 110 Role.TREE | 109 Role.tree |
| 111 ] | 110 ] |
| 112 }); | 111 }); |
| 113 | 112 |
| 114 /** @type {AutomationPredicate.Unary} */ | 113 /** @type {AutomationPredicate.Unary} */ |
| 115 AutomationPredicate.control = AutomationPredicate.match({ | 114 AutomationPredicate.control = AutomationPredicate.match({ |
| 116 anyPredicate: [ | 115 anyPredicate: [ |
| 117 AutomationPredicate.formField, | 116 AutomationPredicate.formField, |
| 118 ], | 117 ], |
| 119 anyRole: [ | 118 anyRole: [ |
| 120 Role.DISCLOSURE_TRIANGLE, | 119 Role.disclosureTriangle, |
| 121 Role.MENU_ITEM, | 120 Role.menuItem, |
| 122 Role.MENU_ITEM_CHECK_BOX, | 121 Role.menuItemCheckBox, |
| 123 Role.MENU_ITEM_RADIO, | 122 Role.menuItemRadio, |
| 124 Role.MENU_LIST_OPTION, | 123 Role.menuListOption, |
| 125 Role.SCROLL_BAR | 124 Role.scrollBar |
| 126 ] | 125 ] |
| 127 }); | 126 }); |
| 128 | 127 |
| 129 /** | 128 /** |
| 130 * @param {!AutomationNode} node | 129 * @param {!AutomationNode} node |
| 131 * @return {boolean} | 130 * @return {boolean} |
| 132 */ | 131 */ |
| 133 AutomationPredicate.image = function(node) { | 132 AutomationPredicate.image = function(node) { |
| 134 return node.role == Role.IMAGE && !!(node.name || node.url); | 133 return node.role == Role.image && !!(node.name || node.url); |
| 135 }; | 134 }; |
| 136 | 135 |
| 137 /** @type {AutomationPredicate.Unary} */ | 136 /** @type {AutomationPredicate.Unary} */ |
| 138 AutomationPredicate.linkOrControl = AutomationPredicate.match({ | 137 AutomationPredicate.linkOrControl = AutomationPredicate.match({ |
| 139 anyPredicate: [ | 138 anyPredicate: [ |
| 140 AutomationPredicate.control | 139 AutomationPredicate.control |
| 141 ], | 140 ], |
| 142 anyRole: [ | 141 anyRole: [ |
| 143 Role.LINK | 142 Role.link |
| 144 ] | 143 ] |
| 145 }); | 144 }); |
| 146 | 145 |
| 147 /** @type {AutomationPredicate.Unary} */ | 146 /** @type {AutomationPredicate.Unary} */ |
| 148 AutomationPredicate.landmark = AutomationPredicate.roles([ | 147 AutomationPredicate.landmark = AutomationPredicate.roles([ |
| 149 Role.APPLICATION, | 148 Role.application, |
| 150 Role.BANNER, | 149 Role.banner, |
| 151 Role.COMPLEMENTARY, | 150 Role.complementary, |
| 152 Role.CONTENT_INFO, | 151 Role.contentInfo, |
| 153 Role.FORM, | 152 Role.form, |
| 154 Role.MAIN, | 153 Role.main, |
| 155 Role.NAVIGATION, | 154 Role.navigation, |
| 156 Role.REGION, | 155 Role.region, |
| 157 Role.SEARCH]); | 156 Role.search]); |
| 158 | 157 |
| 159 /** | 158 /** |
| 160 * @param {!AutomationNode} node | 159 * @param {!AutomationNode} node |
| 161 * @return {boolean} | 160 * @return {boolean} |
| 162 */ | 161 */ |
| 163 AutomationPredicate.visitedLink = function(node) { | 162 AutomationPredicate.visitedLink = function(node) { |
| 164 return node.state.visited; | 163 return node.state.visited; |
| 165 }; | 164 }; |
| 166 | 165 |
| 167 /** | 166 /** |
| 168 * @param {!AutomationNode} node | 167 * @param {!AutomationNode} node |
| 169 * @return {boolean} | 168 * @return {boolean} |
| 170 */ | 169 */ |
| 171 AutomationPredicate.focused = function(node) { | 170 AutomationPredicate.focused = function(node) { |
| 172 return node.state.focused; | 171 return node.state.focused; |
| 173 }; | 172 }; |
| 174 | 173 |
| 175 /** | 174 /** |
| 176 * @param {!AutomationNode} node | 175 * @param {!AutomationNode} node |
| 177 * @return {boolean} | 176 * @return {boolean} |
| 178 */ | 177 */ |
| 179 AutomationPredicate.leaf = function(node) { | 178 AutomationPredicate.leaf = function(node) { |
| 180 return !node.firstChild || | 179 return !node.firstChild || |
| 181 node.role == Role.BUTTON || | 180 node.role == Role.button || |
| 182 node.role == Role.BUTTON_DROP_DOWN || | 181 node.role == Role.buttonDropDown || |
| 183 node.role == Role.POP_UP_BUTTON || | 182 node.role == Role.popUpButton || |
| 184 node.role == Role.SLIDER || | 183 node.role == Role.slider || |
| 185 node.role == Role.TEXT_FIELD || | 184 node.role == Role.textField || |
| 186 node.state[State.INVISIBLE] || | 185 node.state.invisible || |
| 187 node.children.every(function(n) { | 186 node.children.every(function(n) { |
| 188 return n.state[State.INVISIBLE]; | 187 return n.state.invisible; |
| 189 }); | 188 }); |
| 190 }; | 189 }; |
| 191 | 190 |
| 192 /** | 191 /** |
| 193 * @param {!AutomationNode} node | 192 * @param {!AutomationNode} node |
| 194 * @return {boolean} | 193 * @return {boolean} |
| 195 */ | 194 */ |
| 196 AutomationPredicate.leafWithText = function(node) { | 195 AutomationPredicate.leafWithText = function(node) { |
| 197 return AutomationPredicate.leaf(node) && | 196 return AutomationPredicate.leaf(node) && |
| 198 !!(node.name || node.value); | 197 !!(node.name || node.value); |
| 199 }; | 198 }; |
| 200 | 199 |
| 201 /** | 200 /** |
| 202 * Matches against leaves or static text nodes. Useful when restricting | 201 * Matches against leaves or static text nodes. Useful when restricting |
| 203 * traversal to non-inline textboxes while still allowing them if navigation | 202 * traversal to non-inline textboxes while still allowing them if navigation |
| 204 * already entered into an inline textbox. | 203 * already entered into an inline textbox. |
| 205 * @param {!AutomationNode} node | 204 * @param {!AutomationNode} node |
| 206 * @return {boolean} | 205 * @return {boolean} |
| 207 */ | 206 */ |
| 208 AutomationPredicate.leafOrStaticText = function(node) { | 207 AutomationPredicate.leafOrStaticText = function(node) { |
| 209 return AutomationPredicate.leaf(node) || | 208 return AutomationPredicate.leaf(node) || |
| 210 node.role == Role.STATIC_TEXT; | 209 node.role == Role.staticText; |
| 211 }; | 210 }; |
| 212 | 211 |
| 213 /** | 212 /** |
| 214 * Matches against nodes visited during object navigation. An object as | 213 * Matches against nodes visited during object navigation. An object as |
| 215 * defined below, are all nodes that are focusable or static text. When used in | 214 * defined below, are all nodes that are focusable or static text. When used in |
| 216 * tree walking, it should visit all nodes that tab traversal would as well as | 215 * tree walking, it should visit all nodes that tab traversal would as well as |
| 217 * non-focusable static text. | 216 * non-focusable static text. |
| 218 * @param {!AutomationNode} node | 217 * @param {!AutomationNode} node |
| 219 * @return {boolean} | 218 * @return {boolean} |
| 220 */ | 219 */ |
| 221 AutomationPredicate.object = function(node) { | 220 AutomationPredicate.object = function(node) { |
| 222 // Editable nodes are within a text-like field and don't make sense when | 221 // Editable nodes are within a text-like field and don't make sense when |
| 223 // performing object navigation. Users should use line, word, or character | 222 // performing object navigation. Users should use line, word, or character |
| 224 // navigation. Only navigate to the top level node. | 223 // navigation. Only navigate to the top level node. |
| 225 if (node.parent && node.parent.state.editable) | 224 if (node.parent && node.parent.state.editable) |
| 226 return false; | 225 return false; |
| 227 | 226 |
| 228 // Descend into large nodes. | 227 // Descend into large nodes. |
| 229 if (node.name && node.name.length > constants.OBJECT_MAX_CHARCOUNT) | 228 if (node.name && node.name.length > constants.OBJECT_MAX_CHARCOUNT) |
| 230 return false; | 229 return false; |
| 231 | 230 |
| 232 return node.state.focusable || | 231 return node.state.focusable || |
| 233 (AutomationPredicate.leafOrStaticText(node) && | 232 (AutomationPredicate.leafOrStaticText(node) && |
| 234 (/\S+/.test(node.name) || | 233 (/\S+/.test(node.name) || |
| 235 (node.role != Role.LINE_BREAK && | 234 (node.role != Role.lineBreak && |
| 236 node.role != Role.STATIC_TEXT && | 235 node.role != Role.staticText && |
| 237 node.role != Role.INLINE_TEXT_BOX))); | 236 node.role != Role.inlineTextBox))); |
| 238 }; | 237 }; |
| 239 | 238 |
| 240 /** | 239 /** |
| 241 * Matches against nodes visited during group navigation. An object as | 240 * Matches against nodes visited during group navigation. An object as |
| 242 * @param {!AutomationNode} node | 241 * @param {!AutomationNode} node |
| 243 * @return {boolean} | 242 * @return {boolean} |
| 244 */ | 243 */ |
| 245 AutomationPredicate.group = AutomationPredicate.match({ | 244 AutomationPredicate.group = AutomationPredicate.match({ |
| 246 anyRole: [ | 245 anyRole: [ |
| 247 Role.HEADING, | 246 Role.heading, |
| 248 Role.LIST, | 247 Role.list, |
| 249 Role.PARAGRAPH | 248 Role.paragraph |
| 250 ], | 249 ], |
| 251 anyPredicate: [ | 250 anyPredicate: [ |
| 252 AutomationPredicate.editText, | 251 AutomationPredicate.editText, |
| 253 AutomationPredicate.formField, | 252 AutomationPredicate.formField, |
| 254 AutomationPredicate.object, | 253 AutomationPredicate.object, |
| 255 AutomationPredicate.table | 254 AutomationPredicate.table |
| 256 ] | 255 ] |
| 257 }); | 256 }); |
| 258 | 257 |
| 259 /** | 258 /** |
| (...skipping 11 matching lines...) Expand all Loading... |
| 271 | 270 |
| 272 /** | 271 /** |
| 273 * Matches against a node that contains other interesting nodes. | 272 * Matches against a node that contains other interesting nodes. |
| 274 * These nodes should always have their subtrees scanned when navigating. | 273 * These nodes should always have their subtrees scanned when navigating. |
| 275 * @param {!AutomationNode} node | 274 * @param {!AutomationNode} node |
| 276 * @return {boolean} | 275 * @return {boolean} |
| 277 */ | 276 */ |
| 278 AutomationPredicate.container = function(node) { | 277 AutomationPredicate.container = function(node) { |
| 279 return AutomationPredicate.match({ | 278 return AutomationPredicate.match({ |
| 280 anyRole: [ | 279 anyRole: [ |
| 281 Role.DIV, | 280 Role.div, |
| 282 Role.DOCUMENT, | 281 Role.document, |
| 283 Role.GROUP, | 282 Role.group, |
| 284 Role.LIST_ITEM, | 283 Role.listItem, |
| 285 Role.TOOLBAR, | 284 Role.toolbar, |
| 286 Role.WINDOW], | 285 Role.window], |
| 287 anyPredicate: [ | 286 anyPredicate: [ |
| 288 AutomationPredicate.landmark, | 287 AutomationPredicate.landmark, |
| 289 AutomationPredicate.structuralContainer, | 288 AutomationPredicate.structuralContainer, |
| 290 function(node) { | 289 function(node) { |
| 291 // For example, crosh. | 290 // For example, crosh. |
| 292 return (node.role == Role.TEXT_FIELD && node.state.readOnly); | 291 return (node.role == Role.textField && node.state.readOnly); |
| 293 }, | 292 }, |
| 294 function(node) { | 293 function(node) { |
| 295 return (node.state.editable && | 294 return (node.state.editable && |
| 296 node.parent && | 295 node.parent && |
| 297 !node.parent.state.editable); | 296 !node.parent.state.editable); |
| 298 }] | 297 }] |
| 299 })(node); | 298 })(node); |
| 300 }; | 299 }; |
| 301 | 300 |
| 302 /** | 301 /** |
| 303 * Matches against nodes that contain interesting nodes, but should never be | 302 * Matches against nodes that contain interesting nodes, but should never be |
| 304 * visited. | 303 * visited. |
| 305 * @param {!AutomationNode} node | 304 * @param {!AutomationNode} node |
| 306 * @return {boolean} | 305 * @return {boolean} |
| 307 */ | 306 */ |
| 308 AutomationPredicate.structuralContainer = AutomationPredicate.roles([ | 307 AutomationPredicate.structuralContainer = AutomationPredicate.roles([ |
| 309 Role.ALERT_DIALOG, | 308 Role.alertDialog, |
| 310 Role.DIALOG, | 309 Role.dialog, |
| 311 Role.ROOT_WEB_AREA, | 310 Role.rootWebArea, |
| 312 Role.WEB_VIEW, | 311 Role.webView, |
| 313 Role.WINDOW, | 312 Role.window, |
| 314 Role.EMBEDDED_OBJECT, | 313 Role.embeddedObject, |
| 315 Role.IFRAME, | 314 Role.iframe, |
| 316 Role.IFRAME_PRESENTATIONAL]); | 315 Role.iframePresentational]); |
| 317 | 316 |
| 318 /** | 317 /** |
| 319 * Returns whether the given node should not be crossed when performing | 318 * Returns whether the given node should not be crossed when performing |
| 320 * traversals up the ancestry chain. | 319 * traversals up the ancestry chain. |
| 321 * @param {AutomationNode} node | 320 * @param {AutomationNode} node |
| 322 * @return {boolean} | 321 * @return {boolean} |
| 323 */ | 322 */ |
| 324 AutomationPredicate.root = function(node) { | 323 AutomationPredicate.root = function(node) { |
| 325 switch (node.role) { | 324 switch (node.role) { |
| 326 case Role.WINDOW: | 325 case Role.window: |
| 327 return true; | 326 return true; |
| 328 case Role.DIALOG: | 327 case Role.dialog: |
| 329 // The below logic handles nested dialogs properly in the desktop tree | 328 // The below logic handles nested dialogs properly in the desktop tree |
| 330 // like that found in a bubble view. | 329 // like that found in a bubble view. |
| 331 return node.root.role != Role.DESKTOP || | 330 return node.root.role != Role.desktop || |
| 332 (!!node.parent && | 331 (!!node.parent && |
| 333 node.parent.role == Role.WINDOW && | 332 node.parent.role == Role.window && |
| 334 node.parent.children.every(function(child) { | 333 node.parent.children.every(function(child) { |
| 335 return node.role == Role.WINDOW || node.role == Role.DIALOG; | 334 return node.role == Role.window || node.role == Role.dialog; |
| 336 })); | 335 })); |
| 337 case Role.TOOLBAR: | 336 case Role.toolbar: |
| 338 return node.root.role == Role.DESKTOP; | 337 return node.root.role == Role.desktop; |
| 339 case Role.ROOT_WEB_AREA: | 338 case Role.rootWebArea: |
| 340 return !node.parent || node.parent.root.role == Role.DESKTOP; | 339 return !node.parent || node.parent.root.role == Role.desktop; |
| 341 default: | 340 default: |
| 342 return false; | 341 return false; |
| 343 } | 342 } |
| 344 }; | 343 }; |
| 345 | 344 |
| 346 /** | 345 /** |
| 347 * Nodes that should be ignored while traversing the automation tree. For | 346 * Nodes that should be ignored while traversing the automation tree. For |
| 348 * example, apply this predicate when moving to the next object. | 347 * example, apply this predicate when moving to the next object. |
| 349 * @param {!AutomationNode} node | 348 * @param {!AutomationNode} node |
| 350 * @return {boolean} | 349 * @return {boolean} |
| 351 */ | 350 */ |
| 352 AutomationPredicate.shouldIgnoreNode = function(node) { | 351 AutomationPredicate.shouldIgnoreNode = function(node) { |
| 353 // Ignore invisible nodes. | 352 // Ignore invisible nodes. |
| 354 if (node.state.invisible || | 353 if (node.state.invisible || |
| 355 (node.location.height == 0 && node.location.width == 0)) | 354 (node.location.height == 0 && node.location.width == 0)) |
| 356 return true; | 355 return true; |
| 357 | 356 |
| 358 // Ignore structural containres. | 357 // Ignore structural containres. |
| 359 if (AutomationPredicate.structuralContainer(node)) | 358 if (AutomationPredicate.structuralContainer(node)) |
| 360 return true; | 359 return true; |
| 361 | 360 |
| 362 // Ignore list markers since we already announce listitem role. | 361 // Ignore list markers since we already announce listitem role. |
| 363 if (node.role == Role.LIST_MARKER) | 362 if (node.role == Role.listMarker) |
| 364 return true; | 363 return true; |
| 365 | 364 |
| 366 // Don't ignore nodes with names or name-like attribute. | 365 // Don't ignore nodes with names or name-like attribute. |
| 367 if (node.name || node.value || node.description || node.url) | 366 if (node.name || node.value || node.description || node.url) |
| 368 return false; | 367 return false; |
| 369 | 368 |
| 370 // Ignore some roles. | 369 // Ignore some roles. |
| 371 return AutomationPredicate.leaf(node) && | 370 return AutomationPredicate.leaf(node) && |
| 372 (AutomationPredicate.roles([Role.CLIENT, | 371 (AutomationPredicate.roles([Role.client, |
| 373 Role.COLUMN, | 372 Role.column, |
| 374 Role.DIV, | 373 Role.div, |
| 375 Role.GROUP, | 374 Role.group, |
| 376 Role.IMAGE, | 375 Role.image, |
| 377 Role.STATIC_TEXT, | 376 Role.staticText, |
| 378 Role.SVG_ROOT, | 377 Role.svgRoot, |
| 379 Role.TABLE_HEADER_CONTAINER, | 378 Role.tableHeaderContainer, |
| 380 Role.UNKNOWN | 379 Role.unknown |
| 381 ])(node)); | 380 ])(node)); |
| 382 }; | 381 }; |
| 383 | 382 |
| 384 /** | 383 /** |
| 385 * Returns if the node has a meaningful checked state. | 384 * Returns if the node has a meaningful checked state. |
| 386 * @param {!AutomationNode} node | 385 * @param {!AutomationNode} node |
| 387 * @return {boolean} | 386 * @return {boolean} |
| 388 */ | 387 */ |
| 389 AutomationPredicate.checkable = AutomationPredicate.roles([ | 388 AutomationPredicate.checkable = AutomationPredicate.roles([ |
| 390 Role.CHECK_BOX, | 389 Role.checkBox, |
| 391 Role.RADIO_BUTTON, | 390 Role.radioButton, |
| 392 Role.MENU_ITEM_CHECK_BOX, | 391 Role.menuItemCheckBox, |
| 393 Role.MENU_ITEM_RADIO, | 392 Role.menuItemRadio, |
| 394 Role.TREE_ITEM]); | 393 Role.treeItem]); |
| 395 | 394 |
| 396 // Table related predicates. | 395 // Table related predicates. |
| 397 /** | 396 /** |
| 398 * Returns if the node has a cell like role. | 397 * Returns if the node has a cell like role. |
| 399 * @param {!AutomationNode} node | 398 * @param {!AutomationNode} node |
| 400 * @return {boolean} | 399 * @return {boolean} |
| 401 */ | 400 */ |
| 402 AutomationPredicate.cellLike = AutomationPredicate.roles([ | 401 AutomationPredicate.cellLike = AutomationPredicate.roles([ |
| 403 Role.CELL, | 402 Role.cell, |
| 404 Role.ROW_HEADER, | 403 Role.rowHeader, |
| 405 Role.COLUMN_HEADER]); | 404 Role.columnHeader]); |
| 406 | 405 |
| 407 /** | 406 /** |
| 408 * Returns a predicate that will match against the directed next cell taking | 407 * Returns a predicate that will match against the directed next cell taking |
| 409 * into account the current ancestor cell's position in the table. | 408 * into account the current ancestor cell's position in the table. |
| 410 * @param {AutomationNode} start | 409 * @param {AutomationNode} start |
| 411 * @param {{dir: (Dir|undefined), | 410 * @param {{dir: (Dir|undefined), |
| 412 * row: (boolean|undefined), | 411 * row: (boolean|undefined), |
| 413 * col: (boolean|undefined)}} opts | 412 * col: (boolean|undefined)}} opts |
| 414 * |dir|, specifies direction for |row or/and |col| movement by one cell. | 413 * |dir|, specifies direction for |row or/and |col| movement by one cell. |
| 415 * |dir| defaults to forward. | 414 * |dir| defaults to forward. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 }; | 474 }; |
| 476 | 475 |
| 477 /** | 476 /** |
| 478 * Returns a predicate that will match against a heading with a specific | 477 * Returns a predicate that will match against a heading with a specific |
| 479 * hierarchical level. | 478 * hierarchical level. |
| 480 * @param {number} level 1-6 | 479 * @param {number} level 1-6 |
| 481 * @return {AutomationPredicate.Unary} | 480 * @return {AutomationPredicate.Unary} |
| 482 */ | 481 */ |
| 483 AutomationPredicate.makeHeadingPredicate = function(level) { | 482 AutomationPredicate.makeHeadingPredicate = function(level) { |
| 484 return function(node) { | 483 return function(node) { |
| 485 return node.role == Role.HEADING && node.hierarchicalLevel == level; | 484 return node.role == Role.heading && node.hierarchicalLevel == level; |
| 486 }; | 485 }; |
| 487 }; | 486 }; |
| 488 | 487 |
| 489 }); // goog.scope | 488 }); // goog.scope |
| OLD | NEW |