Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js

Issue 2939273002: DO NOT SUBMIT: what chrome/browser/resources/ could eventually look like with clang-format (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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');
(...skipping 21 matching lines...) Expand all
32 * @typedef {function(!AutomationNode, !AutomationNode) : boolean} 32 * @typedef {function(!AutomationNode, !AutomationNode) : boolean}
33 */ 33 */
34 AutomationPredicate.Binary; 34 AutomationPredicate.Binary;
35 35
36 /** 36 /**
37 * Constructs a predicate given a list of roles. 37 * Constructs a predicate given a list of roles.
38 * @param {!Array<Role>} roles 38 * @param {!Array<Role>} roles
39 * @return {AutomationPredicate.Unary} 39 * @return {AutomationPredicate.Unary}
40 */ 40 */
41 AutomationPredicate.roles = function(roles) { 41 AutomationPredicate.roles = function(roles) {
42 return AutomationPredicate.match({anyRole: roles }); 42 return AutomationPredicate.match({anyRole: roles});
43 }; 43 };
44 44
45 /** 45 /**
46 * Constructs a predicate given a list of roles or predicates. 46 * Constructs a predicate given a list of roles or predicates.
47 * @param {{anyRole: (Array<Role>|undefined), 47 * @param {{anyRole: (Array<Role>|undefined),
48 * anyPredicate: (Array<AutomationPredicate.Unary>|undefined)}} params 48 * anyPredicate: (Array<AutomationPredicate.Unary>|undefined)}} params
49 * @return {AutomationPredicate.Unary} 49 * @return {AutomationPredicate.Unary}
50 */ 50 */
51 AutomationPredicate.match = function(params) { 51 AutomationPredicate.match = function(params) {
52 var anyRole = params.anyRole || []; 52 var anyRole = params.anyRole || [];
53 var anyPredicate = params.anyPredicate || []; 53 var anyPredicate = params.anyPredicate || [];
54 return function(node) { 54 return function(node) {
55 return anyRole.some(function(role) { return role == node.role; }) || 55 return anyRole.some(function(role) {
56 anyPredicate.some(function(p) { return p(node); }); 56 return role == node.role;
57 }) ||
58 anyPredicate.some(function(p) {
59 return p(node);
60 });
57 }; 61 };
58 }; 62 };
59 63
60 /** @type {AutomationPredicate.Unary} */ 64 /** @type {AutomationPredicate.Unary} */
61 AutomationPredicate.checkBox = 65 AutomationPredicate.checkBox =
62 AutomationPredicate.roles([Role.CHECK_BOX, Role.SWITCH]); 66 AutomationPredicate.roles([Role.CHECK_BOX, Role.SWITCH]);
63 /** @type {AutomationPredicate.Unary} */ 67 /** @type {AutomationPredicate.Unary} */
64 AutomationPredicate.comboBox = AutomationPredicate.roles( 68 AutomationPredicate.comboBox = AutomationPredicate.roles(
65 [Role.COMBO_BOX, Role.POP_UP_BUTTON, Role.MENU_LIST_POPUP]); 69 [Role.COMBO_BOX, Role.POP_UP_BUTTON, Role.MENU_LIST_POPUP]);
66 /** @type {AutomationPredicate.Unary} */ 70 /** @type {AutomationPredicate.Unary} */
(...skipping 14 matching lines...) Expand all
81 */ 85 */
82 AutomationPredicate.button = function(node) { 86 AutomationPredicate.button = function(node) {
83 return /button/i.test(node.role); 87 return /button/i.test(node.role);
84 }; 88 };
85 89
86 /** 90 /**
87 * @param {!AutomationNode} node 91 * @param {!AutomationNode} node
88 * @return {boolean} 92 * @return {boolean}
89 */ 93 */
90 AutomationPredicate.editText = function(node) { 94 AutomationPredicate.editText = function(node) {
91 return node.state.editable && 95 return node.state.editable && node.parent && !node.parent.state.editable;
92 node.parent &&
93 !node.parent.state.editable;
94 }; 96 };
95 97
96 /** @type {AutomationPredicate.Unary} */ 98 /** @type {AutomationPredicate.Unary} */
97 AutomationPredicate.formField = AutomationPredicate.match({ 99 AutomationPredicate.formField = AutomationPredicate.match({
98 anyPredicate: [ 100 anyPredicate: [
99 AutomationPredicate.button, 101 AutomationPredicate.button, AutomationPredicate.comboBox,
100 AutomationPredicate.comboBox,
101 AutomationPredicate.editText 102 AutomationPredicate.editText
102 ], 103 ],
103 anyRole: [ 104 anyRole: [
104 Role.CHECK_BOX, 105 Role.CHECK_BOX, Role.COLOR_WELL, Role.LIST_BOX, Role.SLIDER, Role.SWITCH,
105 Role.COLOR_WELL, 106 Role.TAB, Role.TREE
106 Role.LIST_BOX,
107 Role.SLIDER,
108 Role.SWITCH,
109 Role.TAB,
110 Role.TREE
111 ] 107 ]
112 }); 108 });
113 109
114 /** @type {AutomationPredicate.Unary} */ 110 /** @type {AutomationPredicate.Unary} */
115 AutomationPredicate.control = AutomationPredicate.match({ 111 AutomationPredicate.control = AutomationPredicate.match({
116 anyPredicate: [ 112 anyPredicate: [
117 AutomationPredicate.formField, 113 AutomationPredicate.formField,
118 ], 114 ],
119 anyRole: [ 115 anyRole: [
120 Role.DISCLOSURE_TRIANGLE, 116 Role.DISCLOSURE_TRIANGLE, Role.MENU_ITEM, Role.MENU_ITEM_CHECK_BOX,
121 Role.MENU_ITEM, 117 Role.MENU_ITEM_RADIO, Role.MENU_LIST_OPTION, Role.SCROLL_BAR
122 Role.MENU_ITEM_CHECK_BOX,
123 Role.MENU_ITEM_RADIO,
124 Role.MENU_LIST_OPTION,
125 Role.SCROLL_BAR
126 ] 118 ]
127 }); 119 });
128 120
129 /** 121 /**
130 * @param {!AutomationNode} node 122 * @param {!AutomationNode} node
131 * @return {boolean} 123 * @return {boolean}
132 */ 124 */
133 AutomationPredicate.image = function(node) { 125 AutomationPredicate.image = function(node) {
134 return node.role == Role.IMAGE && !!(node.name || node.url); 126 return node.role == Role.IMAGE && !!(node.name || node.url);
135 }; 127 };
136 128
137 /** @type {AutomationPredicate.Unary} */ 129 /** @type {AutomationPredicate.Unary} */
138 AutomationPredicate.linkOrControl = AutomationPredicate.match({ 130 AutomationPredicate.linkOrControl = AutomationPredicate.match(
139 anyPredicate: [ 131 {anyPredicate: [AutomationPredicate.control], anyRole: [Role.LINK]});
140 AutomationPredicate.control
141 ],
142 anyRole: [
143 Role.LINK
144 ]
145 });
146 132
147 /** @type {AutomationPredicate.Unary} */ 133 /** @type {AutomationPredicate.Unary} */
148 AutomationPredicate.landmark = AutomationPredicate.roles([ 134 AutomationPredicate.landmark = AutomationPredicate.roles([
149 Role.APPLICATION, 135 Role.APPLICATION, Role.BANNER, Role.COMPLEMENTARY, Role.CONTENT_INFO,
150 Role.BANNER, 136 Role.FORM, Role.MAIN, Role.NAVIGATION, Role.REGION, Role.SEARCH
151 Role.COMPLEMENTARY, 137 ]);
152 Role.CONTENT_INFO,
153 Role.FORM,
154 Role.MAIN,
155 Role.NAVIGATION,
156 Role.REGION,
157 Role.SEARCH]);
158 138
159 /** 139 /**
160 * @param {!AutomationNode} node 140 * @param {!AutomationNode} node
161 * @return {boolean} 141 * @return {boolean}
162 */ 142 */
163 AutomationPredicate.visitedLink = function(node) { 143 AutomationPredicate.visitedLink = function(node) {
164 return node.state.visited; 144 return node.state.visited;
165 }; 145 };
166 146
167 /** 147 /**
168 * @param {!AutomationNode} node 148 * @param {!AutomationNode} node
169 * @return {boolean} 149 * @return {boolean}
170 */ 150 */
171 AutomationPredicate.focused = function(node) { 151 AutomationPredicate.focused = function(node) {
172 return node.state.focused; 152 return node.state.focused;
173 }; 153 };
174 154
175 /** 155 /**
176 * @param {!AutomationNode} node 156 * @param {!AutomationNode} node
177 * @return {boolean} 157 * @return {boolean}
178 */ 158 */
179 AutomationPredicate.leaf = function(node) { 159 AutomationPredicate.leaf = function(node) {
180 return !node.firstChild || 160 return !node.firstChild || node.role == Role.BUTTON ||
181 node.role == Role.BUTTON || 161 node.role == Role.BUTTON_DROP_DOWN || node.role == Role.POP_UP_BUTTON ||
182 node.role == Role.BUTTON_DROP_DOWN || 162 node.role == Role.SLIDER || node.role == Role.TEXT_FIELD ||
183 node.role == Role.POP_UP_BUTTON || 163 node.state[State.INVISIBLE] || node.children.every(function(n) {
184 node.role == Role.SLIDER ||
185 node.role == Role.TEXT_FIELD ||
186 node.state[State.INVISIBLE] ||
187 node.children.every(function(n) {
188 return n.state[State.INVISIBLE]; 164 return n.state[State.INVISIBLE];
189 }); 165 });
190 }; 166 };
191 167
192 /** 168 /**
193 * @param {!AutomationNode} node 169 * @param {!AutomationNode} node
194 * @return {boolean} 170 * @return {boolean}
195 */ 171 */
196 AutomationPredicate.leafWithText = function(node) { 172 AutomationPredicate.leafWithText = function(node) {
197 return AutomationPredicate.leaf(node) && 173 return AutomationPredicate.leaf(node) && !!(node.name || node.value);
198 !!(node.name || node.value);
199 }; 174 };
200 175
201 /** 176 /**
202 * Matches against leaves or static text nodes. Useful when restricting 177 * Matches against leaves or static text nodes. Useful when restricting
203 * traversal to non-inline textboxes while still allowing them if navigation 178 * traversal to non-inline textboxes while still allowing them if navigation
204 * already entered into an inline textbox. 179 * already entered into an inline textbox.
205 * @param {!AutomationNode} node 180 * @param {!AutomationNode} node
206 * @return {boolean} 181 * @return {boolean}
207 */ 182 */
208 AutomationPredicate.leafOrStaticText = function(node) { 183 AutomationPredicate.leafOrStaticText = function(node) {
209 return AutomationPredicate.leaf(node) || 184 return AutomationPredicate.leaf(node) || node.role == Role.STATIC_TEXT;
210 node.role == Role.STATIC_TEXT;
211 }; 185 };
212 186
213 /** 187 /**
214 * Matches against nodes visited during object navigation. An object as 188 * 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 189 * 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 190 * tree walking, it should visit all nodes that tab traversal would as well as
217 * non-focusable static text. 191 * non-focusable static text.
218 * @param {!AutomationNode} node 192 * @param {!AutomationNode} node
219 * @return {boolean} 193 * @return {boolean}
220 */ 194 */
221 AutomationPredicate.object = function(node) { 195 AutomationPredicate.object = function(node) {
222 // Editable nodes are within a text-like field and don't make sense when 196 // 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 197 // performing object navigation. Users should use line, word, or character
224 // navigation. Only navigate to the top level node. 198 // navigation. Only navigate to the top level node.
225 if (node.parent && node.parent.state.editable) 199 if (node.parent && node.parent.state.editable)
226 return false; 200 return false;
227 201
228 // Descend into large nodes. 202 // Descend into large nodes.
229 if (node.name && node.name.length > constants.OBJECT_MAX_CHARCOUNT) 203 if (node.name && node.name.length > constants.OBJECT_MAX_CHARCOUNT)
230 return false; 204 return false;
231 205
232 return node.state.focusable || 206 return node.state.focusable ||
233 (AutomationPredicate.leafOrStaticText(node) && 207 (AutomationPredicate.leafOrStaticText(node) &&
234 (/\S+/.test(node.name) || 208 (/\S+/.test(node.name) ||
235 (node.role != Role.LINE_BREAK && 209 (node.role != Role.LINE_BREAK && node.role != Role.STATIC_TEXT &&
236 node.role != Role.STATIC_TEXT &&
237 node.role != Role.INLINE_TEXT_BOX))); 210 node.role != Role.INLINE_TEXT_BOX)));
238 }; 211 };
239 212
240 /** 213 /**
241 * Matches against nodes visited during group navigation. An object as 214 * Matches against nodes visited during group navigation. An object as
242 * @param {!AutomationNode} node 215 * @param {!AutomationNode} node
243 * @return {boolean} 216 * @return {boolean}
244 */ 217 */
245 AutomationPredicate.group = AutomationPredicate.match({ 218 AutomationPredicate.group = AutomationPredicate.match({
246 anyRole: [ 219 anyRole: [Role.HEADING, Role.LIST, Role.PARAGRAPH],
247 Role.HEADING,
248 Role.LIST,
249 Role.PARAGRAPH
250 ],
251 anyPredicate: [ 220 anyPredicate: [
252 AutomationPredicate.editText, 221 AutomationPredicate.editText, AutomationPredicate.formField,
253 AutomationPredicate.formField, 222 AutomationPredicate.object, AutomationPredicate.table
254 AutomationPredicate.object,
255 AutomationPredicate.table
256 ] 223 ]
257 }); 224 });
258 225
259 /** 226 /**
260 * @param {!AutomationNode} first 227 * @param {!AutomationNode} first
261 * @param {!AutomationNode} second 228 * @param {!AutomationNode} second
262 * @return {boolean} 229 * @return {boolean}
263 */ 230 */
264 AutomationPredicate.linebreak = function(first, second) { 231 AutomationPredicate.linebreak = function(first, second) {
265 // TODO(dtseng): Use next/previousOnLin once available. 232 // TODO(dtseng): Use next/previousOnLin once available.
266 var fl = first.location; 233 var fl = first.location;
267 var sl = second.location; 234 var sl = second.location;
268 return fl.top != sl.top || 235 return fl.top != sl.top || (fl.top + fl.height != sl.top + sl.height);
269 (fl.top + fl.height != sl.top + sl.height);
270 }; 236 };
271 237
272 /** 238 /**
273 * Matches against a node that contains other interesting nodes. 239 * Matches against a node that contains other interesting nodes.
274 * These nodes should always have their subtrees scanned when navigating. 240 * These nodes should always have their subtrees scanned when navigating.
275 * @param {!AutomationNode} node 241 * @param {!AutomationNode} node
276 * @return {boolean} 242 * @return {boolean}
277 */ 243 */
278 AutomationPredicate.container = function(node) { 244 AutomationPredicate.container = function(node) {
279 return AutomationPredicate.match({ 245 return AutomationPredicate.match({
280 anyRole: [ 246 anyRole: [
281 Role.GENERIC_CONTAINER, 247 Role.GENERIC_CONTAINER, Role.DOCUMENT, Role.GROUP, Role.LIST_ITEM,
282 Role.DOCUMENT, 248 Role.TOOLBAR, Role.WINDOW
283 Role.GROUP, 249 ],
284 Role.LIST_ITEM,
285 Role.TOOLBAR,
286 Role.WINDOW],
287 anyPredicate: [ 250 anyPredicate: [
288 AutomationPredicate.landmark, 251 AutomationPredicate.landmark, AutomationPredicate.structuralContainer,
289 AutomationPredicate.structuralContainer,
290 function(node) { 252 function(node) {
291 // For example, crosh. 253 // For example, crosh.
292 return (node.role == Role.TEXT_FIELD && node.state.readOnly); 254 return (node.role == Role.TEXT_FIELD && node.state.readOnly);
293 }, 255 },
294 function(node) { 256 function(node) {
295 return (node.state.editable && 257 return (
296 node.parent && 258 node.state.editable && node.parent && !node.parent.state.editable);
297 !node.parent.state.editable); 259 }
298 }] 260 ]
299 })(node); 261 })(node);
300 }; 262 };
301 263
302 /** 264 /**
303 * Matches against nodes that contain interesting nodes, but should never be 265 * Matches against nodes that contain interesting nodes, but should never be
304 * visited. 266 * visited.
305 * @param {!AutomationNode} node 267 * @param {!AutomationNode} node
306 * @return {boolean} 268 * @return {boolean}
307 */ 269 */
308 AutomationPredicate.structuralContainer = AutomationPredicate.roles([ 270 AutomationPredicate.structuralContainer = AutomationPredicate.roles([
309 Role.ALERT_DIALOG, 271 Role.ALERT_DIALOG, Role.DIALOG, Role.ROOT_WEB_AREA, Role.WEB_VIEW,
310 Role.DIALOG, 272 Role.WINDOW, Role.EMBEDDED_OBJECT, Role.IFRAME, Role.IFRAME_PRESENTATIONAL,
311 Role.ROOT_WEB_AREA, 273 Role.UNKNOWN
312 Role.WEB_VIEW, 274 ]);
313 Role.WINDOW,
314 Role.EMBEDDED_OBJECT,
315 Role.IFRAME,
316 Role.IFRAME_PRESENTATIONAL,
317 Role.UNKNOWN]);
318 275
319 /** 276 /**
320 * Returns whether the given node should not be crossed when performing 277 * Returns whether the given node should not be crossed when performing
321 * traversals up the ancestry chain. 278 * traversals up the ancestry chain.
322 * @param {AutomationNode} node 279 * @param {AutomationNode} node
323 * @return {boolean} 280 * @return {boolean}
324 */ 281 */
325 AutomationPredicate.root = function(node) { 282 AutomationPredicate.root = function(node) {
326 switch (node.role) { 283 switch (node.role) {
327 case Role.WINDOW: 284 case Role.WINDOW:
328 return true; 285 return true;
329 case Role.DIALOG: 286 case Role.DIALOG:
330 // The below logic handles nested dialogs properly in the desktop tree 287 // The below logic handles nested dialogs properly in the desktop tree
331 // like that found in a bubble view. 288 // like that found in a bubble view.
332 return node.root.role != Role.DESKTOP || 289 return node.root.role != Role.DESKTOP ||
333 (!!node.parent && 290 (!!node.parent && node.parent.role == Role.WINDOW &&
334 node.parent.role == Role.WINDOW &&
335 node.parent.children.every(function(child) { 291 node.parent.children.every(function(child) {
336 return node.role == Role.WINDOW || node.role == Role.DIALOG; 292 return node.role == Role.WINDOW || node.role == Role.DIALOG;
337 })); 293 }));
338 case Role.TOOLBAR: 294 case Role.TOOLBAR:
339 return node.root.role == Role.DESKTOP; 295 return node.root.role == Role.DESKTOP;
340 case Role.ROOT_WEB_AREA: 296 case Role.ROOT_WEB_AREA:
341 return !node.parent || node.parent.root.role == Role.DESKTOP; 297 return !node.parent || node.parent.root.role == Role.DESKTOP;
342 default: 298 default:
343 return false; 299 return false;
344 } 300 }
(...skipping 17 matching lines...) Expand all
362 318
363 // Ignore list markers since we already announce listitem role. 319 // Ignore list markers since we already announce listitem role.
364 if (node.role == Role.LIST_MARKER) 320 if (node.role == Role.LIST_MARKER)
365 return true; 321 return true;
366 322
367 // Don't ignore nodes with names or name-like attribute. 323 // Don't ignore nodes with names or name-like attribute.
368 if (node.name || node.value || node.description || node.url) 324 if (node.name || node.value || node.description || node.url)
369 return false; 325 return false;
370 326
371 // Ignore some roles. 327 // Ignore some roles.
372 return AutomationPredicate.leaf(node) && 328 return AutomationPredicate.leaf(node) && (AutomationPredicate.roles([
373 (AutomationPredicate.roles([Role.CLIENT, 329 Role.CLIENT, Role.COLUMN, Role.GENERIC_CONTAINER, Role.GROUP,
374 Role.COLUMN, 330 Role.IMAGE, Role.STATIC_TEXT, Role.SVG_ROOT,
375 Role.GENERIC_CONTAINER, 331 Role.TABLE_HEADER_CONTAINER, Role.UNKNOWN
376 Role.GROUP, 332 ])(node));
377 Role.IMAGE,
378 Role.STATIC_TEXT,
379 Role.SVG_ROOT,
380 Role.TABLE_HEADER_CONTAINER,
381 Role.UNKNOWN
382 ])(node));
383 }; 333 };
384 334
385 /** 335 /**
386 * Returns if the node has a meaningful checked state. 336 * Returns if the node has a meaningful checked state.
387 * @param {!AutomationNode} node 337 * @param {!AutomationNode} node
388 * @return {boolean} 338 * @return {boolean}
389 */ 339 */
390 AutomationPredicate.checkable = AutomationPredicate.roles([ 340 AutomationPredicate.checkable = AutomationPredicate.roles([
391 Role.CHECK_BOX, 341 Role.CHECK_BOX, Role.RADIO_BUTTON, Role.MENU_ITEM_CHECK_BOX,
392 Role.RADIO_BUTTON, 342 Role.MENU_ITEM_RADIO, Role.TREE_ITEM
393 Role.MENU_ITEM_CHECK_BOX, 343 ]);
394 Role.MENU_ITEM_RADIO,
395 Role.TREE_ITEM]);
396 344
397 // Table related predicates. 345 // Table related predicates.
398 /** 346 /**
399 * Returns if the node has a cell like role. 347 * Returns if the node has a cell like role.
400 * @param {!AutomationNode} node 348 * @param {!AutomationNode} node
401 * @return {boolean} 349 * @return {boolean}
402 */ 350 */
403 AutomationPredicate.cellLike = AutomationPredicate.roles([ 351 AutomationPredicate.cellLike =
404 Role.CELL, 352 AutomationPredicate.roles([Role.CELL, Role.ROW_HEADER, Role.COLUMN_HEADER]);
405 Role.ROW_HEADER,
406 Role.COLUMN_HEADER]);
407 353
408 /** 354 /**
409 * Returns a predicate that will match against the directed next cell taking 355 * Returns a predicate that will match against the directed next cell taking
410 * into account the current ancestor cell's position in the table. 356 * into account the current ancestor cell's position in the table.
411 * @param {AutomationNode} start 357 * @param {AutomationNode} start
412 * @param {{dir: (Dir|undefined), 358 * @param {{dir: (Dir|undefined),
413 * row: (boolean|undefined), 359 * row: (boolean|undefined),
414 * col: (boolean|undefined)}} opts 360 * col: (boolean|undefined)}} opts
415 * |dir|, specifies direction for |row or/and |col| movement by one cell. 361 * |dir|, specifies direction for |row or/and |col| movement by one cell.
416 * |dir| defaults to forward. 362 * |dir| defaults to forward.
417 * |row| and |col| are both false by default. 363 * |row| and |col| are both false by default.
418 * |end| defaults to false. If set to true, |col| must also be set to true. 364 * |end| defaults to false. If set to true, |col| must also be set to true.
419 * It will then return the first or last cell in the current column. 365 * It will then return the first or last cell in the current column.
420 * @return {?AutomationPredicate.Unary} Returns null if not in a table. 366 * @return {?AutomationPredicate.Unary} Returns null if not in a table.
421 */ 367 */
422 AutomationPredicate.makeTableCellPredicate = function(start, opts) { 368 AutomationPredicate.makeTableCellPredicate = function(start, opts) {
423 if (!opts.row && !opts.col) 369 if (!opts.row && !opts.col)
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 return function(node) { 431 return function(node) {
486 return node.role == Role.HEADING && node.hierarchicalLevel == level; 432 return node.role == Role.HEADING && node.hierarchicalLevel == level;
487 }; 433 };
488 }; 434 };
489 435
490 /** 436 /**
491 * Matches against nodes that we may be able to retrieve image data from. 437 * Matches against nodes that we may be able to retrieve image data from.
492 * @param {!AutomationNode} node 438 * @param {!AutomationNode} node
493 * @return {boolean} 439 * @return {boolean}
494 */ 440 */
495 AutomationPredicate.supportsImageData = AutomationPredicate.roles([ 441 AutomationPredicate.supportsImageData =
496 Role.CANVAS, 442 AutomationPredicate.roles([Role.CANVAS, Role.IMAGE, Role.VIDEO]);
497 Role.IMAGE,
498 Role.VIDEO]);
499 443
500 }); // goog.scope 444 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698