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