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 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 /** | 717 /** |
718 * Calling this will make the next speech utterance use |mode| even if it would | 718 * Calling this will make the next speech utterance use |mode| even if it would |
719 * normally queue or do a category flush. This differs from the |withQueueMode| | 719 * normally queue or do a category flush. This differs from the |withQueueMode| |
720 * instance method as it can apply to future output. | 720 * instance method as it can apply to future output. |
721 * @param {cvox.QueueMode} mode | 721 * @param {cvox.QueueMode} mode |
722 */ | 722 */ |
723 Output.forceModeForNextSpeechUtterance = function(mode) { | 723 Output.forceModeForNextSpeechUtterance = function(mode) { |
724 Output.forceModeForNextSpeechUtterance_ = mode; | 724 Output.forceModeForNextSpeechUtterance_ = mode; |
725 }; | 725 }; |
726 | 726 |
| 727 /** |
| 728 * For a given automation property, return true if the value |
| 729 * represents something 'truthy', e.g.: for checked: |
| 730 * 'true'|'mixed' -> true |
| 731 * 'false'|undefined -> false |
| 732 */ |
| 733 Output.isTruthy = function(node, attrib) { |
| 734 switch(attrib) { |
| 735 case 'checked': |
| 736 return node.checked && node.checked !== 'false'; |
| 737 default: |
| 738 return node[attrib] !== undefined || node.state[attrib]; |
| 739 } |
| 740 }; |
| 741 |
727 Output.prototype = { | 742 Output.prototype = { |
728 /** | 743 /** |
729 * @return {boolean} True if there's any speech that will be output. | 744 * @return {boolean} True if there's any speech that will be output. |
730 */ | 745 */ |
731 get hasSpeech() { | 746 get hasSpeech() { |
732 for (var i = 0; i < this.speechBuffer_.length; i++) { | 747 for (var i = 0; i < this.speechBuffer_.length; i++) { |
733 if (this.speechBuffer_[i].trim().length) | 748 if (this.speechBuffer_[i].trim().length) |
734 return true; | 749 return true; |
735 } | 750 } |
736 return false; | 751 return false; |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 } else if (token == 'parentChildCount') { | 1164 } else if (token == 'parentChildCount') { |
1150 if (node.parent) { | 1165 if (node.parent) { |
1151 options.annotation.push(token); | 1166 options.annotation.push(token); |
1152 var count = node.parent.children.filter(function(child) { | 1167 var count = node.parent.children.filter(function(child) { |
1153 return node.role == child.role; | 1168 return node.role == child.role; |
1154 }).length; | 1169 }).length; |
1155 this.append_(buff, String(count)); | 1170 this.append_(buff, String(count)); |
1156 } | 1171 } |
1157 } else if (token == 'checked') { | 1172 } else if (token == 'checked') { |
1158 var msg; | 1173 var msg; |
1159 var ariaChecked = node.htmlAttributes['aria-checked']; | 1174 switch (node.checked) { |
1160 switch (ariaChecked) { | |
1161 case 'mixed': | 1175 case 'mixed': |
1162 msg = 'aria_checked_mixed'; | 1176 msg = 'checked_mixed'; |
1163 break; | 1177 break; |
1164 case 'true': | 1178 case 'true': |
1165 msg = 'aria_checked_true'; | 1179 msg = 'checked_true'; |
1166 break; | |
1167 case 'false': | |
1168 msg = 'aria_checked_false'; | |
1169 break; | 1180 break; |
1170 default: | 1181 default: |
1171 msg = node.state[StateType.CHECKED] ? | 1182 msg = 'checked_false'; |
1172 'aria_checked_true' : 'aria_checked_false'; | 1183 break; |
1173 } | 1184 } |
1174 this.format_(node, '@' + msg, buff); | 1185 this.format_(node, '@' + msg, buff); |
1175 } else if (token == 'state') { | 1186 } else if (token == 'state') { |
1176 if (node.state) { | 1187 if (node.state) { |
1177 Object.getOwnPropertyNames(node.state).forEach(function(s) { | 1188 Object.getOwnPropertyNames(node.state).forEach(function(s) { |
1178 var stateInfo = Output.STATE_INFO_[s]; | 1189 var stateInfo = Output.STATE_INFO_[s]; |
1179 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on) | 1190 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on) |
1180 this.format_(node, '@' + stateInfo.on.msgId, buff); | 1191 this.format_(node, '@' + stateInfo.on.msgId, buff); |
1181 }.bind(this)); | 1192 }.bind(this)); |
1182 } | 1193 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 var msgId = | 1305 var msgId = |
1295 this.formatOptions_.braille ? resolvedInfo.msgId + '_brl' : | 1306 this.formatOptions_.braille ? resolvedInfo.msgId + '_brl' : |
1296 resolvedInfo.msgId; | 1307 resolvedInfo.msgId; |
1297 var msg = Msgs.getMsg(msgId); | 1308 var msg = Msgs.getMsg(msgId); |
1298 this.append_(buff, msg, options); | 1309 this.append_(buff, msg, options); |
1299 } else if (tree.firstChild) { | 1310 } else if (tree.firstChild) { |
1300 // Custom functions. | 1311 // Custom functions. |
1301 if (token == 'if') { | 1312 if (token == 'if') { |
1302 var cond = tree.firstChild; | 1313 var cond = tree.firstChild; |
1303 var attrib = cond.value.slice(1); | 1314 var attrib = cond.value.slice(1); |
1304 if (node[attrib] !== undefined || node.state[attrib]) | 1315 if (Output.isTruthy(node, attrib)) |
1305 this.format_(node, cond.nextSibling, buff); | 1316 this.format_(node, cond.nextSibling, buff); |
1306 else | 1317 else |
1307 this.format_(node, cond.nextSibling.nextSibling, buff); | 1318 this.format_(node, cond.nextSibling.nextSibling, buff); |
1308 } else if (token == 'earcon') { | 1319 } else if (token == 'earcon') { |
1309 // Ignore unless we're generating speech output. | 1320 // Ignore unless we're generating speech output. |
1310 if (!this.formatOptions_.speech) | 1321 if (!this.formatOptions_.speech) |
1311 return; | 1322 return; |
1312 | 1323 |
1313 options.annotation.push( | 1324 options.annotation.push( |
1314 new Output.EarconAction(tree.firstChild.value, | 1325 new Output.EarconAction(tree.firstChild.value, |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 /** | 1888 /** |
1878 * Gets the output buffer for braille. | 1889 * Gets the output buffer for braille. |
1879 * @return {!Spannable} | 1890 * @return {!Spannable} |
1880 */ | 1891 */ |
1881 get brailleOutputForTest() { | 1892 get brailleOutputForTest() { |
1882 return this.mergeBraille_(this.brailleBuffer_); | 1893 return this.mergeBraille_(this.brailleBuffer_); |
1883 } | 1894 } |
1884 }; | 1895 }; |
1885 | 1896 |
1886 }); // goog.scope | 1897 }); // goog.scope |
OLD | NEW |