| 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 |