232 lines
7.2 KiB
JavaScript
232 lines
7.2 KiB
JavaScript
#include cookies.js
|
|
#include utility.js
|
|
#include watcher.js
|
|
|
|
// really need to replace null with undefined where possible, in mami too
|
|
// wondering if there's room for the different backends here
|
|
|
|
var AmiSettings = function() {
|
|
var pub = {};
|
|
var prefix = 'ami_',
|
|
types = ['boolean', 'number', 'string'];
|
|
var settings = new Map,
|
|
locked = [];
|
|
|
|
var createSetting = function(name, type, defaultValue, mutable, virtual) {
|
|
var pub = {},
|
|
cookieName = prefix + name,
|
|
watchers = new AmiWatcher;
|
|
|
|
var virtualValue = undefined;
|
|
|
|
var getValue = function() {
|
|
if(!mutable)
|
|
return defaultValue;
|
|
|
|
var value = virtual ? virtualValue : AmiCookies.getCookie(cookieName);
|
|
if(value === undefined)
|
|
return defaultValue;
|
|
|
|
value = JSON.parse(value);
|
|
if(value === null)
|
|
return defaultValue;
|
|
|
|
return value;
|
|
};
|
|
|
|
var callWatchers = function() {
|
|
watchers.call(pub, getValue(), name);
|
|
};
|
|
|
|
var removeValue = function() {
|
|
if(locked.indexOf(name) >= 0)
|
|
return;
|
|
locked.push(name);
|
|
|
|
if(virtual) virtualValue = undefined;
|
|
else AmiCookies.removeCookie(cookieName);
|
|
callWatchers();
|
|
|
|
$ari(locked, name);
|
|
};
|
|
|
|
var setValue = function(value) {
|
|
if(value === undefined || value === null || value === defaultValue) {
|
|
removeValue();
|
|
return;
|
|
}
|
|
|
|
if(typeof value !== type)
|
|
throw 'value is not correct type';
|
|
|
|
if(locked.indexOf(name) >= 0)
|
|
return;
|
|
locked.push(name);
|
|
|
|
value = JSON.stringify(value);
|
|
if(virtual) virtualValue = value;
|
|
else AmiCookies.setCookie(cookieName, value);
|
|
callWatchers();
|
|
|
|
$ari(locked, name);
|
|
};
|
|
|
|
pub.getName = function() { return name; };
|
|
pub.getType = function() { return type; };
|
|
pub.getDefault = function() { return defaultValue; };
|
|
pub.isMutable = function() { return mutable; };
|
|
pub.isVirtual = function() { return virtual; };
|
|
|
|
pub.getValue = getValue;
|
|
pub.setValue = setValue;
|
|
pub.removeValue = removeValue;
|
|
pub.touch = callWatchers;
|
|
|
|
pub.hasValue = function() {
|
|
if(!mutable) return false;
|
|
|
|
var value = virtual ? virtualValue : AmiCookies.getCookie(cookieName);
|
|
if(value === undefined) return false;
|
|
|
|
value = JSON.parse(value);
|
|
if(value === null || value === defaultValue) return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
pub.toggleValue = function() {
|
|
if(type !== 'boolean')
|
|
throw 'cannot toggle non-boolean setting';
|
|
|
|
if(locked.indexOf(name) >= 0)
|
|
return;
|
|
locked.push(name);
|
|
|
|
var value = virtual ? virtualValue : AmiCookies.getCookie(cookieName);
|
|
if(value === undefined)
|
|
value = defaultValue;
|
|
else
|
|
value = JSON.parse(virtual ? virtualValue : AmiCookies.getCookie(cookieName));
|
|
|
|
value = JSON.stringify(!value);
|
|
if(virtual) virtualValue = value;
|
|
else AmiCookies.setCookie(cookieName, value);
|
|
callWatchers();
|
|
|
|
$ari(locked, name);
|
|
};
|
|
|
|
pub.watch = function(watcher) {
|
|
if(typeof watcher !== 'function')
|
|
throw 'watcher must be a function';
|
|
watchers.watch(watcher, pub, getValue(), name);
|
|
};
|
|
|
|
pub.unwatch = function(watcher) {
|
|
watchers.unwatch(watcher);
|
|
};
|
|
|
|
pub.virtualise = function() {
|
|
if(!mutable || virtual)
|
|
return;
|
|
virtual = true;
|
|
virtualValue = AmiCookies.getCookie(cookieName);
|
|
};
|
|
|
|
return pub;
|
|
};
|
|
|
|
return {
|
|
has: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined) return false;
|
|
return setting.hasValue();
|
|
},
|
|
get: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to get value of undefined setting';
|
|
return setting.getValue();
|
|
},
|
|
getSetting: function() {
|
|
return settings.get(name);
|
|
},
|
|
set: function(name, value) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to set value of undefined setting';
|
|
setting.setValue(value);
|
|
},
|
|
remove: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to remove value of undefined setting';
|
|
setting.removeValue();
|
|
},
|
|
toggle: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to toggle undefined setting';
|
|
setting.toggleValue();
|
|
},
|
|
touch: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to touch undefined setting';
|
|
setting.touch();
|
|
},
|
|
watch: function(name, watcher) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to watch undefined setting';
|
|
setting.watch(watcher);
|
|
},
|
|
unwatch: function(name, watcher) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to unwatch undefined setting';
|
|
setting.unwatch(watcher);
|
|
},
|
|
virtualise: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
throw 'attempting to virtualise undefined setting';
|
|
setting.virtualise();
|
|
},
|
|
define: function(name, type, defaultValue, mutable, virtual) {
|
|
if(typeof name !== 'string')
|
|
throw 'name must be string';
|
|
name = name.trim();
|
|
|
|
if(types.indexOf(type) < 0)
|
|
throw 'invalid type specified';
|
|
|
|
if(mutable === undefined) mutable = true;
|
|
else mutable = !!mutable;
|
|
|
|
virtual = !!virtual;
|
|
|
|
if(defaultValue !== null) {
|
|
if(defaultValue === undefined)
|
|
defaultValue = null;
|
|
else if(type !== typeof defaultValue)
|
|
throw 'defaultValue type must match setting type or be null';
|
|
}
|
|
|
|
var setting = createSetting(name, type, defaultValue, mutable, virtual);
|
|
settings.set(name, setting);
|
|
return setting;
|
|
},
|
|
undefine: function(name) {
|
|
var setting = settings.get(name);
|
|
if(setting === undefined)
|
|
return;
|
|
settings.delete(name);
|
|
setting.removeValue();
|
|
},
|
|
forEach: function(body) {
|
|
settings.forEach(body);
|
|
},
|
|
};
|
|
};
|