// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* @fileoverview Provides the Settings class.
*/
base.exportTo('base', function() {
var alternativeStorageInstance = undefined;
/**
* Settings is a simple wrapper around local storage, to make it easier
* to test classes that have settings.
*
* @constructor
*/
function Settings() {
if (alternativeStorageInstance) {
this.storage_ = alternativeStorageInstance;
} else if ('G_testRunner' in global) {
/**
* In unit tests, use a mock object for storage so we don't change
* localStorage in tests.
*/
this.storage_ = new FakeLocalStorage();
} else {
this.storage_ = localStorage;
}
}
Settings.setAlternativeStorageInstance = function(instance) {
alternativeStorageInstance = instance;
}
Settings.prototype = {
/**
* Get the setting with the given name.
*
* @param {string} key The name of the setting.
* @param {string} opt_default The default value to return if not set.
* @param {string} opt_namespace If set, the setting name will be prefixed
* with this namespace, e.g. "categories.settingName". This is useful for
* a set of related settings.
*/
get: function(key, opt_default, opt_namespace) {
key = this.namespace_(key, opt_namespace);
var val = this.storage_.getItem(key);
if (val === null || val === undefined)
return opt_default;
return String(val);
},
/**
* Set the setting with the given name to the given value.
*
* @param {string} key The name of the setting.
* @param {string} value The value of the setting.
* @param {string} opt_namespace If set, the setting name will be prefixed
* with this namespace, e.g. "categories.settingName". This is useful for
* a set of related settings.
*/
set: function(key, value, opt_namespace) {
this.storage_.setItem(this.namespace_(key, opt_namespace), String(value));
},
/**
* Return a list of all the keys, or all the keys in the given namespace
* if one is provided.
*
* @param {string} opt_namespace If set, only return settings which
* begin with this prefix.
*/
keys: function(opt_namespace) {
var result = [];
opt_namespace = opt_namespace || '';
for (var i = 0; i < this.storage_.length; i++) {
var key = this.storage_.key(i);
if (this.isnamespaced_(key, opt_namespace))
result.push(this.unnamespace_(key, opt_namespace));
}
return result;
},
isnamespaced_: function(key, opt_namespace) {
return key.indexOf(this.normalize_(opt_namespace)) == 0;
},
namespace_: function(key, opt_namespace) {
return this.normalize_(opt_namespace) + key;
},
unnamespace_: function(key, opt_namespace) {
return key.replace(this.normalize_(opt_namespace), '');
},
/**
* All settings are prefixed with a global namespace to avoid collisions.
* Settings may also be namespaced with an additional prefix passed into
* the get, set, and keys methods in order to group related settings.
* This method makes sure the two namespaces are always set properly.
*/
normalize_: function(opt_namespace) {
return Settings.NAMESPACE + (opt_namespace ? opt_namespace + '.' : '');
}
};
Settings.NAMESPACE = 'trace-viewer';
/**
* Create a Fake localStorage object which just stores to a dictionary
* instead of actually saving into localStorage. Only used in unit tests.
* @constructor
*/
function FakeLocalStorage() {
}
FakeLocalStorage.prototype = {
__proto__: Object.prototype,
getItem: function(key) {
// LocalStorage returns null if the key isn't found, not undefined.
if (this[key] === undefined || this[key] === null)
return null;
return this[key];
},
setItem: function(key, value) {
this[key] = value;
},
key: function(i) {
return Object.keys(this).sort()[i];
},
get length() {
return Object.keys(this).length;
}
};
return {
Settings: Settings
};
});