• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
10base.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