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 A collection of JavaScript utilities used to simplify working | 6 * @fileoverview A collection of JavaScript utilities used to simplify working |
7 * with ARIA (http://www.w3.org/TR/wai-aria). | 7 * with ARIA (http://www.w3.org/TR/wai-aria). |
8 */ | 8 */ |
9 | 9 |
10 | 10 |
11 goog.provide('cvox.AriaUtil'); | 11 goog.provide('cvox.AriaUtil'); |
12 goog.require('cvox.AbstractEarcons'); | 12 goog.require('cvox.AbstractEarcons'); |
13 goog.require('cvox.ChromeVox'); | 13 goog.require('cvox.ChromeVox'); |
14 goog.require('cvox.NodeState'); | 14 goog.require('cvox.NodeState'); |
15 goog.require('cvox.NodeStateUtil'); | 15 goog.require('cvox.NodeStateUtil'); |
16 | 16 |
17 | 17 |
18 /** | 18 /** |
19 * Create the namespace | 19 * Create the namespace |
20 * @constructor | 20 * @constructor |
21 */ | 21 */ |
22 cvox.AriaUtil = function() { | 22 cvox.AriaUtil = function() {}; |
23 }; | |
24 | 23 |
25 | 24 |
26 /** | 25 /** |
27 * A mapping from ARIA role names to their message ids. | 26 * A mapping from ARIA role names to their message ids. |
28 * Note: If you are adding a new mapping, the new message identifier needs a | 27 * Note: If you are adding a new mapping, the new message identifier needs a |
29 * corresponding braille message. For example, a message id 'tag_button' | 28 * corresponding braille message. For example, a message id 'tag_button' |
30 * requires another message 'tag_button_brl' within messages.js. | 29 * requires another message 'tag_button_brl' within messages.js. |
31 * @type {Object<string>} | 30 * @type {Object<string>} |
32 */ | 31 */ |
33 cvox.AriaUtil.WIDGET_ROLE_TO_NAME = { | 32 cvox.AriaUtil.WIDGET_ROLE_TO_NAME = { |
34 'alert' : 'role_alert', | 33 'alert': 'role_alert', |
35 'alertdialog' : 'role_alertdialog', | 34 'alertdialog': 'role_alertdialog', |
36 'button' : 'role_button', | 35 'button': 'role_button', |
37 'checkbox' : 'role_checkbox', | 36 'checkbox': 'role_checkbox', |
38 'columnheader' : 'role_columnheader', | 37 'columnheader': 'role_columnheader', |
39 'combobox' : 'role_combobox', | 38 'combobox': 'role_combobox', |
40 'dialog' : 'role_dialog', | 39 'dialog': 'role_dialog', |
41 'grid' : 'role_grid', | 40 'grid': 'role_grid', |
42 'gridcell' : 'role_gridcell', | 41 'gridcell': 'role_gridcell', |
43 'link' : 'role_link', | 42 'link': 'role_link', |
44 'listbox' : 'role_listbox', | 43 'listbox': 'role_listbox', |
45 'log' : 'role_log', | 44 'log': 'role_log', |
46 'marquee' : 'role_marquee', | 45 'marquee': 'role_marquee', |
47 'menu' : 'role_menu', | 46 'menu': 'role_menu', |
48 'menubar' : 'role_menubar', | 47 'menubar': 'role_menubar', |
49 'menuitem' : 'role_menuitem', | 48 'menuitem': 'role_menuitem', |
50 'menuitemcheckbox' : 'role_menuitemcheckbox', | 49 'menuitemcheckbox': 'role_menuitemcheckbox', |
51 'menuitemradio' : 'role_menuitemradio', | 50 'menuitemradio': 'role_menuitemradio', |
52 'option' : 'role_option', | 51 'option': 'role_option', |
53 'progressbar' : 'role_progressbar', | 52 'progressbar': 'role_progressbar', |
54 'radio' : 'role_radio', | 53 'radio': 'role_radio', |
55 'radiogroup' : 'role_radiogroup', | 54 'radiogroup': 'role_radiogroup', |
56 'rowheader' : 'role_rowheader', | 55 'rowheader': 'role_rowheader', |
57 'scrollbar' : 'role_scrollbar', | 56 'scrollbar': 'role_scrollbar', |
58 'slider' : 'role_slider', | 57 'slider': 'role_slider', |
59 'spinbutton' : 'role_spinbutton', | 58 'spinbutton': 'role_spinbutton', |
60 'status' : 'role_status', | 59 'status': 'role_status', |
61 'tab' : 'role_tab', | 60 'tab': 'role_tab', |
62 'tablist' : 'role_tablist', | 61 'tablist': 'role_tablist', |
63 'tabpanel' : 'role_tabpanel', | 62 'tabpanel': 'role_tabpanel', |
64 'textbox' : 'role_textbox', | 63 'textbox': 'role_textbox', |
65 'timer' : 'role_timer', | 64 'timer': 'role_timer', |
66 'toolbar' : 'role_toolbar', | 65 'toolbar': 'role_toolbar', |
67 'tooltip' : 'role_tooltip', | 66 'tooltip': 'role_tooltip', |
68 'treeitem' : 'role_treeitem' | 67 'treeitem': 'role_treeitem' |
69 }; | 68 }; |
70 | 69 |
71 | 70 |
72 /** | 71 /** |
73 * Note: If you are adding a new mapping, the new message identifier needs a | 72 * Note: If you are adding a new mapping, the new message identifier needs a |
74 * corresponding braille message. For example, a message id 'tag_button' | 73 * corresponding braille message. For example, a message id 'tag_button' |
75 * requires another message 'tag_button_brl' within messages.js. | 74 * requires another message 'tag_button_brl' within messages.js. |
76 * @type {Object<string>} | 75 * @type {Object<string>} |
77 */ | 76 */ |
78 cvox.AriaUtil.STRUCTURE_ROLE_TO_NAME = { | 77 cvox.AriaUtil.STRUCTURE_ROLE_TO_NAME = { |
79 'article' : 'role_article', | 78 'article': 'role_article', |
80 'application' : 'role_application', | 79 'application': 'role_application', |
81 'banner' : 'role_banner', | 80 'banner': 'role_banner', |
82 'columnheader' : 'role_columnheader', | 81 'columnheader': 'role_columnheader', |
83 'complementary' : 'role_complementary', | 82 'complementary': 'role_complementary', |
84 'contentinfo' : 'role_contentinfo', | 83 'contentinfo': 'role_contentinfo', |
85 'definition' : 'role_definition', | 84 'definition': 'role_definition', |
86 'directory' : 'role_directory', | 85 'directory': 'role_directory', |
87 'document' : 'role_document', | 86 'document': 'role_document', |
88 'form' : 'role_form', | 87 'form': 'role_form', |
89 'group' : 'role_group', | 88 'group': 'role_group', |
90 'heading' : 'role_heading', | 89 'heading': 'role_heading', |
91 'img' : 'role_img', | 90 'img': 'role_img', |
92 'list' : 'role_list', | 91 'list': 'role_list', |
93 'listitem' : 'role_listitem', | 92 'listitem': 'role_listitem', |
94 'main' : 'role_main', | 93 'main': 'role_main', |
95 'math' : 'role_math', | 94 'math': 'role_math', |
96 'navigation' : 'role_navigation', | 95 'navigation': 'role_navigation', |
97 'note' : 'role_note', | 96 'note': 'role_note', |
98 'region' : 'role_region', | 97 'region': 'role_region', |
99 'rowheader' : 'role_rowheader', | 98 'rowheader': 'role_rowheader', |
100 'search' : 'role_search', | 99 'search': 'role_search', |
101 'separator' : 'role_separator' | 100 'separator': 'role_separator' |
102 }; | 101 }; |
103 | 102 |
104 | 103 |
105 /** | 104 /** |
106 * @type {Array<Object>} | 105 * @type {Array<Object>} |
107 */ | 106 */ |
108 cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS = [ | 107 cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS = [ |
109 { name: 'aria-autocomplete', values: | 108 { |
110 {'inline' : 'aria_autocomplete_inline', | 109 name: 'aria-autocomplete', |
111 'list' : 'aria_autocomplete_list', | 110 values: { |
112 'both' : 'aria_autocomplete_both'} }, | 111 'inline': 'aria_autocomplete_inline', |
113 { name: 'aria-checked', values: | 112 'list': 'aria_autocomplete_list', |
114 {'true' : 'checked_true', | 113 'both': 'aria_autocomplete_both' |
115 'false' : 'checked_false', | 114 } |
116 'mixed' : 'checked_mixed'} }, | 115 }, |
117 { name: 'aria-disabled', values: | 116 { |
118 {'true' : 'aria_disabled_true'} }, | 117 name: 'aria-checked', |
119 { name: 'aria-expanded', values: | 118 values: { |
120 {'true' : 'aria_expanded_true', | 119 'true': 'checked_true', |
121 'false' : 'aria_expanded_false'} }, | 120 'false': 'checked_false', |
122 { name: 'aria-invalid', values: | 121 'mixed': 'checked_mixed' |
123 {'true' : 'aria_invalid_true', | 122 } |
124 'grammar' : 'aria_invalid_grammar', | 123 }, |
125 'spelling' : 'aria_invalid_spelling'} }, | 124 {name: 'aria-disabled', values: {'true': 'aria_disabled_true'}}, { |
126 { name: 'aria-multiline', values: | 125 name: 'aria-expanded', |
127 {'true' : 'aria_multiline_true'} }, | 126 values: {'true': 'aria_expanded_true', 'false': 'aria_expanded_false'} |
128 { name: 'aria-multiselectable', values: | 127 }, |
129 {'true' : 'aria_multiselectable_true'} }, | 128 { |
130 { name: 'aria-pressed', values: | 129 name: 'aria-invalid', |
131 {'true' : 'aria_pressed_true', | 130 values: { |
132 'false' : 'aria_pressed_false', | 131 'true': 'aria_invalid_true', |
133 'mixed' : 'aria_pressed_mixed'} }, | 132 'grammar': 'aria_invalid_grammar', |
134 { name: 'aria-readonly', values: | 133 'spelling': 'aria_invalid_spelling' |
135 {'true' : 'aria_readonly_true'} }, | 134 } |
136 { name: 'aria-required', values: | 135 }, |
137 {'true' : 'aria_required_true'} }, | 136 {name: 'aria-multiline', values: {'true': 'aria_multiline_true'}}, |
138 { name: 'aria-selected', values: | 137 {name: 'aria-multiselectable', values: {'true': 'aria_multiselectable_true'}}, |
139 {'true' : 'aria_selected_true', | 138 { |
140 'false' : 'aria_selected_false'} } | 139 name: 'aria-pressed', |
| 140 values: { |
| 141 'true': 'aria_pressed_true', |
| 142 'false': 'aria_pressed_false', |
| 143 'mixed': 'aria_pressed_mixed' |
| 144 } |
| 145 }, |
| 146 {name: 'aria-readonly', values: {'true': 'aria_readonly_true'}}, |
| 147 {name: 'aria-required', values: {'true': 'aria_required_true'}}, { |
| 148 name: 'aria-selected', |
| 149 values: {'true': 'aria_selected_true', 'false': 'aria_selected_false'} |
| 150 } |
141 ]; | 151 ]; |
142 | 152 |
143 | 153 |
144 /** | 154 /** |
145 * Checks if a node should be treated as a hidden node because of its ARIA | 155 * Checks if a node should be treated as a hidden node because of its ARIA |
146 * markup. | 156 * markup. |
147 * | 157 * |
148 * @param {Node} targetNode The node to check. | 158 * @param {Node} targetNode The node to check. |
149 * @return {boolean} True if the targetNode should be treated as hidden. | 159 * @return {boolean} True if the targetNode should be treated as hidden. |
150 */ | 160 */ |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 */ | 277 */ |
268 cvox.AriaUtil.isButton = function(node) { | 278 cvox.AriaUtil.isButton = function(node) { |
269 var role = cvox.AriaUtil.getRoleAttribute(node); | 279 var role = cvox.AriaUtil.getRoleAttribute(node); |
270 if (role == 'button') { | 280 if (role == 'button') { |
271 return true; | 281 return true; |
272 } | 282 } |
273 if (node.tagName == 'BUTTON') { | 283 if (node.tagName == 'BUTTON') { |
274 return true; | 284 return true; |
275 } | 285 } |
276 if (node.tagName == 'INPUT') { | 286 if (node.tagName == 'INPUT') { |
277 return (node.type == 'submit' || | 287 return ( |
278 node.type == 'reset' || | 288 node.type == 'submit' || node.type == 'reset' || node.type == 'button'); |
279 node.type == 'button'); | |
280 } | 289 } |
281 return false; | 290 return false; |
282 }; | 291 }; |
283 | 292 |
284 /** | 293 /** |
285 * Returns a role message identifier for a node. | 294 * Returns a role message identifier for a node. |
286 * For a localized string, see cvox.AriaUtil.getRoleName. | 295 * For a localized string, see cvox.AriaUtil.getRoleName. |
287 * @param {Node} targetNode The node to get the role name for. | 296 * @param {Node} targetNode The node to get the role name for. |
288 * @return {string} The role name message identifier for the targetNode. | 297 * @return {string} The role name message identifier for the targetNode. |
289 */ | 298 */ |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 * opposed to an ancestor, where we might be more brief. | 367 * opposed to an ancestor, where we might be more brief. |
359 * @return {cvox.NodeState} The status information about the node. | 368 * @return {cvox.NodeState} The status information about the node. |
360 */ | 369 */ |
361 cvox.AriaUtil.getStateMsgs = function(targetNode, primary) { | 370 cvox.AriaUtil.getStateMsgs = function(targetNode, primary) { |
362 var state = []; | 371 var state = []; |
363 if (!targetNode || !targetNode.getAttribute) { | 372 if (!targetNode || !targetNode.getAttribute) { |
364 return state; | 373 return state; |
365 } | 374 } |
366 | 375 |
367 for (var i = 0, attr; attr = cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS[i]; | 376 for (var i = 0, attr; attr = cvox.AriaUtil.ATTRIBUTE_VALUE_TO_STATUS[i]; |
368 i++) { | 377 i++) { |
369 var value = targetNode.getAttribute(attr.name); | 378 var value = targetNode.getAttribute(attr.name); |
370 var msgId = attr.values[value]; | 379 var msgId = attr.values[value]; |
371 if (msgId) { | 380 if (msgId) { |
372 state.push([msgId]); | 381 state.push([msgId]); |
373 } | 382 } |
374 } | 383 } |
375 if (targetNode.getAttribute('role') == 'grid') { | 384 if (targetNode.getAttribute('role') == 'grid') { |
376 return cvox.AriaUtil.getGridState_(targetNode, targetNode); | 385 return cvox.AriaUtil.getGridState_(targetNode, targetNode); |
377 } | 386 } |
378 | 387 |
379 var role = cvox.AriaUtil.getRoleAttribute(targetNode); | 388 var role = cvox.AriaUtil.getRoleAttribute(targetNode); |
380 if (targetNode.getAttribute('aria-haspopup') == 'true') { | 389 if (targetNode.getAttribute('aria-haspopup') == 'true') { |
381 if (role == 'menuitem') { | 390 if (role == 'menuitem') { |
382 state.push(['has_submenu']); | 391 state.push(['has_submenu']); |
383 } else if (cvox.AriaUtil.isButton(targetNode)) { | 392 } else if (cvox.AriaUtil.isButton(targetNode)) { |
384 // Do nothing - the role name will be 'pop-up button'. | 393 // Do nothing - the role name will be 'pop-up button'. |
385 } else { | 394 } else { |
386 state.push(['has_popup']); | 395 state.push(['has_popup']); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 // If this is a composite control or an item within a composite control, | 432 // If this is a composite control or an item within a composite control, |
424 // get the index and count of the current descendant or active | 433 // get the index and count of the current descendant or active |
425 // descendant. | 434 // descendant. |
426 var parentControl = targetNode; | 435 var parentControl = targetNode; |
427 var currentDescendant = null; | 436 var currentDescendant = null; |
428 | 437 |
429 if (cvox.AriaUtil.isCompositeControl(parentControl) && primary) { | 438 if (cvox.AriaUtil.isCompositeControl(parentControl) && primary) { |
430 currentDescendant = cvox.AriaUtil.getActiveDescendant(parentControl); | 439 currentDescendant = cvox.AriaUtil.getActiveDescendant(parentControl); |
431 } else { | 440 } else { |
432 role = cvox.AriaUtil.getRoleAttribute(targetNode); | 441 role = cvox.AriaUtil.getRoleAttribute(targetNode); |
433 if (role == 'option' || | 442 if (role == 'option' || role == 'menuitem' || role == 'menuitemcheckbox' || |
434 role == 'menuitem' || | 443 role == 'menuitemradio' || role == 'radio' || role == 'tab' || |
435 role == 'menuitemcheckbox' || | |
436 role == 'menuitemradio' || | |
437 role == 'radio' || | |
438 role == 'tab' || | |
439 role == 'treeitem') { | 444 role == 'treeitem') { |
440 currentDescendant = targetNode; | 445 currentDescendant = targetNode; |
441 parentControl = targetNode.parentElement; | 446 parentControl = targetNode.parentElement; |
442 while (parentControl && | 447 while (parentControl && |
443 !cvox.AriaUtil.isCompositeControl(parentControl)) { | 448 !cvox.AriaUtil.isCompositeControl(parentControl)) { |
444 parentControl = parentControl.parentElement; | 449 parentControl = parentControl.parentElement; |
445 if (parentControl && | 450 if (parentControl && |
446 cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') { | 451 cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') { |
447 break; | 452 break; |
448 } | 453 } |
449 } | 454 } |
450 } | 455 } |
451 } | 456 } |
452 | 457 |
453 if (parentControl && | 458 if (parentControl && |
454 (cvox.AriaUtil.isCompositeControl(parentControl) || | 459 (cvox.AriaUtil.isCompositeControl(parentControl) || |
455 cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') && | 460 cvox.AriaUtil.getRoleAttribute(parentControl) == 'treeitem') && |
456 currentDescendant) { | 461 currentDescendant) { |
457 var parentRole = cvox.AriaUtil.getRoleAttribute(parentControl); | 462 var parentRole = cvox.AriaUtil.getRoleAttribute(parentControl); |
458 var descendantRoleList; | 463 var descendantRoleList; |
459 switch (parentRole) { | 464 switch (parentRole) { |
460 case 'combobox': | 465 case 'combobox': |
461 case 'listbox': | 466 case 'listbox': |
462 descendantRoleList = ['option']; | 467 descendantRoleList = ['option']; |
463 break; | 468 break; |
464 case 'menu': | 469 case 'menu': |
465 descendantRoleList = ['menuitem', | 470 descendantRoleList = ['menuitem', 'menuitemcheckbox', 'menuitemradio']; |
466 'menuitemcheckbox', | |
467 'menuitemradio']; | |
468 break; | 471 break; |
469 case 'radiogroup': | 472 case 'radiogroup': |
470 descendantRoleList = ['radio']; | 473 descendantRoleList = ['radio']; |
471 break; | 474 break; |
472 case 'tablist': | 475 case 'tablist': |
473 descendantRoleList = ['tab']; | 476 descendantRoleList = ['tab']; |
474 break; | 477 break; |
475 case 'tree': | 478 case 'tree': |
476 case 'treegrid': | 479 case 'treegrid': |
477 case 'treeitem': | 480 case 'treeitem': |
(...skipping 10 matching lines...) Expand all Loading... |
488 if (!isNaN(ariaLength)) { | 491 if (!isNaN(ariaLength)) { |
489 listLength = ariaLength; | 492 listLength = ariaLength; |
490 } | 493 } |
491 var ariaIndex = | 494 var ariaIndex = |
492 parseInt(currentDescendant.getAttribute('aria-posinset'), 10); | 495 parseInt(currentDescendant.getAttribute('aria-posinset'), 10); |
493 if (!isNaN(ariaIndex)) { | 496 if (!isNaN(ariaIndex)) { |
494 currentIndex = ariaIndex; | 497 currentIndex = ariaIndex; |
495 } | 498 } |
496 | 499 |
497 if (listLength == undefined || currentIndex == undefined) { | 500 if (listLength == undefined || currentIndex == undefined) { |
498 var descendants = cvox.AriaUtil.getNextLevel(parentControl, | 501 var descendants = |
499 descendantRoleList); | 502 cvox.AriaUtil.getNextLevel(parentControl, descendantRoleList); |
500 if (listLength == undefined) { | 503 if (listLength == undefined) { |
501 listLength = descendants.length; | 504 listLength = descendants.length; |
502 } | 505 } |
503 if (currentIndex == undefined) { | 506 if (currentIndex == undefined) { |
504 for (var j = 0; j < descendants.length; j++) { | 507 for (var j = 0; j < descendants.length; j++) { |
505 if (descendants[j] == currentDescendant) { | 508 if (descendants[j] == currentDescendant) { |
506 currentIndex = j + 1; | 509 currentIndex = j + 1; |
507 } | 510 } |
508 } | 511 } |
509 } | 512 } |
(...skipping 20 matching lines...) Expand all Loading... |
530 | 533 |
531 if (activeDescendant) { | 534 if (activeDescendant) { |
532 var descendantSelector = '*[role~="row"]'; | 535 var descendantSelector = '*[role~="row"]'; |
533 var rows = parentControl.querySelectorAll(descendantSelector); | 536 var rows = parentControl.querySelectorAll(descendantSelector); |
534 var currentIndex = null; | 537 var currentIndex = null; |
535 for (var j = 0; j < rows.length; j++) { | 538 for (var j = 0; j < rows.length; j++) { |
536 var gridcells = rows[j].querySelectorAll('*[role~="gridcell"]'); | 539 var gridcells = rows[j].querySelectorAll('*[role~="gridcell"]'); |
537 for (var k = 0; k < gridcells.length; k++) { | 540 for (var k = 0; k < gridcells.length; k++) { |
538 if (gridcells[k] == activeDescendant) { | 541 if (gridcells[k] == activeDescendant) { |
539 return /** @type {cvox.NodeState} */ ( | 542 return /** @type {cvox.NodeState} */ ( |
540 [['role_gridcell_pos', j + 1, k + 1]]); | 543 [['role_gridcell_pos', j + 1, k + 1]]); |
541 } | 544 } |
542 } | 545 } |
543 } | 546 } |
544 } | 547 } |
545 return []; | 548 return []; |
546 }; | 549 }; |
547 | 550 |
548 | 551 |
549 /** | 552 /** |
550 * Returns the id of a node's active descendant | 553 * Returns the id of a node's active descendant |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 594 |
592 | 595 |
593 /** | 596 /** |
594 * Recursively finds the first node(s) that match the role. | 597 * Recursively finds the first node(s) that match the role. |
595 * | 598 * |
596 * @param {Node} current The node to start looking at. | 599 * @param {Node} current The node to start looking at. |
597 * @param {Array<string>} role The role(s) to match. | 600 * @param {Array<string>} role The role(s) to match. |
598 * @return {Array<Element>} The array of matching nodes. | 601 * @return {Array<Element>} The array of matching nodes. |
599 */ | 602 */ |
600 cvox.AriaUtil.getNextLevelItems = function(current, role) { | 603 cvox.AriaUtil.getNextLevelItems = function(current, role) { |
601 if (current.nodeType != 1) { // If reached a node that is not an element. | 604 if (current.nodeType != 1) { // If reached a node that is not an element. |
602 return []; | 605 return []; |
603 } | 606 } |
604 if (role.indexOf(cvox.AriaUtil.getRoleAttribute(current)) != -1) { | 607 if (role.indexOf(cvox.AriaUtil.getRoleAttribute(current)) != -1) { |
605 return [current]; | 608 return [current]; |
606 } else { | 609 } else { |
607 var children = current.childNodes; | 610 var children = current.childNodes; |
608 var length = children.length; | 611 var length = children.length; |
609 if (length == 0) { | 612 if (length == 0) { |
610 return []; | 613 return []; |
611 } else { | 614 } else { |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 } else { | 806 } else { |
804 value = 'additions text'; | 807 value = 'additions text'; |
805 } | 808 } |
806 if (value == 'all') { | 809 if (value == 'all') { |
807 value = 'additions removals text'; | 810 value = 'additions removals text'; |
808 } | 811 } |
809 | 812 |
810 var tokens = value.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').split(' '); | 813 var tokens = value.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').split(' '); |
811 | 814 |
812 if (change == 'all') { | 815 if (change == 'all') { |
813 return (tokens.indexOf('additions') >= 0 && | 816 return ( |
814 tokens.indexOf('text') >= 0 && | 817 tokens.indexOf('additions') >= 0 && tokens.indexOf('text') >= 0 && |
815 tokens.indexOf('removals') >= 0); | 818 tokens.indexOf('removals') >= 0); |
816 } else { | 819 } else { |
817 return (tokens.indexOf(change) >= 0); | 820 return (tokens.indexOf(change) >= 0); |
818 } | 821 } |
819 }; | 822 }; |
820 | 823 |
821 | 824 |
822 /** | 825 /** |
823 * Given a node, return all live regions that are either rooted at this | 826 * Given a node, return all live regions that are either rooted at this |
824 * node or contain this node. | 827 * node or contain this node. |
825 * | 828 * |
(...skipping 25 matching lines...) Expand all Loading... |
851 }; | 854 }; |
852 | 855 |
853 | 856 |
854 /** | 857 /** |
855 * Checks to see whether or not a node is an ARIA landmark. | 858 * Checks to see whether or not a node is an ARIA landmark. |
856 * | 859 * |
857 * @param {Node} node The node to be checked. | 860 * @param {Node} node The node to be checked. |
858 * @return {boolean} Whether or not the node is an ARIA landmark. | 861 * @return {boolean} Whether or not the node is an ARIA landmark. |
859 */ | 862 */ |
860 cvox.AriaUtil.isLandmark = function(node) { | 863 cvox.AriaUtil.isLandmark = function(node) { |
861 if (!node || !node.getAttribute) { | 864 if (!node || !node.getAttribute) { |
862 return false; | |
863 } | |
864 var role = cvox.AriaUtil.getRoleAttribute(node); | |
865 switch (role) { | |
866 case 'application': | |
867 case 'banner': | |
868 case 'complementary': | |
869 case 'contentinfo': | |
870 case 'form': | |
871 case 'main': | |
872 case 'navigation': | |
873 case 'search': | |
874 return true; | |
875 } | |
876 return false; | 865 return false; |
| 866 } |
| 867 var role = cvox.AriaUtil.getRoleAttribute(node); |
| 868 switch (role) { |
| 869 case 'application': |
| 870 case 'banner': |
| 871 case 'complementary': |
| 872 case 'contentinfo': |
| 873 case 'form': |
| 874 case 'main': |
| 875 case 'navigation': |
| 876 case 'search': |
| 877 return true; |
| 878 } |
| 879 return false; |
877 }; | 880 }; |
878 | 881 |
879 | 882 |
880 /** | 883 /** |
881 * Checks to see whether or not a node is an ARIA grid. | 884 * Checks to see whether or not a node is an ARIA grid. |
882 * | 885 * |
883 * @param {Node} node The node to be checked. | 886 * @param {Node} node The node to be checked. |
884 * @return {boolean} Whether or not the node is an ARIA grid. | 887 * @return {boolean} Whether or not the node is an ARIA grid. |
885 */ | 888 */ |
886 cvox.AriaUtil.isGrid = function(node) { | 889 cvox.AriaUtil.isGrid = function(node) { |
887 if (!node || !node.getAttribute) { | 890 if (!node || !node.getAttribute) { |
888 return false; | |
889 } | |
890 var role = cvox.AriaUtil.getRoleAttribute(node); | |
891 switch (role) { | |
892 case 'grid': | |
893 case 'treegrid': | |
894 return true; | |
895 } | |
896 return false; | 891 return false; |
| 892 } |
| 893 var role = cvox.AriaUtil.getRoleAttribute(node); |
| 894 switch (role) { |
| 895 case 'grid': |
| 896 case 'treegrid': |
| 897 return true; |
| 898 } |
| 899 return false; |
897 }; | 900 }; |
898 | 901 |
899 | 902 |
900 /** | 903 /** |
901 * Returns the id of an earcon to play along with the description for a node. | 904 * Returns the id of an earcon to play along with the description for a node. |
902 * | 905 * |
903 * @param {Node} node The node to get the earcon for. | 906 * @param {Node} node The node to get the earcon for. |
904 * @return {cvox.Earcon?} The earcon id, or null if none applies. | 907 * @return {cvox.Earcon?} The earcon id, or null if none applies. |
905 */ | 908 */ |
906 cvox.AriaUtil.getEarcon = function(node) { | 909 cvox.AriaUtil.getEarcon = function(node) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 * @param {Node} node The node to be checked. | 968 * @param {Node} node The node to be checked. |
966 * @return {boolean} Whether or not the node is an ARIA math node. | 969 * @return {boolean} Whether or not the node is an ARIA math node. |
967 */ | 970 */ |
968 cvox.AriaUtil.isMath = function(node) { | 971 cvox.AriaUtil.isMath = function(node) { |
969 if (!node || !node.getAttribute) { | 972 if (!node || !node.getAttribute) { |
970 return false; | 973 return false; |
971 } | 974 } |
972 var role = cvox.AriaUtil.getRoleAttribute(node); | 975 var role = cvox.AriaUtil.getRoleAttribute(node); |
973 return role == 'math'; | 976 return role == 'math'; |
974 }; | 977 }; |
OLD | NEW |