Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
157 lines
3.3 KiB
JavaScript
Executable file
157 lines
3.3 KiB
JavaScript
Executable file
define(function(require, exports, module) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Dependencies
|
|
*/
|
|
|
|
var debug = require('debug')('setting-alias');
|
|
|
|
/**
|
|
* Locals
|
|
*/
|
|
|
|
var forwardMethods = [
|
|
'filterOptions',
|
|
'resetOptions',
|
|
'supported',
|
|
'selected',
|
|
'select',
|
|
'next',
|
|
'get',
|
|
'set'
|
|
];
|
|
|
|
/**
|
|
* Exports
|
|
*/
|
|
|
|
module.exports = SettingAlias;
|
|
|
|
/**
|
|
* Initialize a new `SettingsAlias`
|
|
*
|
|
* SettingsAlias's are kinda confusing,
|
|
* but they simplify our app code massively
|
|
* in the long run.
|
|
*
|
|
* A `SettingAlias` has the same API as a `Setting`
|
|
* but behind the scenes provides a single interface
|
|
* to several `Setting`s. Depending on the state
|
|
* of the app, the `SettingAlias` will point to
|
|
* a different settings instance.
|
|
*
|
|
* Example:
|
|
*
|
|
* var flashModesPicture = new Setting({ key: 'flashModesPicture' });
|
|
* var flashModesVideo = new Setting({ key: 'flashModesVideo' });
|
|
* var mode = 'picture';
|
|
*
|
|
* var flashModes = new SettingAlias({
|
|
* key: 'flashModes',
|
|
* settings: {
|
|
* 'picture': flashModesPicture,
|
|
* 'video': flashModesVideo
|
|
* },
|
|
* get: function() {
|
|
* return this.settings[mode];
|
|
* }
|
|
* });
|
|
*
|
|
* flashModes.get('key'); //=> 'flashModesPicture'
|
|
* mode = 'video';
|
|
* flashModes.get('key'); //=> 'flashModesVideo'
|
|
*
|
|
* This means our app can simply call API on
|
|
* `flashModes` setting-alias and not worry
|
|
* about which 'mode' the app is in.
|
|
*
|
|
* Options:
|
|
*
|
|
* - `key` The name of the setting-alias
|
|
* - `settings` Hash of possible `Setting`s
|
|
* - `get` Method that returns the current `Setting`
|
|
*
|
|
* @param {Object} options
|
|
*/
|
|
function SettingAlias(options) {
|
|
debug('initialize');
|
|
this.key = options.key;
|
|
this.settings = options.settings;
|
|
this.current = options.get.bind(this);
|
|
forwardMethods.forEach(this.forward, this);
|
|
debug('initialized');
|
|
}
|
|
|
|
/**
|
|
* Iterates over each setting.
|
|
*
|
|
* @param {Function} fn
|
|
* @private
|
|
*/
|
|
SettingAlias.prototype.each = function(fn) {
|
|
for (var key in this.settings) {
|
|
fn(this.settings[key]);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* States whether the passed key
|
|
* is the currently active setting.
|
|
*
|
|
* @param {String} key
|
|
* @return {Boolean}
|
|
*/
|
|
SettingAlias.prototype.is = function(key) {
|
|
return this.get('key') === key;
|
|
};
|
|
|
|
/**
|
|
* Attaches a method that forwards
|
|
* the call onto the current
|
|
* matching setting.
|
|
*
|
|
* @param {String} method
|
|
*/
|
|
SettingAlias.prototype.forward = function(method) {
|
|
this[method] = function() {
|
|
var setting = this.current();
|
|
return setting[method].apply(setting, arguments);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Add an event callback.
|
|
*
|
|
* The callback is wrapped in
|
|
* a function that first checks that
|
|
* the setting is the active setting
|
|
* before calling the original callback.
|
|
*
|
|
* @param {String} name
|
|
* @param {Function} fn
|
|
*/
|
|
SettingAlias.prototype.on = function(name, fn) {
|
|
var alias = this;
|
|
var wrapped = function() {
|
|
if (!alias.is(this.key)) { return; }
|
|
fn.apply(this, arguments);
|
|
};
|
|
|
|
this.each(function(setting) { setting.on(name, wrapped); });
|
|
fn._settingAliasCallback = wrapped;
|
|
};
|
|
|
|
/**
|
|
* Remove an event callback.
|
|
*
|
|
* @param {String} name
|
|
* @param {Function} fn
|
|
*/
|
|
SettingAlias.prototype.off = function(name, fn) {
|
|
var wrapped = fn._settingAliasCallback;
|
|
this.each(function(setting) { setting.off(name, wrapped); });
|
|
delete fn._settingAliasCallback;
|
|
};
|
|
|
|
});
|