Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2012 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 'use strict';
      6 
      7 /**
      8  * @fileoverview Provides the Settings class.
      9  */
     10 base.exportTo('base', function() {
     11   var alternativeStorageInstance = undefined;
     12 
     13   /**
     14    * Settings is a simple wrapper around local storage, to make it easier
     15    * to test classes that have settings.
     16    *
     17    * @constructor
     18    */
     19   function Settings() {
     20     if (alternativeStorageInstance) {
     21       this.storage_ = alternativeStorageInstance;
     22     } else if ('G_testRunner' in global) {
     23       /**
     24        * In unit tests, use a mock object for storage so we don't change
     25        * localStorage in tests.
     26        */
     27       this.storage_ = new FakeLocalStorage();
     28     } else {
     29       this.storage_ = localStorage;
     30     }
     31   }
     32 
     33   Settings.setAlternativeStorageInstance = function(instance) {
     34     alternativeStorageInstance = instance;
     35   }
     36 
     37   Settings.prototype = {
     38 
     39     /**
     40      * Get the setting with the given name.
     41      *
     42      * @param {string} key The name of the setting.
     43      * @param {string} opt_default The default value to return if not set.
     44      * @param {string} opt_namespace If set, the setting name will be prefixed
     45      * with this namespace, e.g. "categories.settingName". This is useful for
     46      * a set of related settings.
     47      */
     48     get: function(key, opt_default, opt_namespace) {
     49       key = this.namespace_(key, opt_namespace);
     50       var val = this.storage_.getItem(key);
     51       if (val === null || val === undefined)
     52         return opt_default;
     53       return String(val);
     54     },
     55 
     56     /**
     57      * Set the setting with the given name to the given value.
     58      *
     59      * @param {string} key The name of the setting.
     60      * @param {string} value The value of the setting.
     61      * @param {string} opt_namespace If set, the setting name will be prefixed
     62      * with this namespace, e.g. "categories.settingName". This is useful for
     63      * a set of related settings.
     64      */
     65     set: function(key, value, opt_namespace) {
     66       this.storage_.setItem(this.namespace_(key, opt_namespace), String(value));
     67     },
     68 
     69     /**
     70      * Return a list of all the keys, or all the keys in the given namespace
     71      * if one is provided.
     72      *
     73      * @param {string} opt_namespace If set, only return settings which
     74      * begin with this prefix.
     75      */
     76     keys: function(opt_namespace) {
     77       var result = [];
     78       opt_namespace = opt_namespace || '';
     79       for (var i = 0; i < this.storage_.length; i++) {
     80         var key = this.storage_.key(i);
     81         if (this.isnamespaced_(key, opt_namespace))
     82           result.push(this.unnamespace_(key, opt_namespace));
     83       }
     84       return result;
     85     },
     86 
     87     isnamespaced_: function(key, opt_namespace) {
     88       return key.indexOf(this.normalize_(opt_namespace)) == 0;
     89     },
     90 
     91     namespace_: function(key, opt_namespace) {
     92       return this.normalize_(opt_namespace) + key;
     93     },
     94 
     95     unnamespace_: function(key, opt_namespace) {
     96       return key.replace(this.normalize_(opt_namespace), '');
     97     },
     98 
     99     /**
    100      * All settings are prefixed with a global namespace to avoid collisions.
    101      * Settings may also be namespaced with an additional prefix passed into
    102      * the get, set, and keys methods in order to group related settings.
    103      * This method makes sure the two namespaces are always set properly.
    104      */
    105     normalize_: function(opt_namespace) {
    106       return Settings.NAMESPACE + (opt_namespace ? opt_namespace + '.' : '');
    107     }
    108   };
    109 
    110   Settings.NAMESPACE = 'trace-viewer';
    111 
    112   /**
    113    * Create a Fake localStorage object which just stores to a dictionary
    114    * instead of actually saving into localStorage. Only used in unit tests.
    115    * @constructor
    116    */
    117   function FakeLocalStorage() {
    118   }
    119 
    120   FakeLocalStorage.prototype = {
    121     __proto__: Object.prototype,
    122 
    123     getItem: function(key) {
    124       // LocalStorage returns null if the key isn't found, not undefined.
    125       if (this[key] === undefined || this[key] === null)
    126         return null;
    127       return this[key];
    128     },
    129 
    130     setItem: function(key, value) {
    131       this[key] = value;
    132     },
    133 
    134     key: function(i) {
    135       return Object.keys(this).sort()[i];
    136     },
    137     get length() {
    138       return Object.keys(this).length;
    139     }
    140   };
    141 
    142   return {
    143     Settings: Settings
    144   };
    145 });
    146