Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js

Issue 908853004: Revert of Reland #2: Ensure WebView notifies desktop automation on creation, destruction, and change Original (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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');
19 20
20 goog.scope(function() { 21 goog.scope(function() {
21 var AutomationNode = chrome.automation.AutomationNode; 22 var AutomationNode = chrome.automation.AutomationNode;
22 var Dir = AutomationUtil.Dir; 23 var Dir = AutomationUtil.Dir;
23 var EventType = chrome.automation.EventType; 24 var EventType = chrome.automation.EventType;
24 25
25 /** 26 /**
26 * ChromeVox2 background page. 27 * ChromeVox2 background page.
27 * @constructor 28 * @constructor
28 */ 29 */
29 Background = function() { 30 Background = function() {
30 /** 31 /**
31 * A list of site substring patterns to use with ChromeVox next. Keep these 32 * A list of site substring patterns to use with ChromeVox next. Keep these
32 * strings relatively specific. 33 * strings relatively specific.
33 * @type {!Array.<string>} 34 * @type {!Array.<string>}
34 * @private 35 * @private
35 */ 36 */
36 this.whitelist_ = ['chromevox_next_test']; 37 this.whitelist_ = ['chromevox_next_test'];
37 38
38 /** 39 /**
40 * @type {cvox.TabsApiHandler}
41 * @private
42 */
43 this.tabsHandler_ = new cvox.TabsApiHandler(cvox.ChromeVox.tts,
44 cvox.ChromeVox.braille,
45 cvox.ChromeVox.earcons);
46
47 /**
39 * @type {cursors.Range} 48 * @type {cursors.Range}
40 * @private 49 * @private
41 */ 50 */
42 this.currentRange_ = null; 51 this.currentRange_ = null;
43 52
44 /** 53 /**
45 * Whether ChromeVox Next is active. 54 * Whether ChromeVox Next is active.
46 * @type {boolean} 55 * @type {boolean}
47 * @private 56 * @private
48 */ 57 */
(...skipping 17 matching lines...) Expand all
66 menuEnd: this.onEventDefault, 75 menuEnd: this.onEventDefault,
67 menuListValueChanged: this.onEventDefault, 76 menuListValueChanged: this.onEventDefault,
68 loadComplete: this.onLoadComplete, 77 loadComplete: this.onLoadComplete,
69 textChanged: this.onTextOrTextSelectionChanged, 78 textChanged: this.onTextOrTextSelectionChanged,
70 textSelectionChanged: this.onTextOrTextSelectionChanged, 79 textSelectionChanged: this.onTextOrTextSelectionChanged,
71 valueChanged: this.onEventDefault 80 valueChanged: this.onEventDefault
72 }; 81 };
73 82
74 // Register listeners for ... 83 // Register listeners for ...
75 // Desktop. 84 // Desktop.
76 chrome.automation.getDesktop(this.onGotDesktop); 85 chrome.automation.getDesktop(this.onGotTree);
86
87 // Tabs.
88 chrome.tabs.onUpdated.addListener(this.onTabUpdated);
77 }; 89 };
78 90
79 Background.prototype = { 91 Background.prototype = {
80 /** 92 /**
93 * Handles chrome.tabs.onUpdated.
94 * @param {number} tabId
95 * @param {Object} changeInfo
96 */
97 onTabUpdated: function(tabId, changeInfo) {
98 if (changeInfo.status != 'complete')
99 return;
100 chrome.tabs.get(tabId, function(tab) {
101 if (!tab.url)
102 return;
103
104 var next = this.isWhitelisted_(tab.url);
105
106 this.toggleChromeVoxVersion({next: next, classic: !next});
107 }.bind(this));
108 },
109
110 /**
81 * Handles all setup once a new automation tree appears. 111 * Handles all setup once a new automation tree appears.
82 * @param {chrome.automation.AutomationNode} desktop 112 * @param {chrome.automation.AutomationNode} root
83 */ 113 */
84 onGotDesktop: function(desktop) { 114 onGotTree: function(root) {
85 // Register all automation event listeners. 115 // Register all automation event listeners.
86 for (var eventType in this.listeners_) 116 for (var eventType in this.listeners_)
87 desktop.addEventListener(eventType, this.listeners_[eventType], true); 117 root.addEventListener(eventType, this.listeners_[eventType], true);
88 118
89 // The focused state gets set on the containing webView node. 119 if (root.attributes.docLoaded) {
90 var webView = desktop.find({role: chrome.automation.RoleType.webView, 120 this.onLoadComplete(
91 state: {focused: true}}); 121 {target: root, type: chrome.automation.EventType.loadComplete});
92 if (webView) {
93 var root = webView.find({role: chrome.automation.RoleType.rootWebArea});
94 if (root) {
95 this.onLoadComplete(
96 {target: root,
97 type: chrome.automation.EventType.loadComplete});
98 }
99 } 122 }
100 }, 123 },
101 124
102 /** 125 /**
103 * Handles chrome.commands.onCommand. 126 * Handles chrome.commands.onCommand.
104 * @param {string} command 127 * @param {string} command
105 */ 128 */
106 onGotCommand: function(command) { 129 onGotCommand: function(command) {
107 if (command == 'toggleChromeVoxVersion') { 130 if (command == 'toggleChromeVoxVersion') {
108 this.toggleChromeVoxVersion(); 131 this.toggleChromeVoxVersion();
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 new Output().withSpeechAndBraille( 263 new Output().withSpeechAndBraille(
241 this.currentRange_, prevRange, evt.type) 264 this.currentRange_, prevRange, evt.type)
242 .go(); 265 .go();
243 }, 266 },
244 267
245 /** 268 /**
246 * Provides all feedback once a load complete event fires. 269 * Provides all feedback once a load complete event fires.
247 * @param {Object} evt 270 * @param {Object} evt
248 */ 271 */
249 onLoadComplete: function(evt) { 272 onLoadComplete: function(evt) {
250 var next = this.isWhitelisted_(evt.target.attributes.url);
251 this.toggleChromeVoxVersion({next: next, classic: !next});
252 // Don't process nodes inside of web content if ChromeVox Next is inactive. 273 // Don't process nodes inside of web content if ChromeVox Next is inactive.
253 if (evt.target.root.role != chrome.automation.RoleType.desktop && 274 if (evt.target.root.role != chrome.automation.RoleType.desktop &&
254 !this.active_) 275 !this.active_)
255 return; 276 return;
256 277
257 if (this.currentRange_) 278 var node = AutomationUtil.findNodePost(evt.target,
258 return;
259
260 var root = evt.target;
261 var webView = root;
262 while (webView && webView.role != chrome.automation.RoleType.webView)
263 webView = webView.parent;
264
265 if (!webView || !webView.state.focused)
266 return;
267
268 var node = AutomationUtil.findNodePost(root,
269 Dir.FORWARD, 279 Dir.FORWARD,
270 AutomationPredicate.leaf); 280 AutomationPredicate.leaf);
271
272 if (node) 281 if (node)
273 this.currentRange_ = cursors.Range.fromNode(node); 282 this.currentRange_ = cursors.Range.fromNode(node);
274 283
275 if (this.currentRange_) 284 if (this.currentRange_)
276 new Output().withSpeechAndBraille( 285 new Output().withSpeechAndBraille(
277 this.currentRange_, null, evt.type) 286 this.currentRange_, null, evt.type)
278 .go(); 287 .go();
279 }, 288 },
280 289
281 /** 290 /**
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 */ 355 */
347 toggleChromeVoxVersion: function(opt_options) { 356 toggleChromeVoxVersion: function(opt_options) {
348 if (!opt_options) { 357 if (!opt_options) {
349 opt_options = {}; 358 opt_options = {};
350 opt_options.next = !this.active_; 359 opt_options.next = !this.active_;
351 opt_options.classic = !opt_options.next; 360 opt_options.classic = !opt_options.next;
352 } 361 }
353 362
354 if (opt_options.next) { 363 if (opt_options.next) {
355 if (!chrome.commands.onCommand.hasListener(this.onGotCommand)) 364 if (!chrome.commands.onCommand.hasListener(this.onGotCommand))
356 chrome.commands.onCommand.addListener(this.onGotCommand); 365 chrome.commands.onCommand.addListener(this.onGotCommand);
357 this.active_ = true; 366
367 if (!this.active_)
368 chrome.automation.getTree(this.onGotTree);
369 this.active_ = true;
358 } else { 370 } else {
359 if (chrome.commands.onCommand.hasListener(this.onGotCommand)) 371 if (chrome.commands.onCommand.hasListener(this.onGotCommand))
360 chrome.commands.onCommand.removeListener(this.onGotCommand); 372 chrome.commands.onCommand.removeListener(this.onGotCommand);
373
374 if (this.active_) {
375 for (var eventType in this.listeners_) {
376 this.currentRange_.getStart().getNode().root.removeEventListener(
377 eventType, this.listeners_[eventType], true);
378 }
379 }
361 this.active_ = false; 380 this.active_ = false;
362 } 381 }
363 382
364 chrome.tabs.query({active: true}, function(tabs) { 383 chrome.tabs.query({active: true}, function(tabs) {
365 if (opt_options.classic) { 384 if (opt_options.classic) {
366 // This case should do nothing because Classic gets injected by the 385 // This case should do nothing because Classic gets injected by the
367 // extension system via our manifest. Once ChromeVox Next is enabled 386 // extension system via our manifest. Once ChromeVox Next is enabled
368 // for tabs, re-enable. 387 // for tabs, re-enable.
369 // cvox.ChromeVox.injectChromeVoxIntoTabs(tabs); 388 // cvox.ChromeVox.injectChromeVoxIntoTabs(tabs);
370 } else { 389 } else {
371 tabs.forEach(function(tab) { 390 tabs.forEach(function(tab) {
372 this.disableClassicChromeVox_(tab.id); 391 this.disableClassicChromeVox_(tab.id);
373 }.bind(this)); 392 }.bind(this));
374 } 393 }
375 }.bind(this)); 394 }.bind(this));
376 } 395 }
377 }; 396 };
378 397
379 /** @type {Background} */ 398 /** @type {Background} */
380 global.backgroundObj = new Background(); 399 global.backgroundObj = new Background();
381 400
382 }); // goog.scope 401 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698