prefs.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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
3// found in the LICENSE file.
4
5/**
6 * @fileoverview Common page for reading and writing preferences from
7 * the background context (background page or options page).
8 *
9 */
10
11goog.provide('cvox.ChromeVoxPrefs');
12
13goog.require('cvox.ChromeVox');
14goog.require('cvox.ExtensionBridge');
15goog.require('cvox.KeyMap');
16
17
18/**
19 * This object has default values of preferences and contains the common
20 * code for working with preferences shared by the Options and Background
21 * pages.
22 * @constructor
23 */
24cvox.ChromeVoxPrefs = function() {
25  var lastRunVersion = localStorage['lastRunVersion'];
26  if (!lastRunVersion) {
27    lastRunVersion = '1.16.0';
28  }
29  var loadExistingSettings = true;
30  // TODO(dtseng): Logic below needs clarification. Perhaps needs a
31  // 'lastIncompatibleVersion' member.
32  if (lastRunVersion == '1.16.0') {
33    loadExistingSettings = false;
34  }
35  localStorage['lastRunVersion'] = chrome.app.getDetails().version;
36
37  /**
38   * The current mapping from keys to command.
39   * @type {!cvox.KeyMap}
40   * @private
41   */
42  this.keyMap_ = cvox.KeyMap.fromLocalStorage() || cvox.KeyMap.fromDefaults();
43  this.keyMap_.merge(cvox.KeyMap.fromDefaults());
44
45  // Clear per session preferences.
46  // This is to keep the position dictionary from growing excessively large.
47  localStorage['position'] = '{}';
48
49  // Default per session sticky to off.
50  localStorage['sticky'] = false;
51
52  this.init(loadExistingSettings);
53};
54
55
56/**
57 * The default value of all preferences except the key map.
58 * @const
59 * @type {Object.<string, Object>}
60 */
61cvox.ChromeVoxPrefs.DEFAULT_PREFS = {
62  'active': true,
63  'brailleCaptions': false,
64  // TODO(dtseng): Leaking state about multiple key maps here until we have a
65  // class to manage multiple key maps. Also, this doesn't belong as a pref;
66  // should just store in local storage.
67  'currentKeyMap' : cvox.KeyMap.DEFAULT_KEYMAP,
68  'cvoxKey': '',
69  'earcons': true,
70  'focusFollowsMouse': false,
71  'granularity': undefined,
72  'position': '{}',
73  'siteSpecificScriptBase':
74      'https://ssl.gstatic.com/accessibility/javascript/ext/',
75  'siteSpecificScriptLoader':
76      'https://ssl.gstatic.com/accessibility/javascript/ext/loader.js',
77  'sticky': false,
78  'typingEcho': 0,
79  'useIBeamCursor': cvox.ChromeVox.isMac,
80  'useVerboseMode': true,
81  'siteSpecificEnhancements': true
82};
83
84
85/**
86 * Merge the default values of all known prefs with what's found in
87 * localStorage.
88 * @param {boolean} pullFromLocalStorage or not to pull prefs from local
89 * storage. True if we want to respect changes the user has already made
90 * to prefs, false if we want to overwrite them. Set false if we've made
91 * changes to keyboard shortcuts and need to make sure they aren't
92 * overridden by the old keymap in local storage.
93 */
94cvox.ChromeVoxPrefs.prototype.init = function(pullFromLocalStorage) {
95  // Set the default value of any pref that isn't already in localStorage.
96  for (var pref in cvox.ChromeVoxPrefs.DEFAULT_PREFS) {
97    if (localStorage[pref] === undefined) {
98      localStorage[pref] = cvox.ChromeVoxPrefs.DEFAULT_PREFS[pref];
99    }
100  }
101};
102
103/**
104 * Switches to another key map.
105 * @param {string} selectedKeyMap The id of the keymap in
106 * cvox.KeyMap.AVAIABLE_KEYMAP_INFO.
107*/
108cvox.ChromeVoxPrefs.prototype.switchToKeyMap = function(selectedKeyMap) {
109  // TODO(dtseng): Leaking state about multiple key maps here until we have a
110  // class to manage multiple key maps.
111  localStorage['currentKeyMap'] = selectedKeyMap;
112  this.keyMap_ = cvox.KeyMap.fromCurrentKeyMap();
113  this.keyMap_.toLocalStorage();
114  this.keyMap_.resetModifier();
115  this.sendPrefsToAllTabs(false, true);
116};
117
118
119/**
120 * Get the prefs (not including keys).
121 * @return {Object} A map of all prefs except the key map from localStorage.
122 */
123cvox.ChromeVoxPrefs.prototype.getPrefs = function() {
124  var prefs = {};
125  for (var pref in cvox.ChromeVoxPrefs.DEFAULT_PREFS) {
126    prefs[pref] = localStorage[pref];
127  }
128  prefs['version'] = chrome.app.getDetails().version;
129  return prefs;
130};
131
132
133/**
134 * Reloads the key map from local storage.
135 */
136cvox.ChromeVoxPrefs.prototype.reloadKeyMap = function() {
137  // Get the current key map from localStorage.
138  // TODO(dtseng): We currently don't support merges since we write the entire
139  // map back to local storage.
140  var currentKeyMap = cvox.KeyMap.fromLocalStorage();
141  if (!currentKeyMap) {
142    currentKeyMap = cvox.KeyMap.fromCurrentKeyMap();
143    currentKeyMap.toLocalStorage();
144  }
145  this.keyMap_ = currentKeyMap;
146};
147
148
149/**
150 * Get the key map, from key binding to an array of [command, description].
151 * @return {cvox.KeyMap} The key map.
152 */
153cvox.ChromeVoxPrefs.prototype.getKeyMap = function() {
154  return this.keyMap_;
155};
156
157
158/**
159 * Reset to the default key bindings.
160 */
161cvox.ChromeVoxPrefs.prototype.resetKeys = function() {
162  this.keyMap_ = cvox.KeyMap.fromDefaults();
163  this.keyMap_.toLocalStorage();
164  this.sendPrefsToAllTabs(false, true);
165};
166
167
168/**
169 * Send all of the settings to all tabs.
170 * @param {boolean} sendPrefs Whether to send the prefs.
171 * @param {boolean} sendKeyBindings Whether to send the key bindings.
172 */
173cvox.ChromeVoxPrefs.prototype.sendPrefsToAllTabs =
174    function(sendPrefs, sendKeyBindings) {
175  var context = this;
176  var message = {};
177  if (sendPrefs) {
178    message['prefs'] = context.getPrefs();
179  }
180  if (sendKeyBindings) {
181    // Note that cvox.KeyMap stringifies to a minimal object when message gets
182    // passed to the content script.
183    message['keyBindings'] = this.keyMap_.toJSON();
184  }
185  chrome.windows.getAll({populate: true}, function(windows) {
186    for (var i = 0; i < windows.length; i++) {
187      var tabs = windows[i].tabs;
188      for (var j = 0; j < tabs.length; j++) {
189        chrome.tabs.sendMessage(tabs[j].id, message);
190      }
191    }
192  });
193};
194
195/**
196 * Send all of the settings over the specified port.
197 * @param {Port} port The port representing the connection to a content script.
198 */
199cvox.ChromeVoxPrefs.prototype.sendPrefsToPort = function(port) {
200  port.postMessage({
201    'keyBindings': this.keyMap_.toJSON(),
202    'prefs': this.getPrefs()});
203};
204
205
206/**
207 * Set the value of a pref and update all active tabs if it's changed.
208 * @param {string} key The pref key.
209 * @param {Object|string} value The new value of the pref.
210 */
211cvox.ChromeVoxPrefs.prototype.setPref = function(key, value) {
212  if (localStorage[key] != value) {
213    localStorage[key] = value;
214    this.sendPrefsToAllTabs(true, false);
215  }
216};
217
218/**
219 * Delegates to cvox.KeyMap.
220 * @param {string} command The command to set.
221 * @param {cvox.KeySequence} newKey The new key to assign it to.
222 * @return {boolean} True if the key was bound to the command.
223 */
224cvox.ChromeVoxPrefs.prototype.setKey = function(command, newKey) {
225  if (this.keyMap_.rebind(command, newKey)) {
226    this.keyMap_.toLocalStorage();
227    this.sendPrefsToAllTabs(false, true);
228    return true;
229  }
230  return false;
231};
232