definer('Helpers', /** @exports Helpers */ function(string, number, object, is) {
/**
* Модуль функций-помощников.
*
* @constructor
*/
function Helpers() {
/**
* Пользовательские функции-помощники.
*
* @private
* @type {object}
*/
this._custom = {};
}
/**
* Префикс для формируемых идентификаторов.
*
* @type {string}
*/
Helpers.idPrefix = 'i';
/**
* Соль для формируемых идентификаторов.
*
* Формируется один раз для экземпляра `bemer`.
* Актуально при шаблонизации на клиенте и сервере одновременно.
*
* @type {number}
*/
Helpers.idSalt = number.random(1000, 9999, 1);
/**
* Порядковый номер для формирования идентификаторов.
*
* @private
* @type {number}
*/
Helpers._id = 0;
/**
* Сбросить порядковый номер для формирования идентификаторов.
*
* @returns {Helpers}
*/
Helpers.resetId = function() {
Helpers._id = 0;
return Helpers;
};
Helpers.prototype = {
/**
* Получить все функции-помощники.
*
* @returns {object}
*/
get: function() {
return object.extend(this._getConstructor(), this._getHelpers(), this._custom);
},
/**
* Добавить пользовательскую функцию-помощник.
*
* @param {string} name Имя функции
* @param {function} callback Тело функции
* @returns {Helpers}
*/
add: function(name, callback) {
this._custom[name] = callback;
return this;
},
/**
* Получить внутренний и внешний конструкторы.
*
* @private
* @returns {object}
*/
_getConstructor: function() {
return {
/**
* Внутренний конструктор.
*
* @private
* @param {object} bemjson BEMJSON заматченной сущности
* @param {object} [data] Данные по сущности в дереве
* @param {number} [data.index=0] Индекс сущности среди сестринских элементов
* @param {number} [data.length=1] Количество сестринских элементов, включая текущий
* @param {object} [data.context] Информация о контексте родительского блока
* @param {object} [data.context.block] Имя родительского блока
* @param {object} [data.context.mods] Модификаторы родительского блока
*/
__constructor: function(bemjson, data) {
this.bemjson = bemjson;
this.data = object.extend({
index: 0,
length: 1
}, data || {});
this.construct.call(this, bemjson, this.data);
},
/**
* Внешний конструктор.
*
* @param {object} bemjson BEMJSON заматченной сущности
* @param {object} [data] Данные по сущности в дереве
*/
construct: function(bemjson, data) { /* jshint unused: false */ }
};
},
/**
* Получить базовые функции-помощники.
*
* @private
* @returns {object}
*/
_getHelpers: function() {
return object.extend({
/**
* Проверить на первый элемент среди сестринских.
*
* @returns {boolean}
*/
isFirst: function() {
return this.data.index === 0;
},
/**
* Проверить на последний элемент среди сестринских.
*
* @returns {boolean}
*/
isLast: function() {
return this.data.index + 1 === this.data.length;
},
/**
* Проверить узел на элемент.
*
* @returns {boolean}
*/
isElem: function() {
return !!this.bemjson.elem;
},
/**
* Проверить узел на блок.
*
* @returns {boolean}
*/
isBlock: function() {
return !this.isElem();
},
/**
* Сформировать идентификатор.
*
* @param {string} [prefix=i] Префикс для идентификатора
* @returns {string}
*/
id: function(prefix) {
return (prefix || Helpers.idPrefix) + Helpers.idSalt + Helpers._id++;
}
},
this._getHelpersFromModule(string, [
'escape', 'unEscape', 'htmlEscape', 'unHtmlEscape',
'collapse', 'stripTags',
'upper', 'lower', 'repeat'
]),
this._getHelpersFromModule(number, [
'random'
]),
this._getHelpersFromModule(object, [
'extend', 'deepExtend',
'clone', 'deepClone'
]),
{
is: this._getHelpersFromModule(is, [
'string', 'boolean',
'number', 'integer', 'float', 'nan',
'null', 'undefined', 'primitive',
'array', 'argument', 'function', 'native',
'map', 'date', 'regexp',
'type', 'every'
])
}
);
},
/**
* Получить набор функций-помощников из модуля.
*
* @private
* @param {function} context Класс содержащий помощников
* @param {string[]} names Список имён помощников
* @returns {object}
*/
_getHelpersFromModule: function(context, names) {
return names.reduce(function(helpers, method) {
helpers[method] = function() {
return context[method].apply(this, arguments);
}.bind(context);
return helpers;
}, {});
}
};
return Helpers;
});