Home | History | Annotate | Download | only in background
      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 
     11 goog.provide('cvox.ChromeVoxPrefs');
     12 
     13 goog.require('cvox.ChromeVox');
     14 goog.require('cvox.ExtensionBridge');
     15 goog.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  */
     24 cvox.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  */
     61 cvox.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  */
     94 cvox.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 */
    108 cvox.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  */
    123 cvox.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  */
    136 cvox.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  */
    153 cvox.ChromeVoxPrefs.prototype.getKeyMap = function() {
    154   return this.keyMap_;
    155 };
    156 
    157 
    158 /**
    159  * Reset to the default key bindings.
    160  */
    161 cvox.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  */
    173 cvox.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  */
    199 cvox.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  */
    211 cvox.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  */
    224 cvox.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