| Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
|
| diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
|
| index a47944998cf3d49ef86202d8e90b1b4cfec6d3a2..d705fc34b40a84642634a670db5da0570c9192f2 100644
|
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
|
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
|
| @@ -87,6 +87,12 @@ Output = function() {
|
| * @private
|
| */
|
| this.queueMode_ = cvox.QueueMode.QUEUE;
|
| +
|
| + /**
|
| + * @type {boolean}
|
| + * @private
|
| + */
|
| + this.outputContextFirst_ = localStorage['outputContextFirst'] == 'true';
|
| };
|
|
|
| /**
|
| @@ -135,15 +141,12 @@ Output.ROLE_INFO_ = {
|
| msgId: 'role_button',
|
| earconId: 'BUTTON'
|
| },
|
| - cell: {
|
| - msgId: 'role_gridcell'
|
| - },
|
| checkBox: {
|
| msgId: 'role_checkbox'
|
| },
|
| columnHeader: {
|
| msgId: 'role_columnheader',
|
| - inherits: 'abstractContainer'
|
| + inherits: 'cell'
|
| },
|
| comboBox: {
|
| msgId: 'role_combobox'
|
| @@ -268,9 +271,13 @@ Output.ROLE_INFO_ = {
|
| radioGroup: {
|
| msgId: 'role_radiogroup',
|
| },
|
| + row: {
|
| + msgId: 'role_row',
|
| + inherits: 'abstractContainer'
|
| + },
|
| rowHeader: {
|
| msgId: 'role_rowheader',
|
| - inherits: 'abstractContainer'
|
| + inherits: 'cell'
|
| },
|
| scrollBar: {
|
| msgId: 'role_scrollbar',
|
| @@ -422,7 +429,10 @@ Output.RULES = {
|
| speak: '$name $role $descendants'
|
| },
|
| cell: {
|
| - enter: '@column_granularity $tableCellColumnIndex'
|
| + enter: '@cell_summary($tableCellRowIndex, $tableCellColumnIndex) ' +
|
| + '$node(tableColumnHeader)',
|
| + speak: '@cell_summary($tableCellRowIndex, $tableCellColumnIndex) ' +
|
| + '$node(tableColumnHeader)'
|
| },
|
| checkBox: {
|
| speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
|
| @@ -514,7 +524,10 @@ Output.RULES = {
|
| speak: '$descendants'
|
| },
|
| row: {
|
| - enter: '@row_granularity $tableRowIndex'
|
| + enter: '$node(tableRowHeader)'
|
| + },
|
| + rowHeader: {
|
| + speak: '$descendants'
|
| },
|
| slider: {
|
| speak: '$earcon(SLIDER) @describe_slider($value, $name) $description'
|
| @@ -525,6 +538,13 @@ Output.RULES = {
|
| tab: {
|
| speak: '@describe_tab($name)'
|
| },
|
| + table: {
|
| + enter: '@table_summary($name, $tableRowCount, $tableColumnCount) ' +
|
| + '$node(tableHeader)'
|
| + },
|
| + tableHeaderContainer: {
|
| + speak: '$descendants'
|
| + },
|
| textField: {
|
| speak: '$name $value $if($multiline, @tag_textarea, $if(' +
|
| '$inputType, $inputType, $role)) $description',
|
| @@ -806,6 +826,16 @@ Output.prototype = {
|
| return this;
|
| },
|
|
|
| +
|
| + /**
|
| + * Outputs formatting nodes after this will contain context first.
|
| + * @return {!Output}
|
| + */
|
| + withContextFirst: function() {
|
| + this.outputContextFirst_ = true;
|
| + return this;
|
| + },
|
| +
|
| /**
|
| * Apply a format string directly to the output buffer. This lets you
|
| * output a message directly to the buffer using the format syntax.
|
| @@ -1133,14 +1163,19 @@ Output.prototype = {
|
| if (this.formatOptions_.braille)
|
| msgId = msgId + '_brl';
|
| this.append_(buff, Msgs.getMsg(msgId), options);
|
| - } else if (token == 'tableRowIndex' ||
|
| + } else if (token == 'tableCellRowIndex' ||
|
| token == 'tableCellColumnIndex') {
|
| var value = node[token];
|
| - if (!value)
|
| + if (value == undefined)
|
| return;
|
| value = String(value + 1);
|
| options.annotation.push(token);
|
| this.append_(buff, value, options);
|
| + } else if (token == 'node') {
|
| + if (!tree.firstChild || !node[tree.firstChild.value])
|
| + return;
|
| + var related = node[tree.firstChild.value];
|
| + this.node_(related, related, Output.EventType.NAVIGATE, buff);
|
| } else if (node[token] !== undefined) {
|
| options.annotation.push(token);
|
| var value = node[token];
|
| @@ -1218,6 +1253,9 @@ Output.prototype = {
|
| }
|
| var msgBuff = [];
|
| this.format_(node, curArg, msgBuff);
|
| + // Fill in empty string if nothing was formatted.
|
| + if (!msgBuff.length)
|
| + msgBuff = [''];
|
| msgArgs = msgArgs.concat(msgBuff);
|
| curArg = curArg.nextSibling;
|
| }
|
| @@ -1300,11 +1338,11 @@ Output.prototype = {
|
|
|
| var formatNodeAndAncestors = function(node, prevNode) {
|
| var buff = [];
|
| - var outputContextFirst = localStorage['outputContextFirst'] == 'true';
|
| - if (outputContextFirst)
|
| +
|
| + if (this.outputContextFirst_)
|
| this.ancestry_(node, prevNode, type, buff);
|
| this.node_(node, prevNode, type, buff);
|
| - if (!outputContextFirst)
|
| + if (!this.outputContextFirst_)
|
| this.ancestry_(node, prevNode, type, buff);
|
| if (node.location)
|
| this.locations_.push(node.location);
|
| @@ -1448,15 +1486,15 @@ Output.prototype = {
|
| startIndex));
|
| }
|
| }
|
| - var outputContextFirst = localStorage['outputContextFirst'] == 'true';
|
| - if (outputContextFirst)
|
| +
|
| + if (this.outputContextFirst_)
|
| this.ancestry_(node, prevNode, type, buff);
|
| var earcon = this.findEarcon_(node, prevNode);
|
| if (earcon)
|
| options.annotation.push(earcon);
|
| this.append_(buff, range.start.getText().substring(startIndex, endIndex),
|
| options);
|
| - if (!outputContextFirst)
|
| + if (!this.outputContextFirst_)
|
| this.ancestry_(node, prevNode, type, buff);
|
|
|
| var loc =
|
|
|