Refactor structure to be more testable

This commit is contained in:
Keegan
2016-01-27 00:03:07 -08:00
parent b960dc19f4
commit 13b84f7e6c
19 changed files with 391 additions and 3095 deletions
+88
View File
@@ -0,0 +1,88 @@
'use strict';
var itemTypes = require('./items');
var $ = require('../vendor/minified/minified').$;
var _ = require('../vendor/minified/minified')._;
var HTML = require('../vendor/minified/minified').HTML;
function ApiItem(config) {
var self = this;
var eventProxies = {};
var itemType = itemTypes[config.type];
var templateData = _.extend({}, itemType.defaults, config);
var $element = HTML(_.formatHtml(itemType.template, templateData));
var $manipulatorTarget = $element.select('[data-manipulator-target]');
// this caters for situations where the manipulator target is the root element
if (!$manipulatorTarget.length) {
$manipulatorTarget = $element;
}
Object.defineProperties(self, {
id: {
value: config.id || null
},
appKey: {
value: config.appKey || null
},
config: {
value: config || null
},
$element: {
value: $element
},
$manipulatorTarget: {
value: $manipulatorTarget
},
on: {
value: function(events, handler) {
eventProxies[handler] = function() {
handler.apply(self, arguments);
};
return $manipulatorTarget.on(events, eventProxies[handler]);
}
},
one: {
value: function(events, handler) {
eventProxies[handler] = function(event) {
handler.apply(self, arguments);
$.off(eventProxies[handler]);
};
return $manipulatorTarget.on(events, eventProxies[handler]);
}
},
off: {
value: function(handler) {
return $.off(eventProxies[handler]);
}
},
trigger: {
value: $manipulatorTarget.trigger.bind($manipulatorTarget)
},
initialize: {
value: typeof itemType.initialize === 'function' ?
itemType.initialize.bind(self) :
function() {}
}
});
// attach the manipulator methods to the apiItem
_.eachObj(itemType.manipulator, function(methodName, method) {
Object.defineProperty(self, methodName, { value: method.bind(self) });
});
self.initialize();
}
module.exports = ApiItem;
+95
View File
@@ -0,0 +1,95 @@
'use strict';
/**
* A Clay config Item
* @typedef {object} Clay~Item
* @property {string} type
* @property {string} appKey
* @property {string} id
* @property {string} content
* @property {string|boolean} default
* @property {string} label
* @property {object} attributes
* @property {Array} options
* @property {Array} items
*/
var HTML = require('../vendor/minified/minified').HTML;
var _ = require('../vendor/minified/minified')._;
var ApiItem = require('./api-item');
function Api(settings) {
var self = this;
var _items = [];
var _itemsById = {};
var _itemsByAppKey = {};
var _settings = _.copyObj(settings);
Object.defineProperties(self, {
getItemByAppKey: {
value: function(key) {
return _itemsByAppKey[key];
}
},
getItemById: {
value: function(key) {
return _itemsById[key];
}
},
getItemsByType: {
value: function(type) {
return _items.filter(function(item) {
return item.config.type === type;
});
}
},
getSettings: {
value: function() {
_.eachObj(_itemsByAppKey, function(appKey, item) {
_settings[appKey] = item.get();
});
return _settings;
}
},
addItem: {
value: function(item, $container) {
if (Array.isArray(item)) {
item.forEach(function(item) {
self.addItem(item, $container);
});
} else if (item.type === 'section') {
var $wrapper = HTML('<div class="section">');
$container.add($wrapper);
self.addItem(item.items, $wrapper);
} else {
var apiItem = new ApiItem(item);
if (item.id) {
_itemsById[item.id] = apiItem;
}
if (item.appKey) {
_itemsByAppKey[item.appKey] = apiItem;
}
_items.push(apiItem);
// set the value of the item via the manipulator to ensure consistency
var value = typeof _settings[item.appKey] !== 'undefined' ?
_settings[item.appKey] :
(item.value || '');
apiItem.set(value);
$container.add(apiItem.$element);
}
}
}
});
}
module.exports = Api;
+15 -1
View File
@@ -5,6 +5,9 @@ var HTML = require('../../vendor/minified/minified').HTML;
module.exports = {
template: require('../../../templates/items/color.tpl'),
manipulator: require('../manipulators').val,
defaults: {
label: ''
},
initialize: function() {
var self = this;
@@ -72,9 +75,12 @@ module.exports = {
var $valueDisplay = $elem.select('.value');
var $picker = $elem.select('.picker-wrap');
var disabled = self.$manipulatorTarget.get('disabled');
$elem.on('click', function(ev) {
$picker.set('show');
if (!disabled) {
$picker.set('show');
}
});
self.on('|change', function() {
@@ -89,5 +95,13 @@ module.exports = {
$picker.set('-show');
});
self.on('disabled', function() {
disabled = true;
});
self.on('enabled', function() {
disabled = false;
});
}
};
+4 -1
View File
@@ -2,5 +2,8 @@
module.exports = {
template: require('../../../templates/items/footer.tpl'),
manipulator: require('../manipulators').html
manipulator: require('../manipulators').html,
defaults: {
attributes: {}
}
};
+5 -1
View File
@@ -2,5 +2,9 @@
module.exports = {
template: require('../../../templates/items/heading.tpl'),
manipulator: require('../manipulators').html
manipulator: require('../manipulators').html,
defaults: {
attributes: {},
size: 4
}
};
+5 -1
View File
@@ -2,5 +2,9 @@
module.exports = {
template: require('../../../templates/items/input.tpl'),
manipulator: require('../manipulators').val
manipulator: require('../manipulators').val,
defaults: {
label: '',
attributes: {}
}
};
+5 -1
View File
@@ -2,5 +2,9 @@
module.exports = {
template: require('../../../templates/items/radiogroup.tpl'),
manipulator: require('../manipulators').radiogroup
manipulator: require('../manipulators').radiogroup,
defaults: {
label: '',
options: []
}
};
+4
View File
@@ -3,6 +3,10 @@
module.exports = {
template: require('../../../templates/items/select.tpl'),
manipulator: require('../manipulators').val,
defaults: {
label: '',
options: []
},
initialize: function() {
var self = this;
+4 -1
View File
@@ -2,5 +2,8 @@
module.exports = {
template: require('../../../templates/items/submit.tpl'),
manipulator: require('../manipulators').val
manipulator: require('../manipulators').val,
defaults: {
attributes: {}
}
};
+4 -1
View File
@@ -2,5 +2,8 @@
module.exports = {
template: require('../../../templates/items/text.tpl'),
manipulator: require('../manipulators').html
manipulator: require('../manipulators').html,
defaults: {
attributes: {}
}
};
+4 -1
View File
@@ -2,5 +2,8 @@
module.exports = {
template: require('../../../templates/items/toggle.tpl'),
manipulator: require('../manipulators').checked
manipulator: require('../manipulators').checked,
defaults: {
attributes: {}
}
};
+4 -2
View File
@@ -19,10 +19,12 @@ module.exports = {
.trigger('change');
},
disable: function() {
return this.$manipulatorTarget.set('disabled', true);
return this.$manipulatorTarget.set('disabled', true)
.trigger('disabled');
},
enable: function() {
return this.$manipulatorTarget.set('disabled', false);
return this.$manipulatorTarget.set('disabled', false)
.trigger('enabled');
}
},
checked: {