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: 'aria_role_math', | 208 msgId: 'aria_role_math', |
209 inherits: 'abstractContainer' | 209 inherits: 'abstractContainer' |
210 }, | 210 }, |
211 menu: { | 211 menu: { |
212 msgId: 'aria_role_menu' | 212 msgId: 'aria_role_menu' |
213 }, | 213 }, |
214 menuBar: { | 214 menuBar: { |
215 msgId: 'aria_role_menubar', | 215 msgId: 'aria_role_menubar', |
216 }, | 216 }, |
217 menuItem: { | 217 menuItem: { |
218 msgId: 'aria_role_menuitem' | 218 msgId: 'aria_role_menuitem', |
| 219 earconId: 'BUTTON' |
219 }, | 220 }, |
220 menuItemCheckBox: { | 221 menuItemCheckBox: { |
221 msgId: 'aria_role_menuitemcheckbox' | 222 msgId: 'aria_role_menuitemcheckbox', |
| 223 earconId: 'BUTTON' |
222 }, | 224 }, |
223 menuItemRadio: { | 225 menuItemRadio: { |
224 msgId: 'aria_role_menuitemradio' | 226 msgId: 'aria_role_menuitemradio', |
| 227 earconId: 'BUTTON' |
225 }, | 228 }, |
226 menuListOption: { | 229 menuListOption: { |
227 msgId: 'aria_role_menuitem' | 230 msgId: 'aria_role_menuitem' |
228 }, | 231 }, |
229 menuListPopup: { | 232 menuListPopup: { |
230 msgId: 'aria_role_menu' | 233 msgId: 'aria_role_menu' |
231 }, | 234 }, |
232 navigation: { | 235 navigation: { |
233 msgId: 'aria_role_navigation', | 236 msgId: 'aria_role_navigation', |
234 inherits: 'abstractContainer' | 237 inherits: 'abstractContainer' |
235 }, | 238 }, |
236 note: { | 239 note: { |
237 msgId: 'aria_role_note', | 240 msgId: 'aria_role_note', |
238 inherits: 'abstractContainer' | 241 inherits: 'abstractContainer' |
239 }, | 242 }, |
240 popUpButton: { | 243 popUpButton: { |
241 msgId: 'tag_button', | 244 msgId: 'tag_button', |
242 earcon: 'LISTBOX' | |
243 }, | 245 }, |
244 radioButton: { | 246 radioButton: { |
245 msgId: 'input_type_radio' | 247 msgId: 'input_type_radio' |
246 }, | 248 }, |
247 radioGroup: { | 249 radioGroup: { |
248 msgId: 'aria_role_radiogroup', | 250 msgId: 'aria_role_radiogroup', |
249 }, | 251 }, |
250 region: { | 252 region: { |
251 msgId: 'aria_role_region', | 253 msgId: 'aria_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 30 matching lines...) Expand all Loading... |
373 alert: { | 372 alert: { |
374 speak: '!doNotInterrupt $role $descendants' | 373 speak: '!doNotInterrupt $role $descendants' |
375 }, | 374 }, |
376 alertDialog: { | 375 alertDialog: { |
377 enter: '$name $role $descendants' | 376 enter: '$name $role $descendants' |
378 }, | 377 }, |
379 cell: { | 378 cell: { |
380 enter: '@column_granularity $tableCellColumnIndex' | 379 enter: '@column_granularity $tableCellColumnIndex' |
381 }, | 380 }, |
382 checkBox: { | 381 checkBox: { |
383 speak: '$name $role $checked' | 382 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + |
| 383 '$name $role $checked' |
384 }, | 384 }, |
385 dialog: { | 385 dialog: { |
386 enter: '$name $role' | 386 enter: '$name $role' |
387 }, | 387 }, |
388 grid: { | 388 grid: { |
389 enter: '$name $role' | 389 enter: '$name $role' |
390 }, | 390 }, |
391 heading: { | 391 heading: { |
392 enter: '@tag_h+$hierarchicalLevel', | 392 enter: '@tag_h+$hierarchicalLevel', |
393 speak: '@tag_h+$hierarchicalLevel $nameOrDescendants=' | 393 speak: '@tag_h+$hierarchicalLevel $nameOrDescendants=' |
(...skipping 26 matching lines...) Expand all Loading... |
420 '@describe_index($indexInParent, $parentChildCount)' | 420 '@describe_index($indexInParent, $parentChildCount)' |
421 }, | 421 }, |
422 menuListOption: { | 422 menuListOption: { |
423 speak: '$name $value @aria_role_menuitem ' + | 423 speak: '$name $value @aria_role_menuitem ' + |
424 '@describe_index($indexInParent, $parentChildCount)' | 424 '@describe_index($indexInParent, $parentChildCount)' |
425 }, | 425 }, |
426 paragraph: { | 426 paragraph: { |
427 speak: '$descendants' | 427 speak: '$descendants' |
428 }, | 428 }, |
429 popUpButton: { | 429 popUpButton: { |
430 speak: '$value $name $role @aria_has_popup ' + | 430 speak: '$earcon(POP_UP_BUTTON) $value $name $role @aria_has_popup ' + |
431 '$if($collapsed, @aria_expanded_false, @aria_expanded_true)' | 431 '$if($collapsed, @aria_expanded_false, @aria_expanded_true)' |
432 }, | 432 }, |
433 radioButton: { | 433 radioButton: { |
434 speak: '$if($checked, @describe_radio_selected($name), ' + | 434 speak: '$if($checked, @describe_radio_selected($name), ' + |
435 '@describe_radio_unselected($name))' | 435 '@describe_radio_unselected($name))' |
436 }, | 436 }, |
437 radioGroup: { | 437 radioGroup: { |
438 enter: '$name $role' | 438 enter: '$name $role' |
439 }, | 439 }, |
440 rootWebArea: { | 440 rootWebArea: { |
441 enter: '$name' | 441 enter: '$name' |
442 }, | 442 }, |
443 row: { | 443 row: { |
444 enter: '@row_granularity $tableRowIndex' | 444 enter: '@row_granularity $tableRowIndex' |
445 }, | 445 }, |
446 slider: { | 446 slider: { |
447 speak: '@describe_slider($value, $name) $help' | 447 speak: '$earcon(SLIDER) @describe_slider($value, $name) $help' |
448 }, | 448 }, |
449 staticText: { | 449 staticText: { |
450 speak: '$value=' | 450 speak: '$value=' |
451 }, | 451 }, |
452 tab: { | 452 tab: { |
453 speak: '@describe_tab($name)' | 453 speak: '@describe_tab($name)' |
454 }, | 454 }, |
455 textField: { | 455 textField: { |
456 speak: '$name $value $if(' + | 456 speak: '$name $value $if(' + |
457 '$inputType, @input_type_+$inputType, @input_type_text)', | 457 '$inputType, @input_type_+$inputType, @input_type_text)', |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 return this; | 653 return this; |
654 }, | 654 }, |
655 | 655 |
656 /** | 656 /** |
657 * Executes all specified output. | 657 * Executes all specified output. |
658 */ | 658 */ |
659 go: function() { | 659 go: function() { |
660 // Speech. | 660 // Speech. |
661 var queueMode = cvox.QueueMode.FLUSH; | 661 var queueMode = cvox.QueueMode.FLUSH; |
662 this.speechBuffer_.forEach(function(buff, i, a) { | 662 this.speechBuffer_.forEach(function(buff, i, a) { |
663 if (buff.toString()) { | 663 (function() { |
664 (function() { | 664 var scopedBuff = buff; |
665 var scopedBuff = buff; | 665 this.speechProperties_['startCallback'] = function() { |
666 this.speechProperties_['startCallback'] = function() { | 666 var actions = scopedBuff.getSpansInstanceOf(Output.Action); |
667 var actions = scopedBuff.getSpansInstanceOf(Output.Action); | 667 if (actions) { |
668 if (actions) { | 668 actions.forEach(function(a) { |
669 actions.forEach(function(a) { | 669 a.run(); |
670 a.run(); | 670 }); |
671 }); | 671 } |
672 } | 672 }; |
673 }; | 673 }.bind(this)()); |
674 }.bind(this)()); | |
675 | 674 |
676 if (this.speechEndCallback_ && i == a.length - 1) | 675 if (this.speechEndCallback_ && i == a.length - 1) |
677 this.speechProperties_['endCallback'] = this.speechEndCallback_; | 676 this.speechProperties_['endCallback'] = this.speechEndCallback_; |
678 else | 677 else |
679 this.speechProperties_['endCallback'] = null; | 678 this.speechProperties_['endCallback'] = null; |
680 cvox.ChromeVox.tts.speak( | 679 cvox.ChromeVox.tts.speak( |
681 buff.toString(), queueMode, this.speechProperties_); | 680 buff.toString(), queueMode, this.speechProperties_); |
682 queueMode = cvox.QueueMode.QUEUE; | 681 queueMode = cvox.QueueMode.QUEUE; |
683 } | |
684 }.bind(this)); | 682 }.bind(this)); |
685 | 683 |
686 // Braille. | 684 // Braille. |
687 if (this.brailleBuffer_.length) { | 685 if (this.brailleBuffer_.length) { |
688 var buff = this.createBrailleOutput_(); | 686 var buff = this.createBrailleOutput_(); |
689 var selSpan = | 687 var selSpan = |
690 buff.getSpanInstanceOf(Output.SelectionSpan); | 688 buff.getSpanInstanceOf(Output.SelectionSpan); |
691 var startIndex = -1, endIndex = -1; | 689 var startIndex = -1, endIndex = -1; |
692 if (selSpan) { | 690 if (selSpan) { |
693 // Casts ok, since the span is known to be in the spannable. | 691 // Casts ok, since the span is known to be in the spannable. |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 var cond = tree.firstChild; | 919 var cond = tree.firstChild; |
922 var attrib = cond.value.slice(1); | 920 var attrib = cond.value.slice(1); |
923 if (node[attrib] || node.state[attrib]) | 921 if (node[attrib] || node.state[attrib]) |
924 this.format_(node, cond.nextSibling, buff); | 922 this.format_(node, cond.nextSibling, buff); |
925 else | 923 else |
926 this.format_(node, cond.nextSibling.nextSibling, buff); | 924 this.format_(node, cond.nextSibling.nextSibling, buff); |
927 } else if (token == 'earcon') { | 925 } else if (token == 'earcon') { |
928 // Ignore unless we're generating speech output. | 926 // Ignore unless we're generating speech output. |
929 if (!this.formatOptions_.speech) | 927 if (!this.formatOptions_.speech) |
930 return; | 928 return; |
931 // Assumes there's existing output in our buffer. | |
932 var lastBuff = buff[buff.length - 1]; | |
933 if (!lastBuff) | |
934 return; | |
935 | 929 |
936 lastBuff.setSpan( | 930 options.annotation.push( |
937 new Output.EarconAction(tree.firstChild.value), 0, 0); | 931 new Output.EarconAction(tree.firstChild.value), 0, 0); |
| 932 this.append_(buff, '', options); |
938 } else if (token == 'countChildren') { | 933 } else if (token == 'countChildren') { |
939 var role = tree.firstChild.value; | 934 var role = tree.firstChild.value; |
940 var count = node.children.filter(function(e) { | 935 var count = node.children.filter(function(e) { |
941 return e.role == role; | 936 return e.role == role; |
942 }).length; | 937 }).length; |
943 this.append_(buff, String(count)); | 938 this.append_(buff, String(count)); |
944 } | 939 } |
945 } | 940 } |
946 } else if (prefix == '@') { | 941 } else if (prefix == '@') { |
947 var isPluralized = (token[0] == '@'); | 942 var isPluralized = (token[0] == '@'); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1292 elem.end); | 1287 elem.end); |
1293 }); | 1288 }); |
1294 spansToRemove.forEach(result.removeSpan.bind(result)); | 1289 spansToRemove.forEach(result.removeSpan.bind(result)); |
1295 separator = Output.SPACE; | 1290 separator = Output.SPACE; |
1296 }); | 1291 }); |
1297 return result; | 1292 return result; |
1298 } | 1293 } |
1299 }; | 1294 }; |
1300 | 1295 |
1301 }); // goog.scope | 1296 }); // goog.scope |
OLD | NEW |