'use strict';
var componentRegistry = require('./component-registry');
var minified = require('../vendor/minified');
var utils = require('../lib/utils');
var ClayEvents = require('./clay-events');
var _ = minified._;
var HTML = minified.HTML;
/**
* @extends ClayEvents
* @param {Clay~ConfigItem} config
* @constructor
*/
function ClayItem(config) {
var self = this;
var _component = componentRegistry[config.type];
if (!_component) {
throw new Error('The component: ' + config.type + ' is not registered. ' +
'Make sure to register it with ClayConfig.registerComponent()');
}
var _templateData = _.extend({}, _component.defaults || {}, config);
/** @type {string|null} */
self.id = config.id || null;
/** @type {string|null} */
self.appKey = config.appKey || null;
/** @type {Object} */
self.config = config;
/** @type {M} */
self.$element = HTML(_component.template.trim(), _templateData);
/** @type {M} */
self.$manipulatorTarget = self.$element.select('[data-manipulator-target]');
// this caters for situations where the manipulator target is the root element
if (!self.$manipulatorTarget.length) {
self.$manipulatorTarget = self.$element;
}
/**
* Run the initializer if it exists and attaches the css to the head.
* Passes minified as the first param
* @param {ClayConfig} clay
* @returns {ClayItem}
*/
self.initialize = function(clay) {
if (typeof _component.initialize === 'function') {
_component.initialize.call(self, minified, clay);
}
return self;
};
// attach event methods
ClayEvents.call(self, self.$manipulatorTarget);
// attach the manipulator methods to the clayItem
_.eachObj(_component.manipulator, function(methodName, method) {
self[methodName] = method.bind(self);
});
// prevent external modifications of properties
utils.updateProperties(self, { writable: false, configurable: false });
}
module.exports = ClayItem;