summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js204
-rw-r--r--chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs16
2 files changed, 190 insertions, 30 deletions
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
index d5e99ff..4ac38ee 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -78,58 +78,157 @@ Output.SPACE = ' ';
/**
* Metadata about supported automation roles.
- * @const {Object<string, {msgId: string, earcon: (string|undefined)}>}
+ * @const {Object<string, {msgId: string,
+ * earconId: (string|undefined),
+ * inherits: (string|undefined)}>}
+ * msgId: the message id of the role.
+ * earconId: an optional earcon to play when encountering the role.
+ * inherits: inherits rules from this role.
* @private
*/
Output.ROLE_INFO_ = {
alert: {
msgId: 'aria_role_alert',
- earcon: 'ALERT_NONMODAL',
+ earconId: 'ALERT_NONMODAL',
+ },
+ alertDialog: {
+ msgId: 'aria_role_alertdialog'
+ },
+ article: {
+ msgId: 'aria_role_article',
+ inherits: 'abstractContainer'
+ },
+ application: {
+ msgId: 'aria_role_application',
+ inherits: 'abstractContainer'
+ },
+ banner: {
+ msgId: 'aria_role_banner',
+ inherits: 'abstractContainer'
},
button: {
msgId: 'tag_button',
- earcon: 'BUTTON'
+ earconId: 'BUTTON'
+ },
+ cell: {
+ msgId: 'aria_role_gridcell'
},
checkBox: {
msgId: 'input_type_checkbox'
},
+ columnHeader: {
+ msgId: 'aria_role_columnheader',
+ inherits: 'abstractContainer'
+ },
+ comboBox: {
+ msgId: 'aria_role_combobox'
+ },
+ complementary: {
+ msgId: 'aria_role_complementary',
+ inherits: 'abstractContainer'
+ },
+ contentInfo: {
+ msgId: 'aria_role_contentinfo',
+ inherits: 'abstractContainer'
+ },
date: {
- msgId: 'input_type_date'
+ msgId: 'input_type_date',
+ inherits: 'abstractContainer'
+ },
+ definition: {
+ msgId: 'aria_role_definition',
+ inherits: 'abstractContainer'
},
dialog: {
msgId: 'dialog'
},
+ directory: {
+ msgId: 'aria_role_directory',
+ inherits: 'abstractContainer'
+ },
+ document: {
+ msgId: 'aria_role_document',
+ inherits: 'abstractContainer'
+ },
+ form: {
+ msgId: 'aria_role_form',
+ inherits: 'abstractContainer'
+ },
+ grid: {
+ msgId: 'aria_role_grid'
+ },
+ group: {
+ msgId: 'aria_role_group'
+ },
heading: {
msgId: 'aria_role_heading',
},
+ image: {
+ msgId: 'aria_role_img',
+ },
link: {
msgId: 'tag_link',
- earcon: 'LINK'
+ earconId: 'LINK'
},
listBox: {
msgId: 'aria_role_listbox',
- earcon: 'LISTBOX'
+ earconId: 'LISTBOX'
},
listBoxOption: {
msgId: 'aria_role_listitem',
- earcon: 'LIST_ITEM'
+ earconId: 'LIST_ITEM'
},
listItem: {
- msgId: 'ARIA_ROLE_LISTITEM',
- earcon: 'list_item'
+ msgId: 'aria_role_listitem',
+ earconId: 'LIST_ITEM'
+ },
+ log: {
+ msgId: 'aria_role_log',
+ },
+ main: {
+ msgId: 'aria_role_main',
+ inherits: 'abstractContainer'
+ },
+ marquee: {
+ msgId: 'aria_role_marquee',
+ },
+ math: {
+ msgId: 'aria_role_math',
+ inherits: 'abstractContainer'
},
menu: {
msgId: 'aria_role_menu'
},
+ menuBar: {
+ msgId: 'aria_role_menubar',
+ },
menuItem: {
msgId: 'aria_role_menuitem'
},
+ menuItemCheckBox: {
+ msgId: 'aria_role_menuitemcheckbox'
+ },
+ menuItemRadio: {
+ msgId: 'aria_role_menuitemradio'
+ },
menuListOption: {
msgId: 'aria_role_menuitem'
},
menuListPopup: {
msgId: 'aria_role_menu'
},
+ navigation: {
+ msgId: 'aria_role_navigation',
+ inherits: 'abstractContainer'
+ },
+ note: {
+ msgId: 'aria_role_note',
+ inherits: 'abstractContainer'
+ },
+ region: {
+ msgId: 'aria_role_region',
+ inherits: 'abstractContainer'
+ },
popUpButton: {
msgId: 'tag_button',
earcon: 'LISTBOX'
@@ -137,20 +236,54 @@ Output.ROLE_INFO_ = {
radioButton: {
msgId: 'input_type_radio'
},
+ radioGroup: {
+ msgId: 'aria_role_radiogroup',
+ },
+ rowHeader: {
+ msgId: 'aria_role_rowheader',
+ inherits: 'abstractContainer'
+ },
+ scrollBar: {
+ msgId: 'aria_role_scrollbar',
+ },
+ search: {
+ msgId: 'aria_role_search',
+ inherits: 'abstractContainer'
+ },
+ separator: {
+ msgId: 'aria_role_separator',
+ inherits: 'abstractContainer'
+ },
spinButton: {
- msgId: 'aria_role_combobox',
- earcon: 'LISTBOX'
+ msgId: 'aria_role_spinbutton',
+ earconId: 'LISTBOX'
+ },
+ status: {
+ msgId: 'aria_role_status'
+ },
+ tab: {
+ msgId: 'aria_role_tab'
+ },
+ tabList: {
+ msgId: 'aria_role_tablist'
+ },
+ tabPanel: {
+ msgId: 'aria_role_tabpanel'
},
textBox: {
msgId: 'input_type_text',
- earcon: 'EDITABLE_TEXT'
+ earconId: 'EDITABLE_TEXT'
},
textField: {
msgId: 'input_type_text',
- earcon: 'EDITABLE_TEXT'
+ earconId: 'EDITABLE_TEXT'
},
time: {
- msgId: 'tag_time'
+ msgId: 'tag_time',
+ inherits: 'abstractContainer'
+ },
+ timer: {
+ msgId: 'aria_role_timer'
},
toolbar: {
msgId: 'aria_role_toolbar'
@@ -217,19 +350,25 @@ Output.RULES = {
speak: '$name $value $description $help $role',
braille: ''
},
+ abstractContainer: {
+ enter: '$name $role',
+ leave: '@exited_container($role)'
+ },
alert: {
speak: '!doNotInterrupt $role $descendants'
},
+ alertDialog: {
+ enter: '$name $role $descendants'
+ },
checkBox: {
speak: '$name $role $checked'
},
- date: {
- enter: '$name $role',
- leave: '@exited_container($role)'
- },
dialog: {
enter: '$name $role'
},
+ grid: {
+ enter: '$name $role'
+ },
heading: {
enter: '@tag_h+$hierarchicalLevel',
speak: '@tag_h+$hierarchicalLevel $name='
@@ -277,6 +416,9 @@ Output.RULES = {
speak: '$if($checked, @describe_radio_selected($name), ' +
'@describe_radio_unselected($name))'
},
+ radioGroup: {
+ enter: '$name $role'
+ },
slider: {
speak: '@describe_slider($value, $name) $help'
},
@@ -292,10 +434,6 @@ Output.RULES = {
'$earcon(EDITABLE_TEXT)',
braille: ''
},
- time: {
- enter: '$name $role',
- leave: '@exited_container($role)'
- },
toolbar: {
enter: '$name $role'
},
@@ -684,7 +822,7 @@ Output.prototype = {
msg = cvox.ChromeVox.msgs.getMsg(info.msgId + '_brl');
else
msg = cvox.ChromeVox.msgs.getMsg(info.msgId);
- earconId = info.earcon;
+ earconId = info.earconId;
} else {
console.error('Missing role info for ' + node.role);
}
@@ -834,10 +972,22 @@ Output.prototype = {
// Navigate is the default event.
var eventBlock = Output.RULES[type] || Output.RULES['navigate'];
+ var getMergedRoleBlock = function(role) {
+ var parentRole = (Output.ROLE_INFO_[role] || {}).inherits;
+ var roleBlock = eventBlock[role] || eventBlock['default'];
+ var parentRoleBlock = parentRole ? eventBlock[parentRole] : {};
+ var mergedRoleBlock = {};
+ for (var key in parentRoleBlock)
+ mergedRoleBlock[key] = parentRoleBlock[key];
+ for (var key in roleBlock)
+ mergedRoleBlock[key] = roleBlock[key];
+ return mergedRoleBlock;
+ };
+
for (var i = 0, formatPrevNode;
(formatPrevNode = prevUniqueAncestors[i]);
i++) {
- var roleBlock = eventBlock[formatPrevNode.role] || eventBlock['default'];
+ var roleBlock = getMergedRoleBlock(formatPrevNode.role);
if (roleBlock.leave)
this.format_(formatPrevNode, roleBlock.leave, buff, opt_exclude);
}
@@ -847,7 +997,7 @@ Output.prototype = {
for (var j = uniqueAncestors.length - 2, formatNode;
(formatNode = uniqueAncestors[j]);
j--) {
- var roleBlock = eventBlock[formatNode.role] || eventBlock['default'];
+ var roleBlock = getMergedRoleBlock(formatNode.role);
if (roleBlock.enter) {
if (enterRole[formatNode.role])
continue;
@@ -856,8 +1006,8 @@ Output.prototype = {
this.format_(formatNode, roleBlock.enter, tempBuff, opt_exclude);
enterOutputs.unshift(tempBuff);
}
- if (formatNode.role == 'window')
- break;
+ if (formatNode.role == 'window')
+ break;
}
enterOutputs.forEach(function(b) {
buff.push.apply(buff, b);
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
index d916b92..0037d79e 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
@@ -198,11 +198,11 @@ TEST_F('OutputE2ETest', 'Input', function() {
'||Edit text, email entry',
'||Password edit text',
'||Edit text, number entry',
- {string_: '||Combo box', spans_: [{value: 'name', start: 0, end: 0},
+ {string_: '||Spin button', spans_: [{value: 'name', start: 0, end: 0},
{value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
{value: 'value', start: 1, end: 1},
- {value: 'role', start: 2, end: 11},
- {value: {}, start: 2, end: 11}]},
+ {value: 'role', start: 2, end: 13},
+ {value: {}, start: 2, end: 13}]},
{string_: '||Time', spans_: [{value: 'name', start: 0, end: 0},
{value: 'value', start: 1, end: 1},
{value: 'role', start: 2, end: 6}]},
@@ -345,3 +345,13 @@ TEST_F('OutputE2ETest', 'ListBox', function() {
]}, o.toSpannableForTest());
});
});
+
+SYNC_TEST_F('OutputE2ETest', 'MessageIdValidity', function() {
+ for (var key in Output.ROLE_INFO_) {
+ var value = Output.ROLE_INFO_[key];
+ cvox.ChromeVox.msgs.getMsg(value.msgId);
+ assertFalse(/[A-Z]+/.test(value.msgId));
+ if (value.earconId)
+ assertNotNullNorUndefined(cvox.AbstractEarcons[value.earconId]);
+ }
+});