| 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 The entry point for all ChromeVox2 related code for the | 6 * @fileoverview The entry point for all ChromeVox2 related code for the |
| 7 * background page. | 7 * background page. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 goog.provide('Background'); | 10 goog.provide('Background'); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 /** | 148 /** |
| 149 * Stores the mode as computed the last time a current range was set. | 149 * Stores the mode as computed the last time a current range was set. |
| 150 * @type {?ChromeVoxMode} | 150 * @type {?ChromeVoxMode} |
| 151 * @private | 151 * @private |
| 152 */ | 152 */ |
| 153 this.mode_ = null; | 153 this.mode_ = null; |
| 154 | 154 |
| 155 chrome.accessibilityPrivate.onAccessibilityGesture.addListener( | 155 chrome.accessibilityPrivate.onAccessibilityGesture.addListener( |
| 156 this.onAccessibilityGesture_); | 156 this.onAccessibilityGesture_); |
| 157 |
| 158 /** |
| 159 * Maps a non-desktop root automation node to a range position suitable for |
| 160 * restoration. |
| 161 * @type {WeakMap<AutomationNode, cursors.Range>} |
| 162 * @private |
| 163 */ |
| 164 this.focusRecoveryMap_ = new WeakMap(); |
| 157 }; | 165 }; |
| 158 | 166 |
| 159 /** | 167 /** |
| 160 * @const {string} | 168 * @const {string} |
| 161 */ | 169 */ |
| 162 Background.ISSUE_URL = 'https://code.google.com/p/chromium/issues/entry?' + | 170 Background.ISSUE_URL = 'https://code.google.com/p/chromium/issues/entry?' + |
| 163 'labels=Type-Bug,Pri-2,cvox2,OS-Chrome&' + | 171 'labels=Type-Bug,Pri-2,cvox2,OS-Chrome&' + |
| 164 'components=UI>accessibility&' + | 172 'components=UI>accessibility&' + |
| 165 'description='; | 173 'description='; |
| 166 | 174 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 191 'swipeUp1': 'previousLine', | 199 'swipeUp1': 'previousLine', |
| 192 'swipeDown1': 'nextLine', | 200 'swipeDown1': 'nextLine', |
| 193 'swipeLeft1': 'previousObject', | 201 'swipeLeft1': 'previousObject', |
| 194 'swipeRight1': 'nextObject', | 202 'swipeRight1': 'nextObject', |
| 195 'swipeUp2': 'jumpToTop', | 203 'swipeUp2': 'jumpToTop', |
| 196 'swipeDown2': 'readFromHere', | 204 'swipeDown2': 'readFromHere', |
| 197 }; | 205 }; |
| 198 | 206 |
| 199 Background.prototype = { | 207 Background.prototype = { |
| 200 __proto__: ChromeVoxState.prototype, | 208 __proto__: ChromeVoxState.prototype, |
| 209 /** |
| 210 * Maps the last node with range in a given root. |
| 211 * @type {WeakMap<AutomationNode>} |
| 212 */ |
| 213 get focusRecoveryMap() { |
| 214 return this.focusRecoveryMap_; |
| 215 }, |
| 201 | 216 |
| 202 /** | 217 /** |
| 203 * @override | 218 * @override |
| 204 */ | 219 */ |
| 205 getMode: function() { | 220 getMode: function() { |
| 206 if (localStorage['useNext'] == 'true') | 221 if (localStorage['useNext'] == 'true') |
| 207 return ChromeVoxMode.FORCE_NEXT; | 222 return ChromeVoxMode.FORCE_NEXT; |
| 208 | 223 |
| 209 var target; | 224 var target; |
| 210 if (!this.getCurrentRange()) { | 225 if (!this.getCurrentRange()) { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 } else if (action == 'onCommand') { | 652 } else if (action == 'onCommand') { |
| 638 CommandHandler.onCommand(msg['command']); | 653 CommandHandler.onCommand(msg['command']); |
| 639 } else if (action == 'flushNextUtterance') { | 654 } else if (action == 'flushNextUtterance') { |
| 640 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); | 655 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); |
| 641 } | 656 } |
| 642 break; | 657 break; |
| 643 } | 658 } |
| 644 }, | 659 }, |
| 645 | 660 |
| 646 /** | 661 /** |
| 647 * Restore the range to the last range that was *not* in the ChromeVox | 662 * Save the current ChromeVox range. |
| 648 * panel. This is used when the ChromeVox Panel closes. | |
| 649 * @param {function()=} opt_callback | |
| 650 * @private | |
| 651 */ | 663 */ |
| 652 restoreCurrentRange_: function(opt_callback) { | 664 markCurrentRange: function() { |
| 653 if (this.savedRange_) { | 665 if (!this.currentRange) |
| 654 var node = this.savedRange_.start.node; | 666 return; |
| 655 var containingWebView = node; | |
| 656 while (containingWebView && containingWebView.role != RoleType.webView) | |
| 657 containingWebView = containingWebView.parent; | |
| 658 | 667 |
| 659 if (containingWebView) { | 668 var root = AutomationUtil.getTopLevelRoot(this.currentRange.start.node); |
| 660 // Focusing the webView causes a focus change event which steals focus | 669 if (root) |
| 661 // away from the saved range. | 670 this.focusRecoveryMap_.set(root, this.currentRange); |
| 662 var saved = this.savedRange_; | |
| 663 var setSavedRange = function(e) { | |
| 664 if (e.target.root == saved.start.node.root) { | |
| 665 this.navigateToRange(saved, false); | |
| 666 opt_callback && opt_callback(); | |
| 667 } | |
| 668 node.root.removeEventListener(EventType.focus, setSavedRange, true); | |
| 669 }.bind(this); | |
| 670 node.root.addEventListener(EventType.focus, setSavedRange, true); | |
| 671 containingWebView.focus(); | |
| 672 } | |
| 673 this.navigateToRange(this.savedRange_); | |
| 674 this.savedRange_ = null; | |
| 675 } | |
| 676 }, | 671 }, |
| 677 | 672 |
| 678 /** | 673 /** |
| 679 * Move ChromeVox without saving any ranges. | |
| 680 */ | |
| 681 startExcursion: function() { | |
| 682 this.inExcursion_ = true; | |
| 683 }, | |
| 684 | |
| 685 /** | |
| 686 * Move ChromeVox back to the last saved range. | |
| 687 * @param {function()=} opt_callback Called when range has been restored. | |
| 688 */ | |
| 689 endExcursion: function(opt_callback) { | |
| 690 this.inExcursion_ = false; | |
| 691 this.restoreCurrentRange_(opt_callback); | |
| 692 }, | |
| 693 | |
| 694 /** | |
| 695 * Move ChromeVox back to the last saved range. | |
| 696 */ | |
| 697 saveExcursion: function() { | |
| 698 this.savedRange_ = | |
| 699 new cursors.Range(this.currentRange_.start, this.currentRange_.end); | |
| 700 }, | |
| 701 | |
| 702 /** | |
| 703 * Handles accessibility gestures from the touch screen. | 674 * Handles accessibility gestures from the touch screen. |
| 704 * @param {string} gesture The gesture to handle, based on the AXGesture enum | 675 * @param {string} gesture The gesture to handle, based on the AXGesture enum |
| 705 * defined in ui/accessibility/ax_enums.idl | 676 * defined in ui/accessibility/ax_enums.idl |
| 706 * @private | 677 * @private |
| 707 */ | 678 */ |
| 708 onAccessibilityGesture_: function(gesture) { | 679 onAccessibilityGesture_: function(gesture) { |
| 709 // If we're in classic mode, some gestures need to be handled by the | 680 // If we're in classic mode, some gestures need to be handled by the |
| 710 // content script. Other gestures are universal and will be handled in | 681 // content script. Other gestures are universal and will be handled in |
| 711 // this function. | 682 // this function. |
| 712 if (this.mode == ChromeVoxMode.CLASSIC) { | 683 if (this.mode == ChromeVoxMode.CLASSIC) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 return new RegExp('^(' + globs.map(function(glob) { | 733 return new RegExp('^(' + globs.map(function(glob) { |
| 763 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') | 734 return glob.replace(/[.+^$(){}|[\]\\]/g, '\\$&') |
| 764 .replace(/\*/g, '.*') | 735 .replace(/\*/g, '.*') |
| 765 .replace(/\?/g, '.'); | 736 .replace(/\?/g, '.'); |
| 766 }).join('|') + ')$'); | 737 }).join('|') + ')$'); |
| 767 }; | 738 }; |
| 768 | 739 |
| 769 new Background(); | 740 new Background(); |
| 770 | 741 |
| 771 }); // goog.scope | 742 }); // goog.scope |
| OLD | NEW |