| 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'); |
| 11 goog.provide('global'); | 11 goog.provide('global'); |
| 12 | 12 |
| 13 goog.require('AutomationPredicate'); | 13 goog.require('AutomationPredicate'); |
| 14 goog.require('AutomationUtil'); | 14 goog.require('AutomationUtil'); |
| 15 goog.require('Output'); | 15 goog.require('Output'); |
| 16 goog.require('Output.EventType'); | 16 goog.require('Output.EventType'); |
| 17 goog.require('cursors.Cursor'); | 17 goog.require('cursors.Cursor'); |
| 18 goog.require('cvox.ChromeVoxEditableTextBase'); | 18 goog.require('cvox.ChromeVoxEditableTextBase'); |
| 19 goog.require('cvox.TabsApiHandler'); | |
| 20 | 19 |
| 21 // Define types here due to editable_text.js's implicit dependency with | 20 // Define types here due to editable_text.js's implicit dependency with |
| 22 // ChromeVoxEventWatcher. | 21 // ChromeVoxEventWatcher. |
| 23 /** @type {Object} */ | 22 /** @type {Object} */ |
| 24 cvox.ChromeVoxEventWatcher; | 23 cvox.ChromeVoxEventWatcher; |
| 25 /** @type {function(boolean)} */ | 24 /** @type {function(boolean)} */ |
| 26 cvox.ChromeVoxEventWatcher.handleTextChanged; | 25 cvox.ChromeVoxEventWatcher.handleTextChanged; |
| 27 /** @type {function()} */ | 26 /** @type {function()} */ |
| 28 cvox.ChromeVoxEventWatcher.setUpTextHandler; | 27 cvox.ChromeVoxEventWatcher.setUpTextHandler; |
| 29 | 28 |
| 30 goog.scope(function() { | 29 goog.scope(function() { |
| 31 var AutomationNode = chrome.automation.AutomationNode; | 30 var AutomationNode = chrome.automation.AutomationNode; |
| 32 var Dir = AutomationUtil.Dir; | 31 var Dir = AutomationUtil.Dir; |
| 33 var EventType = chrome.automation.EventType; | 32 var EventType = chrome.automation.EventType; |
| 34 | 33 |
| 35 /** | 34 /** |
| 36 * ChromeVox2 background page. | 35 * ChromeVox2 background page. |
| 37 * @constructor | 36 * @constructor |
| 38 */ | 37 */ |
| 39 Background = function() { | 38 Background = function() { |
| 40 /** | 39 /** |
| 41 * A list of site substring patterns to use with ChromeVox next. Keep these | 40 * A list of site substring patterns to use with ChromeVox next. Keep these |
| 42 * strings relatively specific. | 41 * strings relatively specific. |
| 43 * @type {!Array.<string>} | 42 * @type {!Array.<string>} |
| 44 * @private | 43 * @private |
| 45 */ | 44 */ |
| 46 this.whitelist_ = ['chromevox_next_test']; | 45 this.whitelist_ = ['chromevox_next_test']; |
| 47 | 46 |
| 48 /** | 47 /** |
| 49 * @type {cvox.TabsApiHandler} | |
| 50 * @private | |
| 51 */ | |
| 52 this.tabsHandler_ = new cvox.TabsApiHandler(cvox.ChromeVox.tts, | |
| 53 cvox.ChromeVox.braille, | |
| 54 cvox.ChromeVox.earcons); | |
| 55 | |
| 56 /** | |
| 57 * @type {cursors.Range} | 48 * @type {cursors.Range} |
| 58 * @private | 49 * @private |
| 59 */ | 50 */ |
| 60 this.currentRange_ = null; | 51 this.currentRange_ = null; |
| 61 | 52 |
| 62 /** | 53 /** |
| 63 * Whether ChromeVox Next is active. | 54 * Whether ChromeVox Next is active. |
| 64 * @type {boolean} | 55 * @type {boolean} |
| 65 * @private | 56 * @private |
| 66 */ | 57 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 84 menuEnd: this.onEventDefault, | 75 menuEnd: this.onEventDefault, |
| 85 menuListValueChanged: this.onEventDefault, | 76 menuListValueChanged: this.onEventDefault, |
| 86 loadComplete: this.onLoadComplete, | 77 loadComplete: this.onLoadComplete, |
| 87 textChanged: this.onTextOrTextSelectionChanged, | 78 textChanged: this.onTextOrTextSelectionChanged, |
| 88 textSelectionChanged: this.onTextOrTextSelectionChanged, | 79 textSelectionChanged: this.onTextOrTextSelectionChanged, |
| 89 valueChanged: this.onEventDefault | 80 valueChanged: this.onEventDefault |
| 90 }; | 81 }; |
| 91 | 82 |
| 92 // Register listeners for ... | 83 // Register listeners for ... |
| 93 // Desktop. | 84 // Desktop. |
| 94 chrome.automation.getDesktop(this.onGotTree); | 85 chrome.automation.getDesktop(this.onGotDesktop); |
| 95 | 86 |
| 96 // Tabs. | 87 // Tabs. |
| 97 chrome.tabs.onUpdated.addListener(this.onTabUpdated); | 88 chrome.tabs.onUpdated.addListener(this.onTabUpdated); |
| 98 }; | 89 }; |
| 99 | 90 |
| 100 Background.prototype = { | 91 Background.prototype = { |
| 101 /** | 92 /** |
| 102 * Handles chrome.tabs.onUpdated. | 93 * Handles chrome.tabs.onUpdated. |
| 103 * @param {number} tabId | 94 * @param {number} tabId |
| 104 * @param {Object} changeInfo | 95 * @param {Object} changeInfo |
| 105 */ | 96 */ |
| 106 onTabUpdated: function(tabId, changeInfo) { | 97 onTabUpdated: function(tabId, changeInfo) { |
| 107 if (changeInfo.status != 'complete') | 98 if (changeInfo.status != 'complete') |
| 108 return; | 99 return; |
| 109 chrome.tabs.get(tabId, function(tab) { | 100 chrome.tabs.get(tabId, function(tab) { |
| 110 if (!tab.url) | 101 if (!tab.url) |
| 111 return; | 102 return; |
| 112 | 103 |
| 113 var next = this.isWhitelisted_(tab.url); | 104 var next = this.isWhitelisted_(tab.url); |
| 114 | 105 |
| 115 this.toggleChromeVoxVersion({next: next, classic: !next}); | 106 this.toggleChromeVoxVersion({next: next, classic: !next}); |
| 116 }.bind(this)); | 107 }.bind(this)); |
| 117 }, | 108 }, |
| 118 | 109 |
| 119 /** | 110 /** |
| 120 * Handles all setup once a new automation tree appears. | 111 * Handles all setup once a new automation tree appears. |
| 121 * @param {chrome.automation.AutomationNode} root | 112 * @param {chrome.automation.AutomationNode} desktop |
| 122 */ | 113 */ |
| 123 onGotTree: function(root) { | 114 onGotDesktop: function(desktop) { |
| 124 // Register all automation event listeners. | 115 // Register all automation event listeners. |
| 125 for (var eventType in this.listeners_) | 116 for (var eventType in this.listeners_) |
| 126 root.addEventListener(eventType, this.listeners_[eventType], true); | 117 desktop.addEventListener(eventType, this.listeners_[eventType], true); |
| 127 | 118 |
| 128 if (root.attributes.docLoaded) { | 119 var root = desktop.find({role: chrome.automation.RoleType.rootWebArea, |
| 120 state: {focused: true}}); |
| 121 if (root && root.attributes.docLoaded) { |
| 129 this.onLoadComplete( | 122 this.onLoadComplete( |
| 130 {target: root, type: chrome.automation.EventType.loadComplete}); | 123 {target: root, type: chrome.automation.EventType.loadComplete}); |
| 131 } | 124 } |
| 132 }, | 125 }, |
| 133 | 126 |
| 134 /** | 127 /** |
| 135 * Handles chrome.commands.onCommand. | 128 * Handles chrome.commands.onCommand. |
| 136 * @param {string} command | 129 * @param {string} command |
| 137 */ | 130 */ |
| 138 onGotCommand: function(command) { | 131 onGotCommand: function(command) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 */ | 357 */ |
| 365 toggleChromeVoxVersion: function(opt_options) { | 358 toggleChromeVoxVersion: function(opt_options) { |
| 366 if (!opt_options) { | 359 if (!opt_options) { |
| 367 opt_options = {}; | 360 opt_options = {}; |
| 368 opt_options.next = !this.active_; | 361 opt_options.next = !this.active_; |
| 369 opt_options.classic = !opt_options.next; | 362 opt_options.classic = !opt_options.next; |
| 370 } | 363 } |
| 371 | 364 |
| 372 if (opt_options.next) { | 365 if (opt_options.next) { |
| 373 if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) | 366 if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) |
| 374 chrome.commands.onCommand.addListener(this.onGotCommand); | 367 chrome.commands.onCommand.addListener(this.onGotCommand); |
| 375 | 368 this.active_ = true; |
| 376 if (!this.active_) | |
| 377 chrome.automation.getTree(this.onGotTree); | |
| 378 this.active_ = true; | |
| 379 } else { | 369 } else { |
| 380 if (chrome.commands.onCommand.hasListener(this.onGotCommand)) | 370 if (chrome.commands.onCommand.hasListener(this.onGotCommand)) |
| 381 chrome.commands.onCommand.removeListener(this.onGotCommand); | 371 chrome.commands.onCommand.removeListener(this.onGotCommand); |
| 382 | |
| 383 if (this.active_) { | |
| 384 for (var eventType in this.listeners_) { | |
| 385 this.currentRange_.getStart().getNode().root.removeEventListener( | |
| 386 eventType, this.listeners_[eventType], true); | |
| 387 } | |
| 388 } | |
| 389 this.active_ = false; | 372 this.active_ = false; |
| 390 } | 373 } |
| 391 | 374 |
| 392 chrome.tabs.query({active: true}, function(tabs) { | 375 chrome.tabs.query({active: true}, function(tabs) { |
| 393 if (opt_options.classic) { | 376 if (opt_options.classic) { |
| 394 // This case should do nothing because Classic gets injected by the | 377 // This case should do nothing because Classic gets injected by the |
| 395 // extension system via our manifest. Once ChromeVox Next is enabled | 378 // extension system via our manifest. Once ChromeVox Next is enabled |
| 396 // for tabs, re-enable. | 379 // for tabs, re-enable. |
| 397 // cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); | 380 // cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); |
| 398 } else { | 381 } else { |
| 399 tabs.forEach(function(tab) { | 382 tabs.forEach(function(tab) { |
| 400 this.disableClassicChromeVox_(tab.id); | 383 this.disableClassicChromeVox_(tab.id); |
| 401 }.bind(this)); | 384 }.bind(this)); |
| 402 } | 385 } |
| 403 }.bind(this)); | 386 }.bind(this)); |
| 404 } | 387 } |
| 405 }; | 388 }; |
| 406 | 389 |
| 407 /** @type {Background} */ | 390 /** @type {Background} */ |
| 408 global.backgroundObj = new Background(); | 391 global.backgroundObj = new Background(); |
| 409 | 392 |
| 410 }); // goog.scope | 393 }); // goog.scope |
| OLD | NEW |