convert settings API to have Setting class with get() and set() methods. Also several tidy-ups
This commit is contained in:
parent
0930c37675
commit
0c0357c177
4 changed files with 139 additions and 116 deletions
|
|
@ -37,26 +37,28 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
|
||||||
var setCommandSpec = {
|
var setCommandSpec = {
|
||||||
name: "set",
|
name: 'set',
|
||||||
params: [
|
params: [
|
||||||
{
|
{
|
||||||
name: "setting",
|
name: 'setting',
|
||||||
type: "setting",
|
type: 'setting',
|
||||||
description: "The name of the setting to display or alter",
|
description: 'The name of the setting to display or alter',
|
||||||
defaultValue: null
|
defaultValue: null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "value",
|
name: 'value',
|
||||||
type: "settingValue",
|
type: 'settingValue',
|
||||||
description: "The new value for the chosen setting",
|
description: 'The new value for the chosen setting',
|
||||||
defaultValue: null
|
defaultValue: null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
description: "define and show settings",
|
description: 'define and show settings',
|
||||||
exec: function(env, args, request) {
|
exec: function(env, args, request) {
|
||||||
var html;
|
var html;
|
||||||
if (!args.setting) {
|
if (!args.setting) {
|
||||||
|
// 'set' by itself lists all the settings
|
||||||
var settingsList = env.settings._list();
|
var settingsList = env.settings._list();
|
||||||
html = '';
|
html = '';
|
||||||
// first sort the settingsList based on the key
|
// first sort the settingsList based on the key
|
||||||
|
|
@ -69,7 +71,7 @@ var setCommandSpec = {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var url = "https://wiki.mozilla.org/Labs/Skywriter/Settings#" +
|
var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' +
|
||||||
setting.key;
|
setting.key;
|
||||||
settingsList.forEach(function(setting) {
|
settingsList.forEach(function(setting) {
|
||||||
html += '<a class="setting" href="' + url +
|
html += '<a class="setting" href="' + url +
|
||||||
|
|
@ -82,13 +84,22 @@ var setCommandSpec = {
|
||||||
'<br/>';
|
'<br/>';
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
var setting = env.settings.get(args.setting);
|
||||||
|
if (!setting) {
|
||||||
|
request.doneWithError('No setting with the name <strong>' +
|
||||||
|
setting.name + '</strong>.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set with only a setting, shows the value for that setting
|
||||||
if (args.value === undefined) {
|
if (args.value === undefined) {
|
||||||
html = '<strong>' + args.setting + '</strong> = ' +
|
html = '<strong>' + setting.name + '</strong> = ' +
|
||||||
env.settings.get(args.setting);
|
setting.get();
|
||||||
} else {
|
} else {
|
||||||
html = 'Setting: <strong>' + args.setting + '</strong> = ' +
|
// Actually change the setting
|
||||||
args.value;
|
setting.set(args.value);
|
||||||
env.settings.set(args.setting, args.value);
|
html = 'Setting: <strong>' + setting.name + '</strong> = ' +
|
||||||
|
setting.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.done(html);
|
request.done(html);
|
||||||
|
|
@ -96,18 +107,25 @@ var setCommandSpec = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var unsetCommandSpec = {
|
var unsetCommandSpec = {
|
||||||
name: "unset",
|
name: 'unset',
|
||||||
params: [
|
params: [
|
||||||
{
|
{
|
||||||
name: "setting",
|
name: 'setting',
|
||||||
type: "setting",
|
type: 'setting',
|
||||||
description: "The name of the setting to return to defaults"
|
description: 'The name of the setting to return to defaults'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
description: "unset a setting entirely",
|
description: 'unset a setting entirely',
|
||||||
exec: function(env, args, request) {
|
exec: function(env, args, request) {
|
||||||
env.settings.resetValue(args.setting);
|
var setting = env.settings.get(args.setting);
|
||||||
request.done('Reset ' + args.setting + ' to default: ' +
|
if (!setting) {
|
||||||
|
request.doneWithError('No setting with the name <strong>' +
|
||||||
|
args.setting + '</strong>.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting.reset();
|
||||||
|
request.done('Reset ' + setting.name + ' to default: ' +
|
||||||
env.settings.get(args.setting));
|
env.settings.get(args.setting));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -43,18 +43,18 @@ define(function(require, exports, module) {
|
||||||
* This plug-in manages settings.
|
* This plug-in manages settings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var console = require("pilot/console");
|
var console = require('pilot/console');
|
||||||
var oop = require("pilot/oop").oop;
|
var oop = require('pilot/oop').oop;
|
||||||
var types = require("pilot/types");
|
var types = require('pilot/types');
|
||||||
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
var EventEmitter = require('pilot/event_emitter').EventEmitter;
|
||||||
var catalog = require("pilot/catalog");
|
var catalog = require('pilot/catalog');
|
||||||
|
|
||||||
var settingExtensionSpec = {
|
var settingExtensionSpec = {
|
||||||
name: "setting",
|
name: 'setting',
|
||||||
description: "A setting is something that the application offers as a " +
|
description: 'A setting is something that the application offers as a ' +
|
||||||
"way to customize how it works",
|
'way to customize how it works',
|
||||||
register: "env.settings.addSetting",
|
register: 'env.settings.addSetting',
|
||||||
indexOn: "name"
|
indexOn: 'name'
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.startup = function(data, reason) {
|
exports.startup = function(data, reason) {
|
||||||
|
|
@ -65,6 +65,68 @@ exports.shutdown = function(data, reason) {
|
||||||
catalog.removeExtensionSpec(settingExtensionSpec);
|
catalog.removeExtensionSpec(settingExtensionSpec);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new setting.
|
||||||
|
* @param settingSpec An object literal that looks like this:
|
||||||
|
* {
|
||||||
|
* name: 'thing',
|
||||||
|
* description: 'Thing is an example setting',
|
||||||
|
* type: 'string',
|
||||||
|
* defaultValue: 'something'
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
function Setting(settingSpec, settings) {
|
||||||
|
this._settings = settings;
|
||||||
|
|
||||||
|
Object.keys(settingSpec).forEach(function(key) {
|
||||||
|
this[key] = settingSpec[key];
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.type = types.getType(this.type);
|
||||||
|
if (this.type == null) {
|
||||||
|
throw new Error('In ' + this.name +
|
||||||
|
': can\'t find type for: ' + JSON.stringify(settingSpec.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.name) {
|
||||||
|
throw new Error('Setting.name == undefined. Ignoring.', this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.defaultValue === undefined) {
|
||||||
|
throw new Error('Setting.defaultValue == undefined', this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = this.defaultValue;
|
||||||
|
}
|
||||||
|
Setting.prototype = {
|
||||||
|
get: function() {
|
||||||
|
return this.value;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function(value) {
|
||||||
|
if (this.value === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
if (this._settings.persister) {
|
||||||
|
this._settings.persister.persistValue(this._settings, this.name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dispatchEvent('change', { setting: this, value: value });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the value of the <code>key</code> setting to it's default
|
||||||
|
*/
|
||||||
|
resetValue: function() {
|
||||||
|
this.set(this.defaultValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
oop.implement(Setting.prototype, EventEmitter);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for all the various methods of storing settings.
|
* A base class for all the various methods of storing settings.
|
||||||
* <p>Usage:
|
* <p>Usage:
|
||||||
|
|
@ -89,11 +151,6 @@ function Settings(persister) {
|
||||||
*/
|
*/
|
||||||
this._deactivated = {};
|
this._deactivated = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage for the setting values
|
|
||||||
*/
|
|
||||||
this._values = {};
|
|
||||||
|
|
||||||
this._settings = {};
|
this._settings = {};
|
||||||
|
|
||||||
if (persister) {
|
if (persister) {
|
||||||
|
|
@ -116,33 +173,8 @@ Settings.prototype = {
|
||||||
* @param {object} settingSpec Object containing name/type/defaultValue members.
|
* @param {object} settingSpec Object containing name/type/defaultValue members.
|
||||||
*/
|
*/
|
||||||
addSetting: function(settingSpec) {
|
addSetting: function(settingSpec) {
|
||||||
if (!settingSpec.name) {
|
var setting = new Setting(settingSpec, this);
|
||||||
console.error('Setting.name == undefined. Ignoring.', settingSpec);
|
this._settings[setting.name] = setting;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settingSpec.defaultValue === undefined) {
|
|
||||||
console.error('Setting.defaultValue == undefined', settingSpec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = types.getType(settingSpec.type);
|
|
||||||
if (!type) {
|
|
||||||
console.error('Missing type', settingSpec);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// The value can be
|
|
||||||
// 1) the value of a setting that is not activated at the moment
|
|
||||||
// OR
|
|
||||||
// 2) the defaultValue of the setting.
|
|
||||||
var value = this._deactivated[settingSpec.name] ||
|
|
||||||
settingSpec.defaultValue;
|
|
||||||
*/
|
|
||||||
|
|
||||||
var setting = { type: type, spec: settingSpec };
|
|
||||||
this._settings[settingSpec.name] = setting;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
removeSetting: function(name) {
|
removeSetting: function(name) {
|
||||||
|
|
@ -153,6 +185,10 @@ Settings.prototype = {
|
||||||
return Object.keys(this._settings);
|
return Object.keys(this._settings);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSetting: function(name) {
|
||||||
|
return this._settings[name];
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Persister is able to store settings. It is an object that defines
|
* A Persister is able to store settings. It is an object that defines
|
||||||
* two functions:
|
* two functions:
|
||||||
|
|
@ -165,44 +201,6 @@ Settings.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Read accessor
|
|
||||||
*/
|
|
||||||
get: function(key) {
|
|
||||||
return this._values[key];
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override observable.set(key, value) to provide type conversion and
|
|
||||||
* validation.
|
|
||||||
*/
|
|
||||||
set: function(key, value) {
|
|
||||||
var setting = this._settings[key];
|
|
||||||
if (!setting) {
|
|
||||||
console.warn('Setting not defined: ', key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._values[key] = value;
|
|
||||||
if (persister) {
|
|
||||||
persister.persistValue(this, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._dispatchEvent('settingChange', { key: key, value: value });
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the value of the <code>key</code> setting to it's default
|
|
||||||
*/
|
|
||||||
resetValue: function(key) {
|
|
||||||
var setting = this._settings[key];
|
|
||||||
if (setting) {
|
|
||||||
this.set(key, setting.spec.defaultValue);
|
|
||||||
} else {
|
|
||||||
console.log('ignore resetValue on ', key);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
resetAll: function() {
|
resetAll: function() {
|
||||||
this.getSettingNames().forEach(function(key) {
|
this.getSettingNames().forEach(function(key) {
|
||||||
this.resetValue(key);
|
this.resetValue(key);
|
||||||
|
|
@ -267,9 +265,6 @@ Settings.prototype = {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
oop.implement(Settings.prototype, EventEmitter);
|
|
||||||
|
|
||||||
exports.settings = new Settings();
|
exports.settings = new Settings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -200,11 +200,12 @@ function DeferredType(typeSpec) {
|
||||||
DeferredType.prototype = new Type();
|
DeferredType.prototype = new Type();
|
||||||
|
|
||||||
DeferredType.prototype.stringify = function(value) {
|
DeferredType.prototype.stringify = function(value) {
|
||||||
return this.defer.stringify(value);
|
return this.defer().stringify(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
DeferredType.prototype.parse = function(value) {
|
DeferredType.prototype.parse = function(value) {
|
||||||
return this.defer.parse(value);
|
console.log(this.defer);
|
||||||
|
return this.defer().parse(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
DeferredType.prototype.name = 'deferred';
|
DeferredType.prototype.name = 'deferred';
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,10 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
var SelectionType = require("pilot/types/basic").SelectionType;
|
var SelectionType = require('pilot/types/basic').SelectionType;
|
||||||
var DeferredType = require("pilot/types/basic").DeferredType;
|
var DeferredType = require('pilot/types/basic').DeferredType;
|
||||||
var types = require("pilot/types");
|
var types = require('pilot/types');
|
||||||
|
var settings = require('pilot/settings').settings;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -58,13 +59,21 @@ var setting = new SelectionType({
|
||||||
data: function() {
|
data: function() {
|
||||||
return env.settings.getSettingNames();
|
return env.settings.getSettingNames();
|
||||||
},
|
},
|
||||||
stringify: function(value) {
|
stringify: function(setting) {
|
||||||
lastSetting = value;
|
lastSetting = setting;
|
||||||
return SelectionType.prototype.stringify.call(this, value);
|
return setting.name;
|
||||||
},
|
},
|
||||||
parse: function(value) {
|
parse: function(text) {
|
||||||
lastSetting = value;
|
lastSetting = text;
|
||||||
return SelectionType.prototype.parse.call(this, value);
|
|
||||||
|
var conversion = SelectionType.prototype.parse.call(this, text);
|
||||||
|
if (conversion.value) {
|
||||||
|
conversion.value = settings.getSetting(conversion.value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
conversion.message = 'Several possibilities for \'' + text + '\'';
|
||||||
|
}
|
||||||
|
return conversion;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -73,7 +82,7 @@ var setting = new SelectionType({
|
||||||
* of the type to the command line.
|
* of the type to the command line.
|
||||||
*/
|
*/
|
||||||
var settingValue = new DeferredType({
|
var settingValue = new DeferredType({
|
||||||
name: "settingValue",
|
name: 'settingValue',
|
||||||
defer: function() {
|
defer: function() {
|
||||||
return env.settings.getSetting(lastSetting).type;
|
return env.settings.getSetting(lastSetting).type;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue