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

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

Issue 2650733002: Revert of Update json_schema_compiler to handle the Automation extension API (Closed)
Patch Set: Created 3 years, 11 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');
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698