background.js revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @fileoverview Script that runs on the background page. 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.provide('cvox.ChromeVoxBackground'); 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.AbstractEarcons'); 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.AccessibilityApiHandler'); 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.BrailleBackground'); 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.BrailleCaptionsBackground'); 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeMsgs'); 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeVox'); 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeVoxEditableTextBase'); 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeVoxPrefs'); 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.CompositeTts'); 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ConsoleTts'); 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.EarconsBackground'); 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ExtensionBridge'); 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.HostFactory'); 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.InjectedScriptLoader'); 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.NavBraille'); 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(dtseng): This is required to prevent Closure from stripping our export 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// prefs on window. 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.OptionsPage'); 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.PlatformFilter'); 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.PlatformUtil'); 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.TtsBackground'); 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * This object manages the global and persistent state for ChromeVox. 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * It listens for messages from the content scripts on pages and 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * interprets them. 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground = function() { 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Initialize the background page: set up TTS and bridge listeners. 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.init = function() { 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // In the case of ChromeOS, only continue initialization if this instance of 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ChromeVox is as we expect. This prevents ChromeVox from the webstore from 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // running. 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.ChromeVox.isChromeOS && 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.i18n.getMessage('@@extension_id') != 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'mndnfokpggljbaajbnioimlmbfngpief') { 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs = cvox.HostFactory.getMsgs(); 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.prefs = new cvox.ChromeVoxPrefs(); 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.readPrefs(); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var consoleTts = cvox.ConsoleTts.getInstance(); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) consoleTts.setEnabled(true); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Chrome's actual TTS which knows and cares about pitch, volume, etc. 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {cvox.TtsBackground} 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.backgroundTts_ = new cvox.TtsBackground(); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {cvox.TtsInterface} 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts = new cvox.CompositeTts() 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .add(this.backgroundTts_) 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .add(consoleTts); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.earcons = new cvox.EarconsBackground(); 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.addBridgeListener(); 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * The actual Braille service. 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {cvox.BrailleBackground} 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.backgroundBraille_ = new cvox.BrailleBackground(); 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.accessibilityApiHandler_ = new cvox.AccessibilityApiHandler( 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts, this.backgroundBraille_, this.earcons); 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Export globals on cvox.ChromeVox. 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.tts = this.tts; 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.braille = this.backgroundBraille_; 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.earcons = this.earcons; 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(dtseng): Remove the second check on or after m33. 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.ChromeVox.isChromeOS && 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.accessibilityPrivate.onChromeVoxLoadStateChanged) { 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.accessibilityPrivate.onChromeVoxLoadStateChanged.addListener( 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.onLoadStateChanged); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var listOfFiles; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // These lists of files must match the content_scripts section in 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the manifest files. 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (COMPILED) { 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listOfFiles = ['chromeVoxChromePageScript.js']; 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listOfFiles = [ 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'closure/closure_preinit.js', 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'closure/base.js', 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'deps.js', 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'chromevox/injected/loader.js']; 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var self = this; 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var stageTwo = function(code) { 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Inject the content script into all running tabs. 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.windows.getAll({'populate': true}, function(windows) { 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var i = 0; i < windows.length; i++) { 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var tabs = windows[i].tabs; 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (var j = 0; j < tabs.length; j++) { 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var tab = tabs[j]; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) self.injectChromeVoxIntoTab(tab, listOfFiles, code); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.checkVersionNumber(); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Set up a message passing system for goog.provide() calls from 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // within the content scripts. 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.extension.onMessage.addListener( 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(request, sender, callback) { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (request['srcFile']) { 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var srcFile = request['srcFile']; 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.InjectedScriptLoader.fetchCode( 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [srcFile], 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(code) { 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback({'code': code[srcFile]}); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We use fetchCode instead of chrome.extensions.executeFile because 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // executeFile doesn't propagate the file name to the content script 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // which means that script is not visible in Dev Tools. 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.InjectedScriptLoader.fetchCode(listOfFiles, stageTwo); 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (localStorage['active'] == 'false') { 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Warn the user when the browser first starts if ChromeVox is inactive. 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive'), 1); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (cvox.PlatformUtil.matchesPlatform(cvox.PlatformFilter.WML)) { 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Introductory message. 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), 1); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs.getMsg('intro_brl'))); 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Inject ChromeVox into a tab. 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Tab} tab The tab where ChromeVox scripts should be injected. 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Array.<string>} files The files to load. 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Object.<string, string>} code The contents of the files. 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.injectChromeVoxIntoTab = 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) function(tab, files, code) { 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window.console.log('Injecting into ' + tab.id, tab); 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var sawError = false; 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * A helper function which executes code. 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {string} code The code to execute. 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var executeScript = goog.bind(function(code) { 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.executeScript( 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) tab.id, 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) {'code': code, 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'allFrames': true}, 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.bind(function() { 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!chrome.extension.lastError) { 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (sawError) { 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sawError = true; 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) console.error('Could not inject into tab', tab); 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak('Error starting ChromeVox for ' + 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) tab.title + ', ' + tab.url, 1); 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }, this)); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }, this); 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // There is a scenario where two copies of the content script can get 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // loaded into the same tab on browser startup - one automatically 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // and one because the background page injects the content script into 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // every tab on startup. To work around potential bugs resulting from this, 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ChromeVox exports a global function called disableChromeVox() that can 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // be used here to disable any existing running instance before we inject 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // a new instance of the content script into this tab. 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // It's harmless if there wasn't a copy of ChromeVox already running. 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Also, set some variables so that Closure deps work correctly and so 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // that ChromeVox knows not to announce feedback as if a page just loaded. 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) executeScript('try { window.disableChromeVox(); } catch(e) { }\n' + 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'window.INJECTED_AFTER_LOAD = true;\n' + 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'window.CLOSURE_NO_DEPS = true\n'); 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Now inject the ChromeVox content script code into the tab. 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) files.forEach(function(file) { executeScript(code[file]); }); 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Called when a TTS message is received from a page content script. 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Object} msg The TTS message. 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.onTtsMessage = function(msg) { 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['action'] == 'speak') { 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Tell the handler for native UI (chrome of chrome) events that 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the last speech came from web, and not from native UI. 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.accessibilityApiHandler_.setWebContext(); 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(msg['text'], msg['queueMode'], msg['properties']); 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['action'] == 'stop') { 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.stop(); 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['action'] == 'increaseOrDecrease') { 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.increaseOrDecreaseProperty(msg['property'], msg['increase']); 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var property = msg['property']; 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var engine = this.backgroundTts_; 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var valueAsPercent = Math.round( 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.backgroundTts_.propertyToPercentage(property) * 100); 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var announcement; 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (msg['property']) { 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.AbstractTts.RATE: 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announcement = cvox.ChromeVox.msgs.getMsg('announce_rate', 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [valueAsPercent]); 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.AbstractTts.PITCH: 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announcement = cvox.ChromeVox.msgs.getMsg('announce_pitch', 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [valueAsPercent]); 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.AbstractTts.VOLUME: 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announcement = cvox.ChromeVox.msgs.getMsg('announce_volume', 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) [valueAsPercent]); 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (announcement) { 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(announcement, 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.AbstractTts.QUEUE_MODE_FLUSH, 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.AbstractTts.PERSONALITY_ANNOTATION); 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['action'] == 'cyclePunctuationEcho') { 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(cvox.ChromeVox.msgs.getMsg( 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.backgroundTts_.cyclePunctuationEcho()), 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.AbstractTts.QUEUE_MODE_FLUSH); 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Called when an earcon message is received from a page content script. 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {Object} msg The earcon message. 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.onEarconMessage = function(msg) { 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg.action == 'play') { 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.earcons.playEarcon(msg.earcon); 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Listen for connections from our content script bridges, and dispatch the 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * messages to the proper destination. 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.addBridgeListener = function() { 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ExtensionBridge.addMessageListener(goog.bind(function(msg, port) { 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var target = msg['target']; 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var action = msg['action']; 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (target) { 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'OpenTab': 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var destination = new Object(); 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) destination.url = msg['url']; 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.create(destination); 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'KbExplorer': 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var explorerPage = new Object(); 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) explorerPage.url = 'chromevox/background/kbexplorer.html'; 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.create(explorerPage); 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'HelpDocs': 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var helpPage = new Object(); 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) helpPage.url = 'http://chromevox.com/tutorial/index.html'; 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.create(helpPage); 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'Options': 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (action == 'open') { 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var optionsPage = new Object(); 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) optionsPage.url = 'chromevox/background/options.html'; 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.create(optionsPage); 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'Data': 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (action == 'getHistory') { 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var results = {}; 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.history.search({text: '', maxResults: 25}, function(items) { 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) items.forEach(function(item) { 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (item.url) { 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) results[item.url] = true; 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) port.postMessage({ 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'history': results 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'Prefs': 326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (action == 'getPrefs') { 327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.prefs.sendPrefsToPort(port); 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (action == 'setPref') { 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['pref'] == 'active' && 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) msg['value'] != cvox.ChromeVox.isActive) { 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cvox.ChromeVox.isActive) { 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_inactive')); 333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.accessibilityPrivate.setNativeAccessibilityEnabled( 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true); 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.accessibilityPrivate.setNativeAccessibilityEnabled( 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) false); 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['pref'] == 'earcons') { 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.earcons.enabled = msg['value']; 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['pref'] == 'sticky' && msg['announce']) { 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['value']) { 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(cvox.ChromeVox.msgs.getMsg('sticky_mode_enabled')); 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak( 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs.getMsg('sticky_mode_disabled')); 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['pref'] == 'typingEcho' && msg['announce']) { 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var announce = ''; 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (msg['value']) { 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.TypingEcho.CHARACTER: 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announce = cvox.ChromeVox.msgs.getMsg('character_echo'); 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.TypingEcho.WORD: 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announce = cvox.ChromeVox.msgs.getMsg('word_echo'); 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.TypingEcho.CHARACTER_AND_WORD: 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announce = cvox.ChromeVox.msgs.getMsg('character_and_word_echo'); 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case cvox.TypingEcho.NONE: 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) announce = cvox.ChromeVox.msgs.getMsg('none_echo'); 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) default: 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (announce) { 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.tts.speak(announce); 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (msg['pref'] == 'brailleCaptions') { 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.BrailleCaptionsBackground.setActive(msg['value']); 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.prefs.setPref(msg['pref'], msg['value']); 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.readPrefs(); 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'Math': 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO (sorge): Put the change of styles etc. here! 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['action'] == 'getDomains') { 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) port.postMessage({'message': 'DOMAINS_STYLES', 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'domains': this.backgroundTts_.mathmap.allDomains, 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'styles': this.backgroundTts_.mathmap.allStyles}); 382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'TTS': 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['startCallbackId'] != undefined) { 386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) msg['properties']['startCallback'] = function() { 387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) port.postMessage({'message': 'TTS_CALLBACK', 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'id': msg['startCallbackId']}); 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['endCallbackId'] != undefined) { 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) msg['properties']['endCallback'] = function() { 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) port.postMessage({'message': 'TTS_CALLBACK', 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'id': msg['endCallbackId']}); 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try { 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.onTtsMessage(msg); 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } catch (err) { 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) console.log(err); 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'EARCON': 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.onEarconMessage(msg); 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case 'BRAILLE': 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) try { 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.backgroundBraille_.onBrailleMessage(msg); 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } catch (err) { 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) console.log(err); 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }, this)); 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks the version number. If it has changed, display release notes 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * to the user. 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.checkVersionNumber = function() { 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Don't update version or show release notes if the current tab is within an 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // incognito window (which may occur on ChromeOS immediately after OOBE). 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (this.isIncognito_()) { 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.localStorageVersion = localStorage['versionString']; 429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.showNotesIfNewVersion(); 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Display release notes to the user. 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.displayReleaseNotes = function() { 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.create( 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) {'url': 'http://chromevox.com/release_notes.html'}); 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Gets the current version number from the extension manifest. 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.showNotesIfNewVersion = function() { 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check version number in manifest. 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var url = chrome.extension.getURL('manifest.json'); 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var xhr = new XMLHttpRequest(); 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var context = this; 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) xhr.onreadystatechange = function() { 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (xhr.readyState == 4) { 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var manifest = JSON.parse(xhr.responseText); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) console.log('Version: ' + manifest.version); 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var shouldShowReleaseNotes = 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (context.localStorageVersion != manifest.version); 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // On Chrome OS, don't show the release notes the first time, only 459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // after a version upgrade. 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (navigator.userAgent.indexOf('CrOS') != -1 && 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context.localStorageVersion == undefined) { 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shouldShowReleaseNotes = false; 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (shouldShowReleaseNotes) { 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context.displayReleaseNotes(); 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Update version number in local storage 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) localStorage['versionString'] = manifest.version; 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.localStorageVersion = manifest.version; 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) xhr.open('GET', url); 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) xhr.send(); 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Read and apply preferences that affect the background context. 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.readPrefs = function() { 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var prefs = this.prefs.getPrefs(); 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVoxEditableTextBase.useIBeamCursor = 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (prefs['useIBeamCursor'] == 'true'); 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.isActive = 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (prefs['active'] == 'true' || cvox.ChromeVox.isChromeOS); 48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) cvox.ChromeVox.isStickyPrefOn = (prefs['sticky'] == 'true'); 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Checks if we are currently in an incognito window. 493cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @return {boolean} True if incognito or not within a tab context, false 494cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * otherwise. 495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.isIncognito_ = function() { 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var incognito = false; 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome.tabs.getCurrent(function(tab) { 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Tab is null if not called from a tab context. In that case, also consider 501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // it incognito. 502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) incognito = tab ? tab.incognito : true; 503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }); 504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return incognito; 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(dtseng): The loading param is no longer used. Remove it once the 509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// upstream Chrome API changes. 510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Handles the onChromeVoxLoadStateChanged event. 512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {boolean} loading True if ChromeVox is loading; false if it is 513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * unloading. 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {boolean} makeAnnouncements True if announcements should be made. 515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeVoxBackground.prototype.onLoadStateChanged = function( 517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) loading, makeAnnouncements) { 518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (loading) { 519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (makeAnnouncements) { 520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.tts.speak(cvox.ChromeVox.msgs.getMsg('chromevox_intro'), 521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1, 522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) {doNotInterrupt: true}); 523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.braille.write(cvox.NavBraille.fromText( 524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ChromeVox.msgs.getMsg('intro_brl'))); 525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Create the background page object and export a function window['speak'] 531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// so that other background pages can access it. Also export the prefs object 532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// for access by the options page. 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)(function() { 534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var background = new cvox.ChromeVoxBackground(); 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) background.init(); 536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window['speak'] = goog.bind(background.tts.speak, background.tts); 537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Export the prefs object for access by the options page. 539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window['prefs'] = background.prefs; 540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Export the braille object for access by the options page. 542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) window['braille'] = cvox.ChromeVox.braille; 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)})(); 544