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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 /** @type {!Array<!Spannable>} */ | 57 /** @type {!Array<!Spannable>} */ |
58 this.brailleBuffer_ = []; | 58 this.brailleBuffer_ = []; |
59 /** @type {!Array<!Object>} */ | 59 /** @type {!Array<!Object>} */ |
60 this.locations_ = []; | 60 this.locations_ = []; |
61 /** @type {function(?)} */ | 61 /** @type {function(?)} */ |
62 this.speechEndCallback_; | 62 this.speechEndCallback_; |
63 | 63 |
64 /** | 64 /** |
65 * Current global options. | 65 * Current global options. |
66 * @type {{speech: boolean, braille: boolean}} | 66 * @type {{speech: boolean, braille: boolean}} |
| 67 * @private |
67 */ | 68 */ |
68 this.formatOptions_ = {speech: true, braille: false}; | 69 this.formatOptions_ = {speech: true, braille: false}; |
69 | 70 |
70 /** | 71 /** |
71 * Speech properties to apply to the entire output. | 72 * Speech properties to apply to the entire output. |
72 * @type {!Object<*>} | 73 * @type {!Object<*>} |
| 74 * @private |
73 */ | 75 */ |
74 this.speechProperties_ = {}; | 76 this.speechProperties_ = {}; |
| 77 |
| 78 /** |
| 79 * The speech category for the generated speech utterance. |
| 80 * @type {cvox.TtsCategory} |
| 81 * @private |
| 82 */ |
| 83 this.speechCategory_ = cvox.TtsCategory.NAV; |
| 84 |
| 85 /** |
| 86 * The speech queue mode for the generated speech utterance. |
| 87 * @type {cvox.QueueMode} |
| 88 * @private |
| 89 */ |
| 90 this.queueMode_ = cvox.QueueMode.QUEUE; |
75 }; | 91 }; |
76 | 92 |
77 /** | 93 /** |
78 * Delimiter to use between output values. | 94 * Delimiter to use between output values. |
79 * @type {string} | 95 * @type {string} |
80 */ | 96 */ |
81 Output.SPACE = ' '; | 97 Output.SPACE = ' '; |
82 | 98 |
83 /** | 99 /** |
84 * Metadata about supported automation roles. | 100 * Metadata about supported automation roles. |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 }; | 596 }; |
581 | 597 |
582 /** | 598 /** |
583 * Possible events handled by ChromeVox internally. | 599 * Possible events handled by ChromeVox internally. |
584 * @enum {string} | 600 * @enum {string} |
585 */ | 601 */ |
586 Output.EventType = { | 602 Output.EventType = { |
587 NAVIGATE: 'navigate' | 603 NAVIGATE: 'navigate' |
588 }; | 604 }; |
589 | 605 |
| 606 /** |
| 607 * If true, the next speech utterance will flush instead of the normal |
| 608 * queueing mode. |
| 609 * @type {boolean} |
| 610 * @private |
| 611 */ |
| 612 Output.flushNextSpeechUtterance_ = false; |
| 613 |
| 614 /** |
| 615 * Calling this will make the next speech utterance flush even if it would |
| 616 * normally queue or do a category flush. |
| 617 */ |
| 618 Output.flushNextSpeechUtterance = function() { |
| 619 Output.flushNextSpeechUtterance_ = true; |
| 620 }; |
| 621 |
590 Output.prototype = { | 622 Output.prototype = { |
591 /** | 623 /** |
592 * Gets the spoken output with separator '|'. | 624 * Gets the spoken output with separator '|'. |
593 * @return {!Spannable} | 625 * @return {!Spannable} |
594 */ | 626 */ |
595 get speechOutputForTest() { | 627 get speechOutputForTest() { |
596 return this.speechBuffer_.reduce(function(prev, cur) { | 628 return this.speechBuffer_.reduce(function(prev, cur) { |
597 if (prev === null) | 629 if (prev === null) |
598 return cur; | 630 return cur; |
599 prev.append('|'); | 631 prev.append('|'); |
600 prev.append(cur); | 632 prev.append(cur); |
601 return prev; | 633 return prev; |
602 }, null); | 634 }, null); |
603 }, | 635 }, |
604 | 636 |
605 /** | 637 /** |
606 * Gets the output buffer for braille. | 638 * Gets the output buffer for braille. |
607 * @return {!Spannable} | 639 * @return {!Spannable} |
608 */ | 640 */ |
609 get brailleOutputForTest() { | 641 get brailleOutputForTest() { |
610 return this.createBrailleOutput_(); | 642 return this.createBrailleOutput_(); |
611 }, | 643 }, |
612 | 644 |
613 /** | 645 /** |
| 646 * @return {boolean} True if there's any speech that will be output. |
| 647 */ |
| 648 get hasSpeech() { |
| 649 for (var i = 0; i < this.speechBuffer_.length; i++) { |
| 650 if (this.speechBuffer_[i].trim().length) |
| 651 return true; |
| 652 } |
| 653 return false; |
| 654 }, |
| 655 |
| 656 /** |
614 * Specify ranges for speech. | 657 * Specify ranges for speech. |
615 * @param {!cursors.Range} range | 658 * @param {!cursors.Range} range |
616 * @param {cursors.Range} prevRange | 659 * @param {cursors.Range} prevRange |
617 * @param {chrome.automation.EventType|Output.EventType} type | 660 * @param {chrome.automation.EventType|Output.EventType} type |
618 * @return {!Output} | 661 * @return {!Output} |
619 */ | 662 */ |
620 withSpeech: function(range, prevRange, type) { | 663 withSpeech: function(range, prevRange, type) { |
621 this.formatOptions_ = {speech: true, braille: false}; | 664 this.formatOptions_ = {speech: true, braille: false}; |
622 this.render_(range, prevRange, type, this.speechBuffer_); | 665 this.render_(range, prevRange, type, this.speechBuffer_); |
623 return this; | 666 return this; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 this.withBraille(range, prevRange, type); | 704 this.withBraille(range, prevRange, type); |
662 return this; | 705 return this; |
663 }, | 706 }, |
664 | 707 |
665 /** | 708 /** |
666 * Applies the given speech category to the output. | 709 * Applies the given speech category to the output. |
667 * @param {cvox.TtsCategory} category | 710 * @param {cvox.TtsCategory} category |
668 * @return {!Output} | 711 * @return {!Output} |
669 */ | 712 */ |
670 withSpeechCategory: function(category) { | 713 withSpeechCategory: function(category) { |
671 this.speechProperties_['category'] = category; | 714 this.speechCategory_ = category; |
672 return this; | 715 return this; |
673 }, | 716 }, |
674 | 717 |
| 718 /** |
| 719 * Applies the given speech queue mode to the output. |
| 720 * @param {cvox.QueueMode} queueMode The queueMode for the speech. |
| 721 * @return {!Output} |
| 722 */ |
| 723 withQueueMode: function(queueMode) { |
| 724 this.queueMode_ = queueMode; |
| 725 return this; |
| 726 }, |
| 727 |
675 /** | 728 /** |
676 * Apply a format string directly to the output buffer. This lets you | 729 * Apply a format string directly to the output buffer. This lets you |
677 * output a message directly to the buffer using the format syntax. | 730 * output a message directly to the buffer using the format syntax. |
678 * @param {string} formatStr | 731 * @param {string} formatStr |
| 732 * @param {!chrome.automation.AutomationNode=} opt_node An optional |
| 733 * node to apply the formatting to. |
679 * @return {!Output} | 734 * @return {!Output} |
680 */ | 735 */ |
681 format: function(formatStr) { | 736 format: function(formatStr, opt_node) { |
| 737 var node = opt_node || null; |
| 738 |
682 this.formatOptions_ = {speech: true, braille: false}; | 739 this.formatOptions_ = {speech: true, braille: false}; |
683 this.format_(null, formatStr, this.speechBuffer_); | 740 this.format_(node, formatStr, this.speechBuffer_); |
684 | 741 |
685 this.formatOptions_ = {speech: false, braille: true}; | 742 this.formatOptions_ = {speech: false, braille: true}; |
686 this.format_(null, formatStr, this.brailleBuffer_); | 743 this.format_(node, formatStr, this.brailleBuffer_); |
687 | 744 |
688 return this; | 745 return this; |
689 }, | 746 }, |
690 | 747 |
691 /** | 748 /** |
692 * Triggers callback for a speech event. | 749 * Triggers callback for a speech event. |
693 * @param {function()} callback | 750 * @param {function()} callback |
694 */ | 751 */ |
695 onSpeechEnd: function(callback) { | 752 onSpeechEnd: function(callback) { |
696 this.speechEndCallback_ = function(opt_cleanupOnly) { | 753 this.speechEndCallback_ = function(opt_cleanupOnly) { |
697 if (!opt_cleanupOnly) | 754 if (!opt_cleanupOnly) |
698 callback(); | 755 callback(); |
699 }.bind(this); | 756 }.bind(this); |
700 return this; | 757 return this; |
701 }, | 758 }, |
702 | 759 |
703 /** | 760 /** |
704 * Executes all specified output. | 761 * Executes all specified output. |
705 */ | 762 */ |
706 go: function() { | 763 go: function() { |
707 // Speech. | 764 // Speech. |
708 var queueMode = this.speechProperties_['category'] ? | 765 var queueMode = this.queueMode_; |
709 cvox.QueueMode.CATEGORY_FLUSH : cvox.QueueMode.FLUSH; | 766 if (Output.flushNextSpeechUtterance_) { |
| 767 queueMode = cvox.QueueMode.FLUSH; |
| 768 Output.flushNextSpeechUtterance_ = false; |
| 769 } |
| 770 |
| 771 this.speechProperties_.category = this.speechCategory_; |
| 772 |
710 this.speechBuffer_.forEach(function(buff, i, a) { | 773 this.speechBuffer_.forEach(function(buff, i, a) { |
711 (function() { | 774 (function() { |
712 var scopedBuff = buff; | 775 var scopedBuff = buff; |
713 this.speechProperties_['startCallback'] = function() { | 776 this.speechProperties_['startCallback'] = function() { |
714 var actions = scopedBuff.getSpansInstanceOf(Output.Action); | 777 var actions = scopedBuff.getSpansInstanceOf(Output.Action); |
715 if (actions) { | 778 if (actions) { |
716 actions.forEach(function(a) { | 779 actions.forEach(function(a) { |
717 a.run(); | 780 a.run(); |
718 }); | 781 }); |
719 } | 782 } |
(...skipping 27 matching lines...) Expand all Loading... |
747 var output = new cvox.NavBraille({ | 810 var output = new cvox.NavBraille({ |
748 text: buff, | 811 text: buff, |
749 startIndex: startIndex, | 812 startIndex: startIndex, |
750 endIndex: endIndex | 813 endIndex: endIndex |
751 }); | 814 }); |
752 | 815 |
753 cvox.ChromeVox.braille.write(output); | 816 cvox.ChromeVox.braille.write(output); |
754 } | 817 } |
755 | 818 |
756 // Display. | 819 // Display. |
757 if (cvox.ChromeVox.isChromeOS) | 820 if (cvox.ChromeVox.isChromeOS && |
| 821 this.speechCategory_ != cvox.TtsCategory.LIVE) { |
758 chrome.accessibilityPrivate.setFocusRing(this.locations_); | 822 chrome.accessibilityPrivate.setFocusRing(this.locations_); |
| 823 } |
759 }, | 824 }, |
760 | 825 |
761 /** | 826 /** |
762 * Renders the given range using optional context previous range and event | 827 * Renders the given range using optional context previous range and event |
763 * type. | 828 * type. |
764 * @param {!cursors.Range} range | 829 * @param {!cursors.Range} range |
765 * @param {cursors.Range} prevRange | 830 * @param {cursors.Range} prevRange |
766 * @param {chrome.automation.EventType|string} type | 831 * @param {chrome.automation.EventType|string} type |
767 * @param {!Array<Spannable>} buff Buffer to receive rendered output. | 832 * @param {!Array<Spannable>} buff Buffer to receive rendered output. |
768 * @private | 833 * @private |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 elem.end); | 1402 elem.end); |
1338 }); | 1403 }); |
1339 spansToRemove.forEach(result.removeSpan.bind(result)); | 1404 spansToRemove.forEach(result.removeSpan.bind(result)); |
1340 separator = Output.SPACE; | 1405 separator = Output.SPACE; |
1341 }); | 1406 }); |
1342 return result; | 1407 return result; |
1343 } | 1408 } |
1344 }; | 1409 }; |
1345 | 1410 |
1346 }); // goog.scope | 1411 }); // goog.scope |
OLD | NEW |