| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 this[func] = this[func].bind(this); | 79 this[func] = this[func].bind(this); |
| 80 } | 80 } |
| 81 | 81 |
| 82 /** | 82 /** |
| 83 * Maps an automation event to its listener. | 83 * Maps an automation event to its listener. |
| 84 * @type {!Object.<EventType, function(Object) : void>} | 84 * @type {!Object.<EventType, function(Object) : void>} |
| 85 */ | 85 */ |
| 86 this.listeners_ = { | 86 this.listeners_ = { |
| 87 alert: this.onEventDefault, | 87 alert: this.onEventDefault, |
| 88 focus: this.onEventDefault, | 88 focus: this.onEventDefault, |
| 89 hover: this.onEventDefault, |
| 89 menuStart: this.onEventDefault, | 90 menuStart: this.onEventDefault, |
| 90 menuEnd: this.onEventDefault, | 91 menuEnd: this.onEventDefault, |
| 91 loadComplete: this.onLoadComplete, | 92 loadComplete: this.onLoadComplete, |
| 92 textSelectionChanged: this.onTextSelectionChanged | 93 textChanged: this.onTextOrTextSelectionChanged, |
| 94 textSelectionChanged: this.onTextOrTextSelectionChanged, |
| 95 valueChanged: this.onEventDefault |
| 93 }; | 96 }; |
| 94 | 97 |
| 95 // Register listeners for ... | 98 // Register listeners for ... |
| 96 // Desktop. | 99 // Desktop. |
| 97 chrome.automation.getDesktop(this.onGotTree); | 100 chrome.automation.getDesktop(this.onGotTree); |
| 98 | 101 |
| 99 // Tabs. | 102 // Tabs. |
| 100 chrome.tabs.onUpdated.addListener(this.onTabUpdated); | 103 chrome.tabs.onUpdated.addListener(this.onTabUpdated); |
| 101 | |
| 102 // Commands. | |
| 103 chrome.commands.onCommand.addListener(this.onGotCommand); | |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 Background.prototype = { | 106 Background.prototype = { |
| 107 /** | 107 /** |
| 108 * Handles chrome.tabs.onUpdated. | 108 * Handles chrome.tabs.onUpdated. |
| 109 * @param {number} tabId | 109 * @param {number} tabId |
| 110 * @param {Object} changeInfo | 110 * @param {Object} changeInfo |
| 111 */ | 111 */ |
| 112 onTabUpdated: function(tabId, changeInfo) { | 112 onTabUpdated: function(tabId, changeInfo) { |
| 113 if (!this.active_) |
| 114 return; |
| 115 |
| 113 if (changeInfo.status != 'complete') | 116 if (changeInfo.status != 'complete') |
| 114 return; | 117 return; |
| 115 chrome.tabs.get(tabId, function(tab) { | 118 chrome.tabs.get(tabId, function(tab) { |
| 116 if (!tab.url) | 119 if (!tab.url) |
| 117 return; | 120 return; |
| 118 | 121 |
| 119 var next = this.isWhitelisted_(tab.url); | 122 var next = this.isWhitelisted_(tab.url); |
| 120 this.toggleChromeVoxVersion({next: next, classic: !next}); | 123 this.toggleChromeVoxVersion({next: next, classic: !next}); |
| 121 }.bind(this)); | 124 }.bind(this)); |
| 122 }, | 125 }, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 new Output(this.currentRange_, prevRange, Output.EventType.NAVIGATE); | 235 new Output(this.currentRange_, prevRange, Output.EventType.NAVIGATE); |
| 233 } | 236 } |
| 234 }, | 237 }, |
| 235 | 238 |
| 236 /** | 239 /** |
| 237 * Provides all feedback once ChromeVox's focus changes. | 240 * Provides all feedback once ChromeVox's focus changes. |
| 238 * @param {Object} evt | 241 * @param {Object} evt |
| 239 */ | 242 */ |
| 240 onEventDefault: function(evt) { | 243 onEventDefault: function(evt) { |
| 241 var node = evt.target; | 244 var node = evt.target; |
| 245 |
| 242 if (!node) | 246 if (!node) |
| 243 return; | 247 return; |
| 244 | 248 |
| 245 var prevRange = this.currentRange_; | 249 var prevRange = this.currentRange_; |
| 246 this.currentRange_ = cursors.Range.fromNode(node); | 250 this.currentRange_ = cursors.Range.fromNode(node); |
| 251 |
| 252 // Don't process nodes inside of web content if ChromeVox Next is inactive. |
| 253 if (node.root.role != chrome.automation.RoleType.desktop && !this.active_) |
| 254 return; |
| 255 |
| 247 new Output(this.currentRange_, prevRange, evt.type); | 256 new Output(this.currentRange_, prevRange, evt.type); |
| 248 }, | 257 }, |
| 249 | 258 |
| 250 /** | 259 /** |
| 251 * Provides all feedback once a load complete event fires. | 260 * Provides all feedback once a load complete event fires. |
| 252 * @param {Object} evt | 261 * @param {Object} evt |
| 253 */ | 262 */ |
| 254 onLoadComplete: function(evt) { | 263 onLoadComplete: function(evt) { |
| 255 var node = AutomationUtil.findNodePost(evt.target, | 264 var node = AutomationUtil.findNodePost(evt.target, |
| 256 Dir.FORWARD, | 265 Dir.FORWARD, |
| 257 AutomationPredicate.leaf); | 266 AutomationPredicate.leaf); |
| 258 if (node) | 267 if (node) |
| 259 this.currentRange_ = cursors.Range.fromNode(node); | 268 this.currentRange_ = cursors.Range.fromNode(node); |
| 260 | 269 |
| 261 if (this.currentRange_) | 270 if (this.currentRange_) |
| 262 new Output(this.currentRange_, null, evt.type); | 271 new Output(this.currentRange_, null, evt.type); |
| 263 }, | 272 }, |
| 264 | 273 |
| 265 /** | 274 /** |
| 266 * Provides all feedback once a text selection change event fires. | 275 * Provides all feedback once a text selection change event fires. |
| 267 * @param {Object} evt | 276 * @param {Object} evt |
| 268 */ | 277 */ |
| 269 onTextSelectionChanged: function(evt) { | 278 onTextOrTextSelectionChanged: function(evt) { |
| 270 if (!this.currentRange_) | 279 if (!this.currentRange_) { |
| 280 if (!evt.target.state.focused) |
| 281 return; |
| 282 |
| 283 this.onEventDefault(evt); |
| 271 this.currentRange_ = cursors.Range.fromNode(evt.target); | 284 this.currentRange_ = cursors.Range.fromNode(evt.target); |
| 285 } |
| 272 | 286 |
| 273 var textChangeEvent = new cvox.TextChangeEvent( | 287 var textChangeEvent = new cvox.TextChangeEvent( |
| 274 evt.target.attributes.value, | 288 evt.target.attributes.value, |
| 275 evt.target.attributes.textSelStart, | 289 evt.target.attributes.textSelStart, |
| 276 evt.target.attributes.textSelEnd, | 290 evt.target.attributes.textSelEnd, |
| 277 true); // triggered by user | 291 true); // triggered by user |
| 278 if (!this.editableTextHandler || | 292 if (!this.editableTextHandler || |
| 279 evt.target != this.currentRange_.getStart().getNode()) { | 293 evt.target != this.currentRange_.getStart().getNode()) { |
| 280 this.editableTextHandler = | 294 this.editableTextHandler = |
| 281 new cvox.ChromeVoxEditableTextBase( | 295 new cvox.ChromeVoxEditableTextBase( |
| 282 textChangeEvent.value, | 296 textChangeEvent.value, |
| 283 textChangeEvent.start, | 297 textChangeEvent.start, |
| 284 textChangeEvent.end, | 298 textChangeEvent.end, |
| 285 evt.target.state['protected'], | 299 evt.target.state['protected'], |
| 286 cvox.ChromeVox.tts); | 300 cvox.ChromeVox.tts); |
| 287 } | 301 } |
| 288 | 302 |
| 289 this.editableTextHandler.changed(textChangeEvent); | 303 this.editableTextHandler.changed(textChangeEvent); |
| 304 new Output(this.currentRange_, null, evt.type, {braille: true}); |
| 290 }, | 305 }, |
| 291 | 306 |
| 292 /** | 307 /** |
| 293 * @private | 308 * @private |
| 294 * @param {string} url | 309 * @param {string} url |
| 295 * @return {boolean} Whether the given |url| is whitelisted. | 310 * @return {boolean} Whether the given |url| is whitelisted. |
| 296 */ | 311 */ |
| 297 isWhitelisted_: function(url) { | 312 isWhitelisted_: function(url) { |
| 298 return this.whitelist_.some(function(item) { | 313 return this.whitelist_.some(function(item) { |
| 299 return url.indexOf(item) != -1; | 314 return url.indexOf(item) != -1; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 316 * @param {{classic: boolean, next: boolean}=} opt_options Forceably set. | 331 * @param {{classic: boolean, next: boolean}=} opt_options Forceably set. |
| 317 */ | 332 */ |
| 318 toggleChromeVoxVersion: function(opt_options) { | 333 toggleChromeVoxVersion: function(opt_options) { |
| 319 if (!opt_options) { | 334 if (!opt_options) { |
| 320 opt_options = {}; | 335 opt_options = {}; |
| 321 opt_options.next = !this.active_; | 336 opt_options.next = !this.active_; |
| 322 opt_options.classic = !opt_options.next; | 337 opt_options.classic = !opt_options.next; |
| 323 } | 338 } |
| 324 | 339 |
| 325 if (opt_options.next) { | 340 if (opt_options.next) { |
| 341 if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) |
| 342 chrome.commands.onCommand.addListener(this.onGotCommand); |
| 343 |
| 326 chrome.automation.getTree(this.onGotTree); | 344 chrome.automation.getTree(this.onGotTree); |
| 327 this.active_ = true; | 345 this.active_ = true; |
| 328 } else { | 346 } else { |
| 347 if (chrome.commands.onCommand.hasListener(this.onGotCommand)) |
| 348 chrome.commands.onCommand.removeListener(this.onGotCommand); |
| 349 |
| 329 if (this.active_) { | 350 if (this.active_) { |
| 330 for (var eventType in this.listeners_) { | 351 for (var eventType in this.listeners_) { |
| 331 this.currentRange_.getStart().getNode().root.removeEventListener( | 352 this.currentRange_.getStart().getNode().root.removeEventListener( |
| 332 eventType, this.listeners_[eventType], true); | 353 eventType, this.listeners_[eventType], true); |
| 333 } | 354 } |
| 334 } | 355 } |
| 335 this.active_ = false; | 356 this.active_ = false; |
| 336 } | 357 } |
| 337 | 358 |
| 338 chrome.tabs.query({active: true}, function(tabs) { | 359 chrome.tabs.query({active: true}, function(tabs) { |
| 339 if (opt_options.classic) { | 360 if (opt_options.classic) { |
| 340 cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); | 361 cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); |
| 341 } else { | 362 } else { |
| 342 tabs.forEach(function(tab) { | 363 tabs.forEach(function(tab) { |
| 343 this.disableClassicChromeVox_(tab.id); | 364 this.disableClassicChromeVox_(tab.id); |
| 344 }.bind(this)); | 365 }.bind(this)); |
| 345 } | 366 } |
| 346 }.bind(this)); | 367 }.bind(this)); |
| 347 } | 368 } |
| 348 }; | 369 }; |
| 349 | 370 |
| 350 /** @type {Background} */ | 371 /** @type {Background} */ |
| 351 global.backgroundObj = new Background(); | 372 global.backgroundObj = new Background(); |
| 352 | 373 |
| 353 }); // goog.scope | 374 }); // goog.scope |
| OLD | NEW |