Chromium Code Reviews| 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, location: boolean}} | 66 * @type {{speech: boolean, braille: boolean, location: boolean}} |
| 67 * @private | |
| 67 */ | 68 */ |
| 68 this.formatOptions_ = {speech: true, braille: false, location: true}; | 69 this.formatOptions_ = {speech: true, braille: false, location: true}; |
| 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 no speech that will be output. | |
| 647 */ | |
| 648 get empty() { | |
|
Peter Lundblad
2015/11/20 13:42:58
Rename to hasSpeech or similar to make clear from
dmazzoni
2015/11/23 20:16:50
Done.
| |
| 649 for (var i = 0; i < this.speechBuffer_.length; i++) { | |
| 650 if (this.speechBuffer_[i].trim().length) | |
| 651 return false; | |
| 652 } | |
| 653 return true; | |
| 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, location: true}; | 664 this.formatOptions_ = {speech: true, braille: false, location: true}; |
| 622 this.render_(range, prevRange, type, this.speechBuffer_); | 665 this.render_(range, prevRange, type, this.speechBuffer_); |
| 623 return this; | 666 return this; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 648 this.withBraille(range, prevRange, type); | 691 this.withBraille(range, prevRange, type); |
| 649 return this; | 692 return this; |
| 650 }, | 693 }, |
| 651 | 694 |
| 652 /** | 695 /** |
| 653 * Applies the given speech category to the output. | 696 * Applies the given speech category to the output. |
| 654 * @param {cvox.TtsCategory} category | 697 * @param {cvox.TtsCategory} category |
| 655 * @return {!Output} | 698 * @return {!Output} |
| 656 */ | 699 */ |
| 657 withSpeechCategory: function(category) { | 700 withSpeechCategory: function(category) { |
| 658 this.speechProperties_['category'] = category; | 701 this.speechCategory_ = category; |
| 659 return this; | 702 return this; |
| 660 }, | 703 }, |
| 661 | 704 |
| 705 /** | |
| 706 * Applies the given speech queue mode to the output. | |
| 707 * @param {cvox.QueueMode} queueMode The queueMode for the speech. | |
| 708 * @return {!Output} | |
| 709 */ | |
| 710 withQueueMode: function(queueMode) { | |
| 711 this.queueMode_ = queueMode; | |
| 712 return this; | |
| 713 }, | |
| 714 | |
| 662 /** | 715 /** |
| 663 * Apply a format string directly to the output buffer. This lets you | 716 * Apply a format string directly to the output buffer. This lets you |
| 664 * output a message directly to the buffer using the format syntax. | 717 * output a message directly to the buffer using the format syntax. |
| 665 * @param {string} formatStr | 718 * @param {string} formatStr |
| 719 * @param {!chrome.automation.AutomationNode=} opt_node An optional | |
| 720 * node to apply the formatting to. | |
| 666 * @return {!Output} | 721 * @return {!Output} |
| 667 */ | 722 */ |
| 668 format: function(formatStr) { | 723 format: function(formatStr, opt_node) { |
| 724 var node = opt_node || null; | |
| 725 | |
| 669 this.formatOptions_ = {speech: true, braille: false, location: true}; | 726 this.formatOptions_ = {speech: true, braille: false, location: true}; |
| 670 this.format_(null, formatStr, this.speechBuffer_); | 727 this.format_(node, formatStr, this.speechBuffer_); |
| 671 | 728 |
| 672 this.formatOptions_ = {speech: false, braille: true, location: false}; | 729 this.formatOptions_ = {speech: false, braille: true, location: false}; |
| 673 this.format_(null, formatStr, this.brailleBuffer_); | 730 this.format_(node, formatStr, this.brailleBuffer_); |
| 674 | 731 |
| 675 return this; | 732 return this; |
| 676 }, | 733 }, |
| 677 | 734 |
| 678 /** | 735 /** |
| 679 * Triggers callback for a speech event. | 736 * Triggers callback for a speech event. |
| 680 * @param {function()} callback | 737 * @param {function()} callback |
| 681 */ | 738 */ |
| 682 onSpeechEnd: function(callback) { | 739 onSpeechEnd: function(callback) { |
| 683 this.speechEndCallback_ = function(opt_cleanupOnly) { | 740 this.speechEndCallback_ = function(opt_cleanupOnly) { |
| 684 if (!opt_cleanupOnly) | 741 if (!opt_cleanupOnly) |
| 685 callback(); | 742 callback(); |
| 686 }.bind(this); | 743 }.bind(this); |
| 687 return this; | 744 return this; |
| 688 }, | 745 }, |
| 689 | 746 |
| 690 /** | 747 /** |
| 691 * Executes all specified output. | 748 * Executes all specified output. |
| 692 */ | 749 */ |
| 693 go: function() { | 750 go: function() { |
| 694 // Speech. | 751 // Speech. |
| 695 var queueMode = this.speechProperties_['category'] ? | 752 var queueMode = this.queueMode_; |
| 696 cvox.QueueMode.CATEGORY_FLUSH : cvox.QueueMode.FLUSH; | 753 if (Output.flushNextSpeechUtterance_) { |
| 754 queueMode = cvox.QueueMode.FLUSH; | |
| 755 Output.flushNextSpeechUtterance_ = false; | |
| 756 } | |
| 757 | |
| 758 this.speechProperties_.category = this.speechCategory_; | |
| 759 | |
| 697 this.speechBuffer_.forEach(function(buff, i, a) { | 760 this.speechBuffer_.forEach(function(buff, i, a) { |
| 698 (function() { | 761 (function() { |
| 699 var scopedBuff = buff; | 762 var scopedBuff = buff; |
| 700 this.speechProperties_['startCallback'] = function() { | 763 this.speechProperties_['startCallback'] = function() { |
| 701 var actions = scopedBuff.getSpansInstanceOf(Output.Action); | 764 var actions = scopedBuff.getSpansInstanceOf(Output.Action); |
| 702 if (actions) { | 765 if (actions) { |
| 703 actions.forEach(function(a) { | 766 actions.forEach(function(a) { |
| 704 a.run(); | 767 a.run(); |
| 705 }); | 768 }); |
| 706 } | 769 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 734 var output = new cvox.NavBraille({ | 797 var output = new cvox.NavBraille({ |
| 735 text: buff, | 798 text: buff, |
| 736 startIndex: startIndex, | 799 startIndex: startIndex, |
| 737 endIndex: endIndex | 800 endIndex: endIndex |
| 738 }); | 801 }); |
| 739 | 802 |
| 740 cvox.ChromeVox.braille.write(output); | 803 cvox.ChromeVox.braille.write(output); |
| 741 } | 804 } |
| 742 | 805 |
| 743 // Display. | 806 // Display. |
| 744 if (cvox.ChromeVox.isChromeOS) | 807 if (cvox.ChromeVox.isChromeOS && |
| 808 this.speechCategory_ != cvox.TtsCategory.LIVE) { | |
| 745 chrome.accessibilityPrivate.setFocusRing(this.locations_); | 809 chrome.accessibilityPrivate.setFocusRing(this.locations_); |
| 810 } | |
| 746 }, | 811 }, |
| 747 | 812 |
| 748 /** | 813 /** |
| 749 * Renders the given range using optional context previous range and event | 814 * Renders the given range using optional context previous range and event |
| 750 * type. | 815 * type. |
| 751 * @param {!cursors.Range} range | 816 * @param {!cursors.Range} range |
| 752 * @param {cursors.Range} prevRange | 817 * @param {cursors.Range} prevRange |
| 753 * @param {chrome.automation.EventType|string} type | 818 * @param {chrome.automation.EventType|string} type |
| 754 * @param {!Array<Spannable>} buff Buffer to receive rendered output. | 819 * @param {!Array<Spannable>} buff Buffer to receive rendered output. |
| 755 * @private | 820 * @private |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 elem.end); | 1388 elem.end); |
| 1324 }); | 1389 }); |
| 1325 spansToRemove.forEach(result.removeSpan.bind(result)); | 1390 spansToRemove.forEach(result.removeSpan.bind(result)); |
| 1326 separator = Output.SPACE; | 1391 separator = Output.SPACE; |
| 1327 }); | 1392 }); |
| 1328 return result; | 1393 return result; |
| 1329 } | 1394 } |
| 1330 }; | 1395 }; |
| 1331 | 1396 |
| 1332 }); // goog.scope | 1397 }); // goog.scope |
| OLD | NEW |