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 Provides output services for ChromeVox. | 6 * @fileoverview Provides output services for ChromeVox. |
7 */ | 7 */ |
8 | 8 |
9 goog.provide('Output'); | 9 goog.provide('Output'); |
10 goog.provide('Output.EventType'); | 10 goog.provide('Output.EventType'); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 this.speechBuffer_ = []; | 62 this.speechBuffer_ = []; |
63 /** @type {!Array<!Spannable>} @private */ | 63 /** @type {!Array<!Spannable>} @private */ |
64 this.brailleBuffer_ = []; | 64 this.brailleBuffer_ = []; |
65 /** @type {!Array<!Object>} @private */ | 65 /** @type {!Array<!Object>} @private */ |
66 this.locations_ = []; | 66 this.locations_ = []; |
67 /** @type {function(?)} @private */ | 67 /** @type {function(?)} @private */ |
68 this.speechEndCallback_; | 68 this.speechEndCallback_; |
69 | 69 |
70 /** | 70 /** |
71 * Current global options. | 71 * Current global options. |
72 * @type {{speech: boolean, braille: boolean, auralStyle: boolean}} | 72 * @type {{speech: boolean, |
| 73 * braille: boolean, |
| 74 * auralStyle: boolean, |
| 75 * earcons: boolean}} |
73 * @private | 76 * @private |
74 */ | 77 */ |
75 this.formatOptions_ = {speech: true, braille: false, auralStyle: false}; | 78 this.formatOptions_ = |
| 79 {speech: true, braille: false, auralStyle: false, earcons: true}; |
76 | 80 |
77 /** | 81 /** |
78 * The speech category for the generated speech utterance. | 82 * The speech category for the generated speech utterance. |
79 * @type {cvox.TtsCategory} | 83 * @type {cvox.TtsCategory} |
80 * @private | 84 * @private |
81 */ | 85 */ |
82 this.speechCategory_ = cvox.TtsCategory.NAV; | 86 this.speechCategory_ = cvox.TtsCategory.NAV; |
83 | 87 |
84 /** | 88 /** |
85 * The speech queue mode for the generated speech utterance. | 89 * The speech queue mode for the generated speech utterance. |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 '$name $role $checked $description $state' | 434 '$name $role $checked $description $state' |
431 }, | 435 }, |
432 date: { | 436 date: { |
433 enter: '$nameFromNode $role $description' | 437 enter: '$nameFromNode $role $description' |
434 }, | 438 }, |
435 dialog: { | 439 dialog: { |
436 enter: '$nameFromNode $role $description' | 440 enter: '$nameFromNode $role $description' |
437 }, | 441 }, |
438 div: { | 442 div: { |
439 enter: '$nameFromNode', | 443 enter: '$nameFromNode', |
440 speak: '$name $description $descendants' | 444 speak: '$name $description $descendantsNoEarcons' |
441 }, | 445 }, |
442 grid: { | 446 grid: { |
443 enter: '$nameFromNode $role $description' | 447 enter: '$nameFromNode $role $description' |
444 }, | 448 }, |
445 group: { | 449 group: { |
446 enter: '$nameFromNode $state $description', | 450 enter: '$nameFromNode $state $description', |
447 speak: '$nameOrDescendants $value $state $description', | 451 speak: '$nameOrDescendants $value $state $description', |
448 leave: '' | 452 leave: '' |
449 }, | 453 }, |
450 heading: { | 454 heading: { |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 }, | 711 }, |
708 | 712 |
709 /** | 713 /** |
710 * Specify ranges for speech. | 714 * Specify ranges for speech. |
711 * @param {!cursors.Range} range | 715 * @param {!cursors.Range} range |
712 * @param {cursors.Range} prevRange | 716 * @param {cursors.Range} prevRange |
713 * @param {EventType|Output.EventType} type | 717 * @param {EventType|Output.EventType} type |
714 * @return {!Output} | 718 * @return {!Output} |
715 */ | 719 */ |
716 withSpeech: function(range, prevRange, type) { | 720 withSpeech: function(range, prevRange, type) { |
717 this.formatOptions_ = {speech: true, braille: false, auralStyle: false}; | 721 this.formatOptions_ = |
| 722 {speech: true, braille: false, auralStyle: false, earcons: true}; |
718 this.render_(range, prevRange, type, this.speechBuffer_); | 723 this.render_(range, prevRange, type, this.speechBuffer_); |
719 return this; | 724 return this; |
720 }, | 725 }, |
721 | 726 |
722 /** | 727 /** |
723 * Specify ranges for aurally styled speech. | 728 * Specify ranges for aurally styled speech. |
724 * @param {!cursors.Range} range | 729 * @param {!cursors.Range} range |
725 * @param {cursors.Range} prevRange | 730 * @param {cursors.Range} prevRange |
726 * @param {EventType|Output.EventType} type | 731 * @param {EventType|Output.EventType} type |
727 * @return {!Output} | 732 * @return {!Output} |
728 */ | 733 */ |
729 withRichSpeech: function(range, prevRange, type) { | 734 withRichSpeech: function(range, prevRange, type) { |
730 this.formatOptions_ = {speech: true, braille: false, auralStyle: true}; | 735 this.formatOptions_ = |
| 736 {speech: true, braille: false, auralStyle: true, earcons: true}; |
731 this.render_(range, prevRange, type, this.speechBuffer_); | 737 this.render_(range, prevRange, type, this.speechBuffer_); |
732 return this; | 738 return this; |
733 }, | 739 }, |
734 | 740 |
735 /** | 741 /** |
736 * Specify ranges for braille. | 742 * Specify ranges for braille. |
737 * @param {!cursors.Range} range | 743 * @param {!cursors.Range} range |
738 * @param {cursors.Range} prevRange | 744 * @param {cursors.Range} prevRange |
739 * @param {EventType|Output.EventType} type | 745 * @param {EventType|Output.EventType} type |
740 * @return {!Output} | 746 * @return {!Output} |
741 */ | 747 */ |
742 withBraille: function(range, prevRange, type) { | 748 withBraille: function(range, prevRange, type) { |
743 this.formatOptions_ = {speech: false, braille: true, auralStyle: false}; | 749 this.formatOptions_ = |
| 750 {speech: false, braille: true, auralStyle: false, earcons: false}; |
744 this.render_(range, prevRange, type, this.brailleBuffer_); | 751 this.render_(range, prevRange, type, this.brailleBuffer_); |
745 return this; | 752 return this; |
746 }, | 753 }, |
747 | 754 |
748 /** | 755 /** |
749 * Specify ranges for location. | 756 * Specify ranges for location. |
750 * @param {!cursors.Range} range | 757 * @param {!cursors.Range} range |
751 * @param {cursors.Range} prevRange | 758 * @param {cursors.Range} prevRange |
752 * @param {EventType|Output.EventType} type | 759 * @param {EventType|Output.EventType} type |
753 * @return {!Output} | 760 * @return {!Output} |
754 */ | 761 */ |
755 withLocation: function(range, prevRange, type) { | 762 withLocation: function(range, prevRange, type) { |
756 this.formatOptions_ = {speech: false, braille: false, auralStyle: false}; | 763 this.formatOptions_ = |
| 764 {speech: false, braille: false, auralStyle: false, earcons: false}; |
757 this.render_(range, prevRange, type, [] /*unused output*/); | 765 this.render_(range, prevRange, type, [] /*unused output*/); |
758 return this; | 766 return this; |
759 }, | 767 }, |
760 | 768 |
761 /** | 769 /** |
762 * Specify the same ranges for speech and braille. | 770 * Specify the same ranges for speech and braille. |
763 * @param {!cursors.Range} range | 771 * @param {!cursors.Range} range |
764 * @param {cursors.Range} prevRange | 772 * @param {cursors.Range} prevRange |
765 * @param {EventType|Output.EventType} type | 773 * @param {EventType|Output.EventType} type |
766 * @return {!Output} | 774 * @return {!Output} |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 * Apply a format string directly to the speech output buffer. This lets you | 851 * Apply a format string directly to the speech output buffer. This lets you |
844 * output a message directly to the buffer using the format syntax. | 852 * output a message directly to the buffer using the format syntax. |
845 * @param {string} formatStr | 853 * @param {string} formatStr |
846 * @param {!AutomationNode=} opt_node An optional node to apply the | 854 * @param {!AutomationNode=} opt_node An optional node to apply the |
847 * formatting to. | 855 * formatting to. |
848 * @return {!Output} |this| for chaining | 856 * @return {!Output} |this| for chaining |
849 */ | 857 */ |
850 formatForSpeech: function(formatStr, opt_node) { | 858 formatForSpeech: function(formatStr, opt_node) { |
851 var node = opt_node || null; | 859 var node = opt_node || null; |
852 | 860 |
853 this.formatOptions_ = {speech: true, braille: false, auralStyle: false}; | 861 this.formatOptions_ = |
| 862 {speech: true, braille: false, auralStyle: false, earcons: true}; |
854 this.format_(node, formatStr, this.speechBuffer_); | 863 this.format_(node, formatStr, this.speechBuffer_); |
855 | 864 |
856 return this; | 865 return this; |
857 }, | 866 }, |
858 | 867 |
859 /** | 868 /** |
860 * Apply a format string directly to the braille output buffer. This lets you | 869 * Apply a format string directly to the braille output buffer. This lets you |
861 * output a message directly to the buffer using the format syntax. | 870 * output a message directly to the buffer using the format syntax. |
862 * @param {string} formatStr | 871 * @param {string} formatStr |
863 * @param {!AutomationNode=} opt_node An optional node to apply the | 872 * @param {!AutomationNode=} opt_node An optional node to apply the |
864 * formatting to. | 873 * formatting to. |
865 * @return {!Output} |this| for chaining | 874 * @return {!Output} |this| for chaining |
866 */ | 875 */ |
867 formatForBraille: function(formatStr, opt_node) { | 876 formatForBraille: function(formatStr, opt_node) { |
868 var node = opt_node || null; | 877 var node = opt_node || null; |
869 | 878 |
870 this.formatOptions_ = {speech: false, braille: true, auralStyle: false}; | 879 this.formatOptions_ = |
| 880 {speech: false, braille: true, auralStyle: false, earcons: false}; |
871 this.format_(node, formatStr, this.brailleBuffer_); | 881 this.format_(node, formatStr, this.brailleBuffer_); |
872 | 882 |
873 return this; | 883 return this; |
874 }, | 884 }, |
875 | 885 |
876 /** | 886 /** |
877 * Triggers callback for a speech event. | 887 * Triggers callback for a speech event. |
878 * @param {function()} callback | 888 * @param {function()} callback |
879 * @return {Output} | 889 * @return {Output} |
880 */ | 890 */ |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 new cursors.Cursor(leftmost, cursors.NODE_INDEX), | 1127 new cursors.Cursor(leftmost, cursors.NODE_INDEX), |
1118 new cursors.Cursor(rightmost, cursors.NODE_INDEX)); | 1128 new cursors.Cursor(rightmost, cursors.NODE_INDEX)); |
1119 var prev = null; | 1129 var prev = null; |
1120 if (node) | 1130 if (node) |
1121 prev = cursors.Range.fromNode(node); | 1131 prev = cursors.Range.fromNode(node); |
1122 this.render_(subrange, prev, Output.EventType.NAVIGATE, buff); | 1132 this.render_(subrange, prev, Output.EventType.NAVIGATE, buff); |
1123 } else if (token == 'joinedDescendants') { | 1133 } else if (token == 'joinedDescendants') { |
1124 var unjoined = []; | 1134 var unjoined = []; |
1125 this.format_(node, '$descendants', unjoined); | 1135 this.format_(node, '$descendants', unjoined); |
1126 this.append_(buff, unjoined.join(' '), options); | 1136 this.append_(buff, unjoined.join(' '), options); |
| 1137 } else if (token == 'descendantsNoEarcons') { |
| 1138 var state = this.formatOptions_.earcons; |
| 1139 this.formatOptions_.earcons = false; |
| 1140 this.format_(node, '$descendants', buff); |
| 1141 this.formatOptions_.earcons = state; |
1127 } else if (token == 'role') { | 1142 } else if (token == 'role') { |
1128 if (localStorage['useVerboseMode'] == 'false') | 1143 if (localStorage['useVerboseMode'] == 'false') |
1129 return; | 1144 return; |
1130 | 1145 |
1131 if (this.formatOptions_.auralStyle) { | 1146 if (this.formatOptions_.auralStyle) { |
1132 speechProps = new Output.SpeechProperties(); | 1147 speechProps = new Output.SpeechProperties(); |
1133 speechProps['relativePitch'] = -0.3; | 1148 speechProps['relativePitch'] = -0.3; |
1134 } | 1149 } |
1135 options.annotation.push(token); | 1150 options.annotation.push(token); |
1136 var msg = node.role; | 1151 var msg = node.role; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 // Custom functions. | 1210 // Custom functions. |
1196 if (token == 'if') { | 1211 if (token == 'if') { |
1197 var cond = tree.firstChild; | 1212 var cond = tree.firstChild; |
1198 var attrib = cond.value.slice(1); | 1213 var attrib = cond.value.slice(1); |
1199 if (node[attrib] || node.state[attrib]) | 1214 if (node[attrib] || node.state[attrib]) |
1200 this.format_(node, cond.nextSibling, buff); | 1215 this.format_(node, cond.nextSibling, buff); |
1201 else | 1216 else |
1202 this.format_(node, cond.nextSibling.nextSibling, buff); | 1217 this.format_(node, cond.nextSibling.nextSibling, buff); |
1203 } else if (token == 'earcon') { | 1218 } else if (token == 'earcon') { |
1204 // Ignore unless we're generating speech output. | 1219 // Ignore unless we're generating speech output. |
1205 if (!this.formatOptions_.speech) | 1220 if (!this.formatOptions_.speech || !this.formatOptions_.earcons) |
1206 return; | 1221 return; |
1207 | 1222 |
1208 options.annotation.push( | 1223 options.annotation.push( |
1209 new Output.EarconAction(tree.firstChild.value)); | 1224 new Output.EarconAction(tree.firstChild.value)); |
1210 this.append_(buff, '', options); | 1225 this.append_(buff, '', options); |
1211 } else if (token == 'countChildren') { | 1226 } else if (token == 'countChildren') { |
1212 var role = tree.firstChild.value; | 1227 var role = tree.firstChild.value; |
1213 var count = node.children.filter(function(e) { | 1228 var count = node.children.filter(function(e) { |
1214 return e.role == role; | 1229 return e.role == role; |
1215 }).length; | 1230 }).length; |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1648 return result; | 1663 return result; |
1649 }, | 1664 }, |
1650 | 1665 |
1651 /** | 1666 /** |
1652 * Find the earcon for a given node (including ancestry). | 1667 * Find the earcon for a given node (including ancestry). |
1653 * @param {!AutomationNode} node | 1668 * @param {!AutomationNode} node |
1654 * @param {!AutomationNode=} opt_prevNode | 1669 * @param {!AutomationNode=} opt_prevNode |
1655 * @return {Output.Action} | 1670 * @return {Output.Action} |
1656 */ | 1671 */ |
1657 findEarcon_: function(node, opt_prevNode) { | 1672 findEarcon_: function(node, opt_prevNode) { |
| 1673 if (!this.formatOptions_.earcons) |
| 1674 return null; |
1658 if (node === opt_prevNode) | 1675 if (node === opt_prevNode) |
1659 return null; | 1676 return null; |
1660 | 1677 |
1661 if (this.formatOptions_.speech) { | 1678 if (this.formatOptions_.speech) { |
1662 var earconFinder = node; | 1679 var earconFinder = node; |
1663 var ancestors; | 1680 var ancestors; |
1664 if (opt_prevNode) | 1681 if (opt_prevNode) |
1665 ancestors = AutomationUtil.getUniqueAncestors(opt_prevNode, node); | 1682 ancestors = AutomationUtil.getUniqueAncestors(opt_prevNode, node); |
1666 else | 1683 else |
1667 ancestors = AutomationUtil.getAncestors(node); | 1684 ancestors = AutomationUtil.getAncestors(node); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 /** | 1725 /** |
1709 * Gets the output buffer for braille. | 1726 * Gets the output buffer for braille. |
1710 * @return {!Spannable} | 1727 * @return {!Spannable} |
1711 */ | 1728 */ |
1712 get brailleOutputForTest() { | 1729 get brailleOutputForTest() { |
1713 return this.createBrailleOutput_(); | 1730 return this.createBrailleOutput_(); |
1714 } | 1731 } |
1715 }; | 1732 }; |
1716 | 1733 |
1717 }); // goog.scope | 1734 }); // goog.scope |
OLD | NEW |