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 Script that runs on the background page. | 6 * @fileoverview Script that runs on the background page. |
7 * | 7 * |
8 */ | 8 */ |
9 | 9 |
10 goog.provide('cvox.ChromeVoxBackground'); | 10 goog.provide('cvox.ChromeVoxBackground'); |
(...skipping 11 matching lines...) Expand all Loading... |
22 goog.require('cvox.ExtensionBridge'); | 22 goog.require('cvox.ExtensionBridge'); |
23 goog.require('cvox.HostFactory'); | 23 goog.require('cvox.HostFactory'); |
24 goog.require('cvox.InjectedScriptLoader'); | 24 goog.require('cvox.InjectedScriptLoader'); |
25 goog.require('cvox.Msgs'); | 25 goog.require('cvox.Msgs'); |
26 goog.require('cvox.NavBraille'); | 26 goog.require('cvox.NavBraille'); |
27 // TODO(dtseng): This is required to prevent Closure from stripping our export | 27 // TODO(dtseng): This is required to prevent Closure from stripping our export |
28 // prefs on window. | 28 // prefs on window. |
29 goog.require('cvox.OptionsPage'); | 29 goog.require('cvox.OptionsPage'); |
30 goog.require('cvox.PlatformFilter'); | 30 goog.require('cvox.PlatformFilter'); |
31 goog.require('cvox.PlatformUtil'); | 31 goog.require('cvox.PlatformUtil'); |
| 32 goog.require('cvox.QueueMode'); |
32 goog.require('cvox.TabsApiHandler'); | 33 goog.require('cvox.TabsApiHandler'); |
33 goog.require('cvox.TtsBackground'); | 34 goog.require('cvox.TtsBackground'); |
34 | 35 |
35 | 36 |
36 /** | 37 /** |
37 * This object manages the global and persistent state for ChromeVox. | 38 * This object manages the global and persistent state for ChromeVox. |
38 * It listens for messages from the content scripts on pages and | 39 * It listens for messages from the content scripts on pages and |
39 * interprets them. | 40 * interprets them. |
40 * @constructor | 41 * @constructor |
41 */ | 42 */ |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 for (var i = 0; i < windows.length; i++) { | 134 for (var i = 0; i < windows.length; i++) { |
134 var tabs = windows[i].tabs; | 135 var tabs = windows[i].tabs; |
135 self.injectChromeVoxIntoTabs(tabs); | 136 self.injectChromeVoxIntoTabs(tabs); |
136 } | 137 } |
137 }); | 138 }); |
138 }, this)); | 139 }, this)); |
139 } | 140 } |
140 | 141 |
141 if (localStorage['active'] == 'false') { | 142 if (localStorage['active'] == 'false') { |
142 // Warn the user when the browser first starts if ChromeVox is inactive. | 143 // Warn the user when the browser first starts if ChromeVox is inactive. |
143 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive'), 1); | 144 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive'), |
| 145 cvox.QueueMode.QUEUE); |
144 } else if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) { | 146 } else if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) { |
145 // Introductory message. | 147 // Introductory message. |
146 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), 1); | 148 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), |
| 149 cvox.QueueMode.QUEUE); |
147 cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( | 150 cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( |
148 cvox.ChromeVox.msgs.getMsg('intro_brl'))); | 151 cvox.ChromeVox.msgs.getMsg('intro_brl'))); |
149 } | 152 } |
150 }; | 153 }; |
151 | 154 |
152 | 155 |
153 /** | 156 /** |
154 * Inject ChromeVox into a tab. | 157 * Inject ChromeVox into a tab. |
155 * @param {Array.<Tab>} tabs The tab where ChromeVox scripts should be injected. | 158 * @param {Array.<Tab>} tabs The tab where ChromeVox scripts should be injected. |
156 * @param {boolean=} opt_forceCompiled forces compiled ChromeVox to be injected; | 159 * @param {boolean=} opt_forceCompiled forces compiled ChromeVox to be injected; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 goog.bind(function() { | 192 goog.bind(function() { |
190 if (!chrome.extension.lastError) { | 193 if (!chrome.extension.lastError) { |
191 return; | 194 return; |
192 } | 195 } |
193 if (sawError) { | 196 if (sawError) { |
194 return; | 197 return; |
195 } | 198 } |
196 sawError = true; | 199 sawError = true; |
197 console.error('Could not inject into tab', tab); | 200 console.error('Could not inject into tab', tab); |
198 this.tts.speak('Error starting ChromeVox for ' + | 201 this.tts.speak('Error starting ChromeVox for ' + |
199 tab.title + ', ' + tab.url, 1); | 202 tab.title + ', ' + tab.url, cvox.QueueMode.QUEUE); |
200 }, this)); | 203 }, this)); |
201 }, this); | 204 }, this); |
202 | 205 |
203 // There is a scenario where two copies of the content script can get | 206 // There is a scenario where two copies of the content script can get |
204 // loaded into the same tab on browser startup - one automatically and one | 207 // loaded into the same tab on browser startup - one automatically and one |
205 // because the background page injects the content script into every tab | 208 // because the background page injects the content script into every tab |
206 // on startup. To work around potential bugs resulting from this, | 209 // on startup. To work around potential bugs resulting from this, |
207 // ChromeVox exports a global function called disableChromeVox() that can | 210 // ChromeVox exports a global function called disableChromeVox() that can |
208 // be used here to disable any existing running instance before we inject | 211 // be used here to disable any existing running instance before we inject |
209 // a new instance of the content script into this tab. | 212 // a new instance of the content script into this tab. |
(...skipping 20 matching lines...) Expand all Loading... |
230 | 233 |
231 /** | 234 /** |
232 * Called when a TTS message is received from a page content script. | 235 * Called when a TTS message is received from a page content script. |
233 * @param {Object} msg The TTS message. | 236 * @param {Object} msg The TTS message. |
234 */ | 237 */ |
235 cvox.ChromeVoxBackground.prototype.onTtsMessage = function(msg) { | 238 cvox.ChromeVoxBackground.prototype.onTtsMessage = function(msg) { |
236 if (msg['action'] == 'speak') { | 239 if (msg['action'] == 'speak') { |
237 // Tell the handler for native UI (chrome of chrome) events that | 240 // Tell the handler for native UI (chrome of chrome) events that |
238 // the last speech came from web, and not from native UI. | 241 // the last speech came from web, and not from native UI. |
239 this.accessibilityApiHandler_.setWebContext(); | 242 this.accessibilityApiHandler_.setWebContext(); |
240 this.tts.speak(msg['text'], msg['queueMode'], msg['properties']); | 243 this.tts.speak(msg['text'], |
| 244 /** cvox.QueueMode */msg['queueMode'], |
| 245 msg['properties']); |
241 } else if (msg['action'] == 'stop') { | 246 } else if (msg['action'] == 'stop') { |
242 this.tts.stop(); | 247 this.tts.stop(); |
243 } else if (msg['action'] == 'increaseOrDecrease') { | 248 } else if (msg['action'] == 'increaseOrDecrease') { |
244 this.tts.increaseOrDecreaseProperty(msg['property'], msg['increase']); | 249 this.tts.increaseOrDecreaseProperty(msg['property'], msg['increase']); |
245 var property = msg['property']; | 250 var property = msg['property']; |
246 var engine = this.backgroundTts_; | 251 var engine = this.backgroundTts_; |
247 var valueAsPercent = Math.round( | 252 var valueAsPercent = Math.round( |
248 this.backgroundTts_.propertyToPercentage(property) * 100); | 253 this.backgroundTts_.propertyToPercentage(property) * 100); |
249 var announcement; | 254 var announcement; |
250 switch (msg['property']) { | 255 switch (msg['property']) { |
251 case cvox.AbstractTts.RATE: | 256 case cvox.AbstractTts.RATE: |
252 announcement = cvox.ChromeVox.msgs.getMsg('announce_rate', | 257 announcement = cvox.ChromeVox.msgs.getMsg('announce_rate', |
253 [valueAsPercent]); | 258 [valueAsPercent]); |
254 break; | 259 break; |
255 case cvox.AbstractTts.PITCH: | 260 case cvox.AbstractTts.PITCH: |
256 announcement = cvox.ChromeVox.msgs.getMsg('announce_pitch', | 261 announcement = cvox.ChromeVox.msgs.getMsg('announce_pitch', |
257 [valueAsPercent]); | 262 [valueAsPercent]); |
258 break; | 263 break; |
259 case cvox.AbstractTts.VOLUME: | 264 case cvox.AbstractTts.VOLUME: |
260 announcement = cvox.ChromeVox.msgs.getMsg('announce_volume', | 265 announcement = cvox.ChromeVox.msgs.getMsg('announce_volume', |
261 [valueAsPercent]); | 266 [valueAsPercent]); |
262 break; | 267 break; |
263 } | 268 } |
264 if (announcement) { | 269 if (announcement) { |
265 this.tts.speak(announcement, | 270 this.tts.speak(announcement, |
266 cvox.AbstractTts.QUEUE_MODE_FLUSH, | 271 cvox.QueueMode.FLUSH, |
267 cvox.AbstractTts.PERSONALITY_ANNOTATION); | 272 cvox.AbstractTts.PERSONALITY_ANNOTATION); |
268 } | 273 } |
269 } else if (msg['action'] == 'cyclePunctuationEcho') { | 274 } else if (msg['action'] == 'cyclePunctuationEcho') { |
270 this.tts.speak(cvox.ChromeVox.msgs.getMsg( | 275 this.tts.speak(cvox.ChromeVox.msgs.getMsg( |
271 this.backgroundTts_.cyclePunctuationEcho()), | 276 this.backgroundTts_.cyclePunctuationEcho()), |
272 cvox.AbstractTts.QUEUE_MODE_FLUSH); | 277 cvox.QueueMode.FLUSH); |
273 } | 278 } |
274 }; | 279 }; |
275 | 280 |
276 | 281 |
277 /** | 282 /** |
278 * Called when an earcon message is received from a page content script. | 283 * Called when an earcon message is received from a page content script. |
279 * @param {Object} msg The earcon message. | 284 * @param {Object} msg The earcon message. |
280 */ | 285 */ |
281 cvox.ChromeVoxBackground.prototype.onEarconMessage = function(msg) { | 286 cvox.ChromeVoxBackground.prototype.onEarconMessage = function(msg) { |
282 if (msg.action == 'play') { | 287 if (msg.action == 'play') { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 }); | 337 }); |
333 } | 338 } |
334 break; | 339 break; |
335 case 'Prefs': | 340 case 'Prefs': |
336 if (action == 'getPrefs') { | 341 if (action == 'getPrefs') { |
337 this.prefs.sendPrefsToPort(port); | 342 this.prefs.sendPrefsToPort(port); |
338 } else if (action == 'setPref') { | 343 } else if (action == 'setPref') { |
339 if (msg['pref'] == 'active' && | 344 if (msg['pref'] == 'active' && |
340 msg['value'] != cvox.ChromeVox.isActive) { | 345 msg['value'] != cvox.ChromeVox.isActive) { |
341 if (cvox.ChromeVox.isActive) { | 346 if (cvox.ChromeVox.isActive) { |
342 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive')); | 347 this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive'), |
| 348 cvox.QueueMode.FLUSH); |
343 chrome.accessibilityPrivate.setNativeAccessibilityEnabled( | 349 chrome.accessibilityPrivate.setNativeAccessibilityEnabled( |
344 true); | 350 true); |
345 } else { | 351 } else { |
346 chrome.accessibilityPrivate.setNativeAccessibilityEnabled( | 352 chrome.accessibilityPrivate.setNativeAccessibilityEnabled( |
347 false); | 353 false); |
348 } | 354 } |
349 } else if (msg['pref'] == 'earcons') { | 355 } else if (msg['pref'] == 'earcons') { |
350 this.earcons.enabled = msg['value']; | 356 this.earcons.enabled = msg['value']; |
351 } else if (msg['pref'] == 'sticky' && msg['announce']) { | 357 } else if (msg['pref'] == 'sticky' && msg['announce']) { |
352 if (msg['value']) { | 358 if (msg['value']) { |
353 this.tts.speak(cvox.ChromeVox.msgs.getMsg('sticky_mode_enabled')); | 359 this.tts.speak(cvox.ChromeVox.msgs.getMsg('sticky_mode_enabled'), |
| 360 cvox.QueueMode.QUEUE); |
354 } else { | 361 } else { |
355 this.tts.speak( | 362 this.tts.speak( |
356 cvox.ChromeVox.msgs.getMsg('sticky_mode_disabled')); | 363 cvox.ChromeVox.msgs.getMsg('sticky_mode_disabled'), |
| 364 cvox.QueueMode.QUEUE); |
357 } | 365 } |
358 } else if (msg['pref'] == 'typingEcho' && msg['announce']) { | 366 } else if (msg['pref'] == 'typingEcho' && msg['announce']) { |
359 var announce = ''; | 367 var announce = ''; |
360 switch (msg['value']) { | 368 switch (msg['value']) { |
361 case cvox.TypingEcho.CHARACTER: | 369 case cvox.TypingEcho.CHARACTER: |
362 announce = cvox.ChromeVox.msgs.getMsg('character_echo'); | 370 announce = cvox.ChromeVox.msgs.getMsg('character_echo'); |
363 break; | 371 break; |
364 case cvox.TypingEcho.WORD: | 372 case cvox.TypingEcho.WORD: |
365 announce = cvox.ChromeVox.msgs.getMsg('word_echo'); | 373 announce = cvox.ChromeVox.msgs.getMsg('word_echo'); |
366 break; | 374 break; |
367 case cvox.TypingEcho.CHARACTER_AND_WORD: | 375 case cvox.TypingEcho.CHARACTER_AND_WORD: |
368 announce = cvox.ChromeVox.msgs.getMsg('character_and_word_echo'); | 376 announce = cvox.ChromeVox.msgs.getMsg('character_and_word_echo'); |
369 break; | 377 break; |
370 case cvox.TypingEcho.NONE: | 378 case cvox.TypingEcho.NONE: |
371 announce = cvox.ChromeVox.msgs.getMsg('none_echo'); | 379 announce = cvox.ChromeVox.msgs.getMsg('none_echo'); |
372 break; | 380 break; |
373 default: | 381 default: |
374 break; | 382 break; |
375 } | 383 } |
376 if (announce) { | 384 if (announce) { |
377 this.tts.speak(announce); | 385 this.tts.speak(announce, cvox.QueueMode.QUEUE); |
378 } | 386 } |
379 } else if (msg['pref'] == 'brailleCaptions') { | 387 } else if (msg['pref'] == 'brailleCaptions') { |
380 cvox.BrailleCaptionsBackground.setActive(msg['value']); | 388 cvox.BrailleCaptionsBackground.setActive(msg['value']); |
381 } | 389 } |
382 this.prefs.setPref(msg['pref'], msg['value']); | 390 this.prefs.setPref(msg['pref'], msg['value']); |
383 this.readPrefs(); | 391 this.readPrefs(); |
384 } | 392 } |
385 break; | 393 break; |
386 case 'Math': | 394 case 'Math': |
387 // TODO (sorge): Put the change of styles etc. here! | 395 // TODO (sorge): Put the change of styles etc. here! |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 * Handles the onChromeVoxLoadStateChanged event. | 529 * Handles the onChromeVoxLoadStateChanged event. |
522 * @param {boolean} loading True if ChromeVox is loading; false if it is | 530 * @param {boolean} loading True if ChromeVox is loading; false if it is |
523 * unloading. | 531 * unloading. |
524 * @param {boolean} makeAnnouncements True if announcements should be made. | 532 * @param {boolean} makeAnnouncements True if announcements should be made. |
525 */ | 533 */ |
526 cvox.ChromeVoxBackground.prototype.onLoadStateChanged = function( | 534 cvox.ChromeVoxBackground.prototype.onLoadStateChanged = function( |
527 loading, makeAnnouncements) { | 535 loading, makeAnnouncements) { |
528 if (loading) { | 536 if (loading) { |
529 if (makeAnnouncements) { | 537 if (makeAnnouncements) { |
530 cvox.ChromeVox.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), | 538 cvox.ChromeVox.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), |
531 1, | 539 cvox.QueueMode.QUEUE, |
532 {doNotInterrupt: true}); | 540 {doNotInterrupt: true}); |
533 cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( | 541 cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( |
534 cvox.ChromeVox.msgs.getMsg('intro_brl'))); | 542 cvox.ChromeVox.msgs.getMsg('intro_brl'))); |
535 } | 543 } |
536 } | 544 } |
537 }; | 545 }; |
538 | 546 |
539 | 547 |
540 // Create the background page object and export a function window['speak'] | 548 // Create the background page object and export a function window['speak'] |
541 // so that other background pages can access it. Also export the prefs object | 549 // so that other background pages can access it. Also export the prefs object |
542 // for access by the options page. | 550 // for access by the options page. |
543 (function() { | 551 (function() { |
544 var background = new cvox.ChromeVoxBackground(); | 552 var background = new cvox.ChromeVoxBackground(); |
545 background.init(); | 553 background.init(); |
546 window['speak'] = goog.bind(background.tts.speak, background.tts); | 554 window['speak'] = goog.bind(background.tts.speak, background.tts); |
547 | 555 |
548 // Export the prefs object for access by the options page. | 556 // Export the prefs object for access by the options page. |
549 window['prefs'] = background.prefs; | 557 window['prefs'] = background.prefs; |
550 | 558 |
551 // Export the braille object for access by the options page. | 559 // Export the braille object for access by the options page. |
552 window['braille'] = cvox.ChromeVox.braille; | 560 window['braille'] = cvox.ChromeVox.braille; |
553 | 561 |
554 // Export this background page for ChromeVox Next to access. | 562 // Export this background page for ChromeVox Next to access. |
555 cvox.ChromeVox.background = background; | 563 cvox.ChromeVox.background = background; |
556 })(); | 564 })(); |
OLD | NEW |