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 object. 9 */ 10 base.exportTo('base', function() { 11 var storage_ = localStorage; 12 13 /** 14 * Settings is a simple wrapper around local storage, to make it easier 15 * to test classes that have settings. 16 * 17 * May be called as new base.Settings() or simply base.Settings() 18 * @constructor 19 */ 20 function Settings() { 21 return Settings; 22 }; 23 24 /** 25 * Get the setting with the given name. 26 * 27 * @param {string} key The name of the setting. 28 * @param {string=} opt_default The default value to return if not set. 29 * @param {string=} opt_namespace If set, the setting name will be prefixed 30 * with this namespace, e.g. "categories.settingName". This is useful for 31 * a set of related settings. 32 */ 33 Settings.get = function(key, opt_default, opt_namespace) { 34 key = Settings.namespace_(key, opt_namespace); 35 var rawVal = storage_.getItem(key); 36 if (rawVal === null || rawVal === undefined) 37 return opt_default; 38 39 // Old settings versions used to stringify objects instead of putting them 40 // into JSON. If those are encountered, parse will fail. In that case, 41 // "upgrade" the setting to the default value. 42 try { 43 return JSON.parse(rawVal).value; 44 } catch (e) { 45 storage_.removeItem(Settings.namespace_(key, opt_namespace)); 46 return opt_default; 47 } 48 }, 49 50 /** 51 * Set the setting with the given name to the given value. 52 * 53 * @param {string} key The name of the setting. 54 * @param {string} value The value of the setting. 55 * @param {string=} opt_namespace If set, the setting name will be prefixed 56 * with this namespace, e.g. "categories.settingName". This is useful for 57 * a set of related settings. 58 */ 59 Settings.set = function(key, value, opt_namespace) { 60 if (value === undefined) 61 throw new Error('Settings.set: value must not be undefined'); 62 var v = JSON.stringify({value: value}); 63 storage_.setItem(Settings.namespace_(key, opt_namespace), v); 64 }, 65 66 /** 67 * Return a list of all the keys, or all the keys in the given namespace 68 * if one is provided. 69 * 70 * @param {string=} opt_namespace If set, only return settings which 71 * begin with this prefix. 72 */ 73 Settings.keys = function(opt_namespace) { 74 var result = []; 75 opt_namespace = opt_namespace || ''; 76 for (var i = 0; i < storage_.length; i++) { 77 var key = storage_.key(i); 78 if (Settings.isnamespaced_(key, opt_namespace)) 79 result.push(Settings.unnamespace_(key, opt_namespace)); 80 } 81 return result; 82 }, 83 84 Settings.isnamespaced_ = function(key, opt_namespace) { 85 return key.indexOf(Settings.normalize_(opt_namespace)) == 0; 86 }, 87 88 Settings.namespace_ = function(key, opt_namespace) { 89 return Settings.normalize_(opt_namespace) + key; 90 }, 91 92 Settings.unnamespace_ = function(key, opt_namespace) { 93 return key.replace(Settings.normalize_(opt_namespace), ''); 94 }, 95 96 /** 97 * All settings are prefixed with a global namespace to avoid collisions. 98 * Settings may also be namespaced with an additional prefix passed into 99 * the get, set, and keys methods in order to group related settings. 100 * This method makes sure the two namespaces are always set properly. 101 */ 102 Settings.normalize_ = function(opt_namespace) { 103 return Settings.NAMESPACE + (opt_namespace ? opt_namespace + '.' : ''); 104 } 105 106 Settings.setAlternativeStorageInstance = function(instance) { 107 storage_ = instance; 108 } 109 Settings.getAlternativeStorageInstance = function() { 110 if (storage_ === localStorage) 111 return undefined; 112 return storage_; 113 } 114 115 Settings.NAMESPACE = 'trace-viewer'; 116 117 return { 118 Settings: Settings 119 }; 120 }); 121