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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 msgId: 'role_math', | 208 msgId: 'role_math', |
209 inherits: 'abstractContainer' | 209 inherits: 'abstractContainer' |
210 }, | 210 }, |
211 menu: { | 211 menu: { |
212 msgId: 'role_menu' | 212 msgId: 'role_menu' |
213 }, | 213 }, |
214 menuBar: { | 214 menuBar: { |
215 msgId: 'role_menubar', | 215 msgId: 'role_menubar', |
216 }, | 216 }, |
217 menuItem: { | 217 menuItem: { |
218 msgId: 'role_menuitem' | 218 msgId: 'role_menuitem', |
| 219 earconId: 'BUTTON' |
219 }, | 220 }, |
220 menuItemCheckBox: { | 221 menuItemCheckBox: { |
221 msgId: 'role_menuitemcheckbox' | 222 msgId: 'role_menuitemcheckbox', |
| 223 earconId: 'BUTTON' |
222 }, | 224 }, |
223 menuItemRadio: { | 225 menuItemRadio: { |
224 msgId: 'role_menuitemradio' | 226 msgId: 'role_menuitemradio', |
| 227 earconId: 'BUTTON' |
225 }, | 228 }, |
226 menuListOption: { | 229 menuListOption: { |
227 msgId: 'role_menuitem' | 230 msgId: 'role_menuitem' |
228 }, | 231 }, |
229 menuListPopup: { | 232 menuListPopup: { |
230 msgId: 'role_menu' | 233 msgId: 'role_menu' |
231 }, | 234 }, |
232 navigation: { | 235 navigation: { |
233 msgId: 'role_navigation', | 236 msgId: 'role_navigation', |
234 inherits: 'abstractContainer' | 237 inherits: 'abstractContainer' |
235 }, | 238 }, |
236 note: { | 239 note: { |
237 msgId: 'role_note', | 240 msgId: 'role_note', |
238 inherits: 'abstractContainer' | 241 inherits: 'abstractContainer' |
239 }, | 242 }, |
240 popUpButton: { | 243 popUpButton: { |
241 msgId: 'role_button', | 244 msgId: 'role_button', |
242 earcon: 'LISTBOX' | |
243 }, | 245 }, |
244 radioButton: { | 246 radioButton: { |
245 msgId: 'role_radio' | 247 msgId: 'role_radio' |
246 }, | 248 }, |
247 radioGroup: { | 249 radioGroup: { |
248 msgId: 'role_radiogroup', | 250 msgId: 'role_radiogroup', |
249 }, | 251 }, |
250 region: { | 252 region: { |
251 msgId: 'role_region', | 253 msgId: 'role_region', |
252 inherits: 'abstractContainer' | 254 inherits: 'abstractContainer' |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 * off: {msgId: string, earconId: string}, | 316 * off: {msgId: string, earconId: string}, |
315 * omitted: {msgId: string, earconId: string}}>} | 317 * omitted: {msgId: string, earconId: string}}>} |
316 * on: info used to describe a state that is set to true. | 318 * on: info used to describe a state that is set to true. |
317 * off: info used to describe a state that is set to false. | 319 * off: info used to describe a state that is set to false. |
318 * omitted: info used to describe a state that is undefined. | 320 * omitted: info used to describe a state that is undefined. |
319 * @private | 321 * @private |
320 */ | 322 */ |
321 Output.STATE_INFO_ = { | 323 Output.STATE_INFO_ = { |
322 checked: { | 324 checked: { |
323 on: { | 325 on: { |
324 earconId: 'CHECK_ON', | |
325 msgId: 'checkbox_checked_state' | 326 msgId: 'checkbox_checked_state' |
326 }, | 327 }, |
327 off: { | 328 off: { |
328 earconId: 'CHECK_OFF', | |
329 msgId: 'checkbox_unchecked_state' | 329 msgId: 'checkbox_unchecked_state' |
330 }, | 330 }, |
331 omitted: { | 331 omitted: { |
332 earconId: 'CHECK_OFF', | |
333 msgId: 'checkbox_unchecked_state' | 332 msgId: 'checkbox_unchecked_state' |
334 } | 333 } |
335 }, | 334 }, |
336 collapsed: { | 335 collapsed: { |
337 on: { | 336 on: { |
338 msgId: 'aria_expanded_false' | 337 msgId: 'aria_expanded_false' |
339 }, | 338 }, |
340 off: { | 339 off: { |
341 msgId: 'aria_expanded_true' | 340 msgId: 'aria_expanded_true' |
342 } | 341 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 alert: { | 387 alert: { |
389 speak: '!doNotInterrupt $role $descendants' | 388 speak: '!doNotInterrupt $role $descendants' |
390 }, | 389 }, |
391 alertDialog: { | 390 alertDialog: { |
392 enter: '$name $role $descendants' | 391 enter: '$name $role $descendants' |
393 }, | 392 }, |
394 cell: { | 393 cell: { |
395 enter: '@column_granularity $tableCellColumnIndex' | 394 enter: '@column_granularity $tableCellColumnIndex' |
396 }, | 395 }, |
397 checkBox: { | 396 checkBox: { |
398 speak: '$name $role $checked' | 397 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + |
| 398 '$name $role $checked' |
399 }, | 399 }, |
400 dialog: { | 400 dialog: { |
401 enter: '$name $role' | 401 enter: '$name $role' |
402 }, | 402 }, |
403 div: { | 403 div: { |
404 enter: '$name', | 404 enter: '$name', |
405 speak: '$name' | 405 speak: '$name' |
406 }, | 406 }, |
407 grid: { | 407 grid: { |
408 enter: '$name $role' | 408 enter: '$name $role' |
(...skipping 30 matching lines...) Expand all Loading... |
439 '@describe_index($indexInParent, $parentChildCount)' | 439 '@describe_index($indexInParent, $parentChildCount)' |
440 }, | 440 }, |
441 menuListOption: { | 441 menuListOption: { |
442 speak: '$name $value @role_menuitem ' + | 442 speak: '$name $value @role_menuitem ' + |
443 '@describe_index($indexInParent, $parentChildCount)' | 443 '@describe_index($indexInParent, $parentChildCount)' |
444 }, | 444 }, |
445 paragraph: { | 445 paragraph: { |
446 speak: '$descendants' | 446 speak: '$descendants' |
447 }, | 447 }, |
448 popUpButton: { | 448 popUpButton: { |
449 speak: '$value $name $role @aria_has_popup ' + | 449 speak: '$earcon(POP_UP_BUTTON) $value $name $role @aria_has_popup ' + |
450 '$if($collapsed, @aria_expanded_false, @aria_expanded_true)' | 450 '$if($collapsed, @aria_expanded_false, @aria_expanded_true)' |
451 }, | 451 }, |
452 radioButton: { | 452 radioButton: { |
453 speak: '$if($checked, @describe_radio_selected($name), ' + | 453 speak: '$if($checked, @describe_radio_selected($name), ' + |
454 '@describe_radio_unselected($name))' | 454 '@describe_radio_unselected($name))' |
455 }, | 455 }, |
456 radioGroup: { | 456 radioGroup: { |
457 enter: '$name $role' | 457 enter: '$name $role' |
458 }, | 458 }, |
459 rootWebArea: { | 459 rootWebArea: { |
460 enter: '$name' | 460 enter: '$name' |
461 }, | 461 }, |
462 row: { | 462 row: { |
463 enter: '@row_granularity $tableRowIndex' | 463 enter: '@row_granularity $tableRowIndex' |
464 }, | 464 }, |
465 slider: { | 465 slider: { |
466 speak: '@describe_slider($value, $name) $help' | 466 speak: '$earcon(SLIDER) @describe_slider($value, $name) $help' |
467 }, | 467 }, |
468 staticText: { | 468 staticText: { |
469 speak: '$value=' | 469 speak: '$value=' |
470 }, | 470 }, |
471 tab: { | 471 tab: { |
472 speak: '@describe_tab($name)' | 472 speak: '@describe_tab($name)' |
473 }, | 473 }, |
474 textField: { | 474 textField: { |
475 speak: '$name $value $if(' + | 475 speak: '$name $value $if(' + |
476 '$inputType, $inputType, $role)', | 476 '$inputType, $inputType, $role)', |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 }, | 683 }, |
684 | 684 |
685 /** | 685 /** |
686 * Executes all specified output. | 686 * Executes all specified output. |
687 */ | 687 */ |
688 go: function() { | 688 go: function() { |
689 // Speech. | 689 // Speech. |
690 var queueMode = this.speechProperties_['category'] ? | 690 var queueMode = this.speechProperties_['category'] ? |
691 cvox.QueueMode.CATEGORY_FLUSH : cvox.QueueMode.FLUSH; | 691 cvox.QueueMode.CATEGORY_FLUSH : cvox.QueueMode.FLUSH; |
692 this.speechBuffer_.forEach(function(buff, i, a) { | 692 this.speechBuffer_.forEach(function(buff, i, a) { |
693 if (buff.toString()) { | 693 (function() { |
694 (function() { | 694 var scopedBuff = buff; |
695 var scopedBuff = buff; | 695 this.speechProperties_['startCallback'] = function() { |
696 this.speechProperties_['startCallback'] = function() { | 696 var actions = scopedBuff.getSpansInstanceOf(Output.Action); |
697 var actions = scopedBuff.getSpansInstanceOf(Output.Action); | 697 if (actions) { |
698 if (actions) { | 698 actions.forEach(function(a) { |
699 actions.forEach(function(a) { | 699 a.run(); |
700 a.run(); | 700 }); |
701 }); | 701 } |
702 } | 702 }; |
703 }; | 703 }.bind(this)()); |
704 }.bind(this)()); | |
705 | 704 |
706 if (this.speechEndCallback_ && i == a.length - 1) | 705 if (this.speechEndCallback_ && i == a.length - 1) |
707 this.speechProperties_['endCallback'] = this.speechEndCallback_; | 706 this.speechProperties_['endCallback'] = this.speechEndCallback_; |
708 else | 707 else |
709 this.speechProperties_['endCallback'] = null; | 708 this.speechProperties_['endCallback'] = null; |
710 cvox.ChromeVox.tts.speak( | 709 cvox.ChromeVox.tts.speak( |
711 buff.toString(), queueMode, this.speechProperties_); | 710 buff.toString(), queueMode, this.speechProperties_); |
712 queueMode = cvox.QueueMode.QUEUE; | 711 queueMode = cvox.QueueMode.QUEUE; |
713 } | |
714 }.bind(this)); | 712 }.bind(this)); |
715 | 713 |
716 // Braille. | 714 // Braille. |
717 if (this.brailleBuffer_.length) { | 715 if (this.brailleBuffer_.length) { |
718 var buff = this.createBrailleOutput_(); | 716 var buff = this.createBrailleOutput_(); |
719 var selSpan = | 717 var selSpan = |
720 buff.getSpanInstanceOf(Output.SelectionSpan); | 718 buff.getSpanInstanceOf(Output.SelectionSpan); |
721 var startIndex = -1, endIndex = -1; | 719 var startIndex = -1, endIndex = -1; |
722 if (selSpan) { | 720 if (selSpan) { |
723 // Casts ok, since the span is known to be in the spannable. | 721 // Casts ok, since the span is known to be in the spannable. |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 var cond = tree.firstChild; | 958 var cond = tree.firstChild; |
961 var attrib = cond.value.slice(1); | 959 var attrib = cond.value.slice(1); |
962 if (node[attrib] || node.state[attrib]) | 960 if (node[attrib] || node.state[attrib]) |
963 this.format_(node, cond.nextSibling, buff); | 961 this.format_(node, cond.nextSibling, buff); |
964 else | 962 else |
965 this.format_(node, cond.nextSibling.nextSibling, buff); | 963 this.format_(node, cond.nextSibling.nextSibling, buff); |
966 } else if (token == 'earcon') { | 964 } else if (token == 'earcon') { |
967 // Ignore unless we're generating speech output. | 965 // Ignore unless we're generating speech output. |
968 if (!this.formatOptions_.speech) | 966 if (!this.formatOptions_.speech) |
969 return; | 967 return; |
970 // Assumes there's existing output in our buffer. | |
971 var lastBuff = buff[buff.length - 1]; | |
972 if (!lastBuff) | |
973 return; | |
974 | 968 |
975 lastBuff.setSpan( | 969 options.annotation.push( |
976 new Output.EarconAction(tree.firstChild.value), 0, 0); | 970 new Output.EarconAction(tree.firstChild.value)); |
| 971 this.append_(buff, '', options); |
977 } else if (token == 'countChildren') { | 972 } else if (token == 'countChildren') { |
978 var role = tree.firstChild.value; | 973 var role = tree.firstChild.value; |
979 var count = node.children.filter(function(e) { | 974 var count = node.children.filter(function(e) { |
980 return e.role == role; | 975 return e.role == role; |
981 }).length; | 976 }).length; |
982 this.append_(buff, String(count)); | 977 this.append_(buff, String(count)); |
983 } | 978 } |
984 } | 979 } |
985 } else if (prefix == '@') { | 980 } else if (prefix == '@') { |
986 var isPluralized = (token[0] == '@'); | 981 var isPluralized = (token[0] == '@'); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 elem.end); | 1326 elem.end); |
1332 }); | 1327 }); |
1333 spansToRemove.forEach(result.removeSpan.bind(result)); | 1328 spansToRemove.forEach(result.removeSpan.bind(result)); |
1334 separator = Output.SPACE; | 1329 separator = Output.SPACE; |
1335 }); | 1330 }); |
1336 return result; | 1331 return result; |
1337 } | 1332 } |
1338 }; | 1333 }; |
1339 | 1334 |
1340 }); // goog.scope | 1335 }); // goog.scope |
OLD | NEW |