snakeskin
Version:
Awesome JavaScript template engine.
1,546 lines (1,265 loc) • 32 kB
JavaScript
/*!
* Snakeskin v7.5.1 (live)
* https://github.com/SnakeskinTpl/Snakeskin
*
* Released under the MIT license
* https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
*
* Date: 'Fri, 21 Sep 2018 15:57:44 GMT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define('Snakeskin', factory) :
(global.Snakeskin = factory());
}(this, (function () { 'use strict';
var Snakeskin = void 0;
var Snakeskin$1 = Snakeskin = {
VERSION: [7, 5, 1]
};
/**
* The operation UID
* @type {?string}
*/
Snakeskin.UID = null;
/**
* The namespace for directives
* @const
*/
Snakeskin.Directives = {};
/**
* The namespace for filters
* @const
*/
Snakeskin.Filters = {};
/**
* The namespace for super-global variables
* @const
*/
Snakeskin.Vars = {
/**
* Decorator for template overriding
*
* @param {string} name
* @return {!Function}
*/
override: function override(name) {
return function (fn, ctx) {
return ctx[name] = fn;
};
},
/**
* Decorator for template ignoring
* @param {!Function} fn
*/
ignore: function ignore(fn) {
fn.ignore = true;
}
};
/**
* The namespace for local variables
* @const
*/
Snakeskin.LocalVars = {};
/**
* The cache of templates
* @const
*/
Snakeskin.cache = {};
Array.isArray = Array.isArray || function (obj) {
return {}.call(obj) === '[object Array]';
};
String.prototype.trim = String.prototype.trim || function () {
var str = this.replace(/^\s\s*/, '');
var i = str.length;
for (var rgxp = /\s/; rgxp.test(str.charAt(--i));) {
// Do nothing
}
return str.substring(0, i + 1);
};
/**
* Returns true if the specified value is a function
*
* @param {?} obj - source value
* @return {boolean}
*/
function isFunction(obj) {
return typeof obj === 'function';
}
/**
* Returns true if the specified value is a number
*
* @param {?} obj - source value
* @return {boolean}
*/
/**
* Returns true if the specified value is a string
*
* @param {?} obj - source value
* @return {boolean}
*/
function isString(obj) {
return typeof obj === 'string';
}
/**
* Returns true if the specified value is a boolean
*
* @param {?} obj - source value
* @return {boolean}
*/
/**
* Returns true if the specified value is an array
*
* @param {?} obj - source value
* @return {boolean}
*/
function isArray(obj) {
return Array.isArray(obj);
}
/**
* Returns true if the specified value is a plain object
*
* @param {?} obj - source value
* @return {boolean}
*/
function isObject(obj) {
return Boolean(obj) && obj.constructor === Object;
}
/**
* Special Snakeskin class for escaping HTML entities from an object
*
* @constructor
* @param {?} obj - source object
* @param {?string=} [opt_attr] - type of attribute declaration
*/
Snakeskin$1.HTMLObject = function (obj, opt_attr) {
this.value = obj;
this.attr = opt_attr;
};
/**
* StringBuffer constructor
*
* @constructor
* @return {!Array}
*/
Snakeskin$1.StringBuffer = function () {
return [];
};
/**
* @param {!Function} child
* @param {!Function} parent
*/
function inherit(child, parent) {
/** @constructor */
var F = function F() {
this.constructor = child;
};
F.prototype = parent.prototype;
child.prototype = new F();
}
/**
* Node constructor
* @constructor
*/
Snakeskin$1.Node = function () {};
/**
* Returns the number of child elements
* @return {number}
*/
Snakeskin$1.Node.prototype.length = function () {
return this.value.childNodes.length;
};
/**
* Returns text content
* @return {string}
*/
Snakeskin$1.Node.prototype.textContent = function () {
return this.value.textContent;
};
/**
* DocumentFragment constructor
*
* @constructor
* @extends {Snakeskin.Node}
* @param {string} renderMode - rendering mode of templates
*/
Snakeskin$1.DocumentFragment = function (renderMode) {
this.renderMode = renderMode;
this.value = document.createDocumentFragment();
};
inherit(Snakeskin$1.DocumentFragment, Snakeskin$1.Node);
/**
* Appends a child to the document fragment
* @param {?} el - element for appending
*/
Snakeskin$1.DocumentFragment.prototype.appendChild = function (el) {
this.value.appendChild(el);
};
/**
* Returns text content
* @return {string}
*/
Snakeskin$1.DocumentFragment.prototype.textContent = function () {
var children = this.value.childNodes;
var res = '';
for (var i = 0; i < children.length; i++) {
res += children[i].outerHTML || children[i].textContent;
}
return res;
};
/**
* Element constructor
*
* @constructor
* @extends {Snakeskin.Node}
*
* @param {string} name - element name
* @param {string} renderMode - rendering mode of templates
*/
Snakeskin$1.Element = function (name, renderMode) {
this.renderMode = renderMode;
this.value = document.createElement(name);
};
inherit(Snakeskin$1.Element, Snakeskin$1.Node);
/**
* Appends a child to the element
* @param {?} el - element for appending
*/
Snakeskin$1.Element.prototype.appendChild = function (el) {
this.value.appendChild(el);
};
/**
* Sets an attribute to the element
*
* @param {string} name - attribute name
* @param {string} val - attribute value
*/
Snakeskin$1.Element.prototype.setAttribute = function (name, val) {
this.value.setAttribute(name, val);
};
/**
* Returns text content
* @return {string}
*/
Snakeskin$1.Element.prototype.textContent = function () {
return this.value.outerHTML;
};
/**
* Comment constructor
*
* @constructor
* @extends {Snakeskin.Node}
*
* @param {string} text - comment text
* @param {string} renderMode - rendering mode of templates
*/
Snakeskin$1.Comment = function (text, renderMode) {
this.renderMode = renderMode;
this.value = document.createComment(text);
};
inherit(Snakeskin$1.Comment, Snakeskin$1.Node);
/**
* Text constructor
*
* @constructor
* @extends {Snakeskin.Node}
*
* @param {string} text
* @param {string} renderMode - rendering mode of templates
*/
Snakeskin$1.Text = function (text, renderMode) {
this.renderMode = renderMode;
this.value = document.createTextNode(text);
};
inherit(Snakeskin$1.Text, Snakeskin$1.Node);
/**
* Map of inline tag names
* @const
*/
Snakeskin$1.inlineTags = {
'html': {
'area': 'href',
'base': 'href',
'br': true,
'col': true,
'embed': 'src',
'hr': true,
'img': 'src',
'input': 'value',
'link': 'href',
'meta': 'content',
'param': 'value',
'source': 'src',
'track': 'src',
'wbr': true
},
'xml': {}
};
/**
* Appends a value to the specified element
*
* @param {(!Snakeskin.DocumentFragment|!Snakeskin.Element)} el - base element
* @param {?} val - value for appending
* @param {string} renderMode - rendering mode of templates
* @return {(!Snakeskin.Element|!Snakeskin.Comment|!Snakeskin.Text)}
*/
Snakeskin$1.appendChild = function (el, val, renderMode) {
if (val instanceof Snakeskin$1.Node === false) {
val = new Snakeskin$1.Text(String(val), renderMode);
}
if (el) {
el.appendChild(val.value);
}
return val;
};
/**
* Sets an attribute to the specified element
*
* @param {!Snakeskin.Node} node - source element
* @param {string} name - attribute name
* @param {?} val - attribute value
*/
Snakeskin$1.setAttribute = function (node, name, val) {
node.setAttribute(name, val instanceof Snakeskin$1.Node ? val.textContent() : String(val));
};
var keys = function () {
return (/\[native code]/.test(Object.keys && Object.keys.toString()) && Object.keys
);
}();
/**
* Common iterator
* (with hasOwnProperty for objects)
*
* @param {(Array|Object|undefined)} obj - source object
* @param {(
* function(?, ?, !Array, {isFirst: boolean, isLast: boolean, length: number})|
* function(?, ?, !Object, {i: number, isFirst: boolean, isLast: boolean, length: number})
* )} callback - callback function
*/
Snakeskin$1.forEach = function (obj, callback) {
if (!obj) {
return;
}
var length = 0;
if (isArray(obj)) {
length = obj.length;
for (var i = 0; i < length; i++) {
if (callback(obj[i], i, obj, { isFirst: i === 0, isLast: i === length - 1, length: length }) === false) {
break;
}
}
} else if (keys) {
var arr = keys(obj);
length = arr.length;
for (var _i = 0; _i < length; _i++) {
if (callback(obj[arr[_i]], arr[_i], obj, { i: _i, isFirst: _i === 0, isLast: _i === length - 1, length: length }) === false) {
break;
}
}
} else {
if (callback.length >= 4) {
for (var key in obj) {
if (!obj.hasOwnProperty(key)) {
break;
}
length++;
}
}
var _i2 = 0;
for (var _key in obj) {
if (!obj.hasOwnProperty(_key)) {
break;
}
if (callback(obj[_key], _key, obj, { i: _i2, isFirst: _i2 === 0, isLast: _i2 === length - 1, length: length }) === false) {
break;
}
_i2++;
}
}
};
/**
* Object iterator
* (without hasOwnProperty)
*
* @param {(Object|undefined)} obj - source object
* @param {function(?, string, !Object, {i: number, isFirst: boolean, isLast: boolean, length: number})} callback - callback function
*/
Snakeskin$1.forIn = function (obj, callback) {
if (!obj) {
return;
}
var length = 0,
i = 0;
if (callback.length >= 4) {
/* eslint-disable guard-for-in */
for (var ignore in obj) {
length++;
}
/* eslint-enable guard-for-in */
}
for (var key in obj) {
if (callback(obj[key], key, obj, { i: i, isFirst: i === 0, isLast: i === length - 1, length: length }) === false) {
break;
}
i++;
}
};
/**
* Decorates a function by another functions
*
* @param {!Array<!Function>} decorators - array of decorator functions
* @param {!Function} fn - source function
* @param {!Object} nms - source namespace
* @return {!Function}
*/
Snakeskin$1.decorate = function (decorators, nms, fn) {
Snakeskin$1.forEach(decorators, function (decorator) {
return fn = decorator(fn, nms) || fn;
});
fn.decorators = decorators;
return fn;
};
/**
* Gets an object with an undefined type
* (for the GCC)
*
* @param {?} val - source object
* @return {?}
*/
function any(val) {
return val;
}
/**
* String tag (for ES6 string templates) for truncate starting whitespaces and eol-s
*
* @param {!Array<string>} strings
* @param {...?} expr
* @return {string}
*/
var rRgxp = /([\\/'*+?|()[\]{}.^$-])/g;
/**
* Escapes RegExp characters in a string
*
* @param {string} str - source string
* @return {string}
*/
function r(str) {
return str.replace(rRgxp, '\\$1');
}
var isNotPrimitiveRgxp = /^\(*\s*(.*?)\s*\)*$/;
var isNotPrimitiveMap = { 'false': true, 'null': true, 'true': true, 'undefined': true };
/**
* Returns true if the specified string can't be parse as a primitive value
*
* @param {string} str - source string
* @param {Object<string, boolean>=} opt_map - map of primitives
* @return {boolean}
*/
function isNotPrimitive(str, opt_map) {
str = ((isNotPrimitiveRgxp.exec(str) || [])[1] || '').trim();
return Boolean(str && isNaN(Number(str)) && !(opt_map || isNotPrimitiveMap)[str]);
}
var stringRender = {
'stringBuffer': true,
'stringConcat': true
};
var attrSeparators = {
'-': true,
':': true,
'_': true
};
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _COMMENTS;
var _BASE_SYS_ESCAPES;
var _SYS_ESCAPES;
var _STRONG_SYS_ESCAPES;
// The base directive separators
// >>>
var LEFT_BOUND = '{';
var ADV_LEFT_BOUND = '#';
// <<<
// The additional directive separators
// >>>
var I18N = '`';
var SINGLE_COMMENT = '///';
var MULT_COMMENT_START = '/*';
var MULT_COMMENT_END = '*/';
var COMMENTS = (_COMMENTS = {}, defineProperty(_COMMENTS, SINGLE_COMMENT, SINGLE_COMMENT), defineProperty(_COMMENTS, MULT_COMMENT_START, MULT_COMMENT_START), defineProperty(_COMMENTS, MULT_COMMENT_END, MULT_COMMENT_END), _COMMENTS);
var MICRO_TEMPLATE = '${';
var BASE_SHORTS = defineProperty({
'-': true
}, ADV_LEFT_BOUND, true);
var SHORTS = {};
Snakeskin$1.forEach(BASE_SHORTS, function (el, key) {
return SHORTS[key] = true;
});
// <<<
// The context modifiers
// >>>
// <<<
// Jade-Like
// >>>
var CONCAT = '&';
var CONCAT_END = '.';
var IGNORE = '|';
var INLINE = ' :: ';
// <<<
// The filter modifiers
// >>>
// <<<
// Escaping
// >>>
var BASE_SYS_ESCAPES = (_BASE_SYS_ESCAPES = {
'\\': true,
'"': true,
'\'': true,
'/': true
}, defineProperty(_BASE_SYS_ESCAPES, I18N, true), defineProperty(_BASE_SYS_ESCAPES, LEFT_BOUND, true), defineProperty(_BASE_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_BASE_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), _BASE_SYS_ESCAPES);
var SYS_ESCAPES = (_SYS_ESCAPES = {
'\\': true
}, defineProperty(_SYS_ESCAPES, I18N, true), defineProperty(_SYS_ESCAPES, LEFT_BOUND, true), defineProperty(_SYS_ESCAPES, ADV_LEFT_BOUND, true), defineProperty(_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), defineProperty(_SYS_ESCAPES, CONCAT, true), defineProperty(_SYS_ESCAPES, CONCAT_END, true), defineProperty(_SYS_ESCAPES, IGNORE, true), defineProperty(_SYS_ESCAPES, INLINE.trim().charAt(0), true), _SYS_ESCAPES);
Snakeskin$1.forEach(BASE_SHORTS, function (el, key) {
return SYS_ESCAPES[key.charAt(0)] = true;
});
var STRONG_SYS_ESCAPES = (_STRONG_SYS_ESCAPES = {
'\\': true
}, defineProperty(_STRONG_SYS_ESCAPES, I18N, true), defineProperty(_STRONG_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_STRONG_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), _STRONG_SYS_ESCAPES);
var MICRO_TEMPLATE_ESCAPES = defineProperty({
'\\': true
}, MICRO_TEMPLATE.charAt(0), true);
// <<<
// The reserved names
// >>>
var tmpSep = [];
Snakeskin$1.forEach(attrSeparators, function (el, key) {
tmpSep.push(r(key));
});
var attrKey = /([^\s=]+)/;
var Filters = Snakeskin$1.Filters;
/**
* Imports an object to Filters
*
* @param {!Object} filters - import object
* @param {?string=} [opt_namespace] - namespace for saving, for example foo.bar
* @return {!Object}
*/
Snakeskin$1.importFilters = function (filters, opt_namespace) {
var obj = Filters;
if (opt_namespace) {
Snakeskin$1.forEach(opt_namespace.split('.'), function (el) {
obj[el] = obj[el] || {};
obj = obj[el];
});
}
Snakeskin$1.forEach(filters, function (el, key) {
return obj[key] = el;
});
return this;
};
/**
* Sets parameters to the specified Snakeskin filter
*
* @param {(string|!Function)} filter - filter name or the filter function
* @param {Object} params - parameters
* @return {!Function}
*/
Snakeskin$1.setFilterParams = function (filter, params) {
var safe = params['safe'];
if (safe) {
params['bind'] = ['Unsafe'].concat(params['bind'] || []);
}
var tmp = void 0;
function wrapper(val, Unsafe) {
var _tmp2;
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
if (val && isFunction(Unsafe) && val instanceof Unsafe) {
var _tmp;
val.value = (_tmp = tmp).call.apply(_tmp, [this, val.value].concat(args));
return val;
}
return (_tmp2 = tmp).call.apply(_tmp2, [this, val].concat(args));
}
if (isString(filter)) {
if (safe) {
tmp = Filters[filter];
Filters[filter] = wrapper;
}
Filters[filter] = Filters[filter] || function (str) {
return str;
};
Filters[filter]['ssFilterParams'] = params;
return Filters[filter];
}
if (safe) {
tmp = filter;
filter = wrapper;
}
filter['ssFilterParams'] = params;
return any(filter);
};
/**
* Console API
* @const
*/
Filters['console'] = {
/**
* @param {?} val
* @return {?}
*/
'dir': function dir(val) {
var _console;
(_console = console).dir.apply(_console, arguments);
return val;
},
/**
* @param {?} val
* @return {?}
*/
'error': function error(val) {
var _console2;
(_console2 = console).error.apply(_console2, arguments);
return val;
},
/**
* @param {?} val
* @return {?}
*/
'info': function info(val) {
var _console3;
(_console3 = console).info.apply(_console3, arguments);
return val;
},
/**
* @param {?} val
* @return {?}
*/
'log': function log(val) {
var _console4;
(_console4 = console).log.apply(_console4, arguments);
return val;
},
/**
* @param {?} val
* @return {?}
*/
'table': function table(val) {
var _console5;
(_console5 = console).table.apply(_console5, arguments);
return val;
},
/**
* @param {?} val
* @return {?}
*/
'warn': function warn(val) {
var _console6;
(_console6 = console).warn.apply(_console6, arguments);
return val;
}
};
var entityMap = {
'"': '"',
'&': '&',
'\'': ''',
'<': '<',
'>': '>'
};
var escapeHTMLRgxp = /[<>"'/]|&(?!#|[a-z]+;)/g;
var escapeHTML = function escapeHTML(s) {
return entityMap[s] || s;
};
var uentityMap = {
''': '\'',
'/': '/',
'&': '&',
'>': '>',
'<': '<',
'"': '"'
};
var uescapeHTMLRgxp = /&|<|>|"|'|//g;
var uescapeHTML = function uescapeHTML(s) {
return uentityMap[s];
};
/**
* Escapes HTML entities from a string
*
* @param {?} val - source value
* @param {?=} [opt_Unsafe] - unsafe class constructor
* @param {?string=} [opt_attr] - type of attribute declaration
* @param {Object=} [opt_attrCache] - attribute cache object
* @param {?=} [opt_true] - true value
* @return {(string|!Snakeskin.HTMLObject|!Snakeskin.Node)}
*/
Filters['html'] = function (val, opt_Unsafe, opt_attr, opt_attrCache, opt_true) {
if (!val || val instanceof Snakeskin$1.Node) {
return val;
}
if (val instanceof Snakeskin$1.HTMLObject) {
Snakeskin$1.forEach(val.value, function (el, key, data) {
if (val.attr) {
opt_attrCache[key] = data[key] = el[0] !== opt_true ? [Filters['html'](el[0], opt_Unsafe, val.attr, opt_attrCache, opt_true)] : el;
} else {
data[key] = Filters['html'](el, opt_Unsafe);
}
});
return val;
}
if (isFunction(opt_Unsafe) && val instanceof opt_Unsafe) {
return val.value;
}
return String(opt_attr ? Filters[opt_attr](val) : val).replace(escapeHTMLRgxp, escapeHTML);
};
Snakeskin$1.setFilterParams('html', {
bind: ['Unsafe', '$attrType', function (o) {
return o.getVar('$attrs');
}, 'TRUE'],
test: function test(val) {
return isNotPrimitive(val);
}
});
Filters['htmlObject'] = function (val) {
if (val instanceof Snakeskin$1.HTMLObject) {
return '';
}
return val;
};
Snakeskin$1.setFilterParams('htmlObject', {
test: function test(val) {
return isNotPrimitive(val);
}
});
/**
* Replaces undefined to ''
*
* @param {?} val - source value
* @return {?}
*/
Filters['undef'] = function (val) {
return val !== undefined ? val : '';
};
Snakeskin$1.setFilterParams('undef', {
test: function test(val) {
return isNotPrimitive(val, { 'false': true, 'null': true, 'true': true });
}
});
/**
* Replaces escaped HTML entities to real content
*
* @param {?} val - source value
* @return {string}
*/
Filters['uhtml'] = function (val) {
return String(val).replace(uescapeHTMLRgxp, uescapeHTML);
};
var stripTagsRgxp = /<\/?[^>]+>/g;
/**
* Removes < > from a string
*
* @param {?} val - source value
* @return {string}
*/
Filters['stripTags'] = function (val) {
return String(val).replace(stripTagsRgxp, '');
};
var uriO = /%5B/g;
var uriC = /%5D/g;
/**
* Encodes URL
*
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI
* @param {?} val - source value
* @return {string}
*/
Filters['uri'] = function (val) {
return encodeURI(String(val)).replace(uriO, '[').replace(uriC, ']');
};
Snakeskin$1.setFilterParams('uri', {
safe: true
});
/**
* Converts a string to uppercase
*
* @param {?} val - source value
* @return {string}
*/
Filters['upper'] = function (val) {
return String(val).toUpperCase();
};
Snakeskin$1.setFilterParams('upper', {
safe: true
});
/**
* Converts the first letter of a string to uppercase
*
* @param {?} val - source value
* @return {string}
*/
Filters['ucfirst'] = function (val) {
val = String(val);
return val.charAt(0).toUpperCase() + val.slice(1);
};
Snakeskin$1.setFilterParams('ucfirst', {
safe: true
});
/**
* Converts a string to lowercase
*
* @param {?} val - source value
* @return {string}
*/
Filters['lower'] = function (val) {
return String(val).toLowerCase();
};
Snakeskin$1.setFilterParams('lower', {
safe: true
});
/**
* Converts the first letter of a string to lowercase
*
* @param {?} val - source value
* @return {string}
*/
Filters['lcfirst'] = function (val) {
val = String(val);
return val.charAt(0).toLowerCase() + val.slice(1);
};
Snakeskin$1.setFilterParams('lcfirst', {
safe: true
});
/**
* Removes whitespace from both ends of a string
*
* @param {?} val - source value
* @return {string}
*/
Filters['trim'] = function (val) {
return String(val).trim();
};
Snakeskin$1.setFilterParams('trim', {
safe: true
});
var spaceCollapseRgxp = /\s{2,}/g;
/**
* Removes whitespace from both ends of a string
* and collapses whitespace
*
* @param {?} val - source value
* @return {string}
*/
Filters['collapse'] = function (val) {
return String(val).replace(spaceCollapseRgxp, ' ').trim();
};
Snakeskin$1.setFilterParams('collapse', {
safe: true
});
/**
* Truncates a string to the specified length
* (at the end puts three dots)
*
* @param {?} val - source value
* @param {number} length - maximum length
* @param {?boolean=} opt_wordOnly - if is false, then the string will be truncated without
* taking into account the integrity of the words
*
* @param {?boolean=} opt_html - if is true, then the dots will be inserted as HTML-mnemonic
* @return {string}
*/
Filters['truncate'] = function (val, length, opt_wordOnly, opt_html) {
val = String(val);
if (!val || val.length <= length) {
return val;
}
var tmp = val.slice(0, length - 1);
var i = tmp.length,
lastInd = void 0;
while (i-- && opt_wordOnly) {
if (tmp.charAt(i) === ' ') {
lastInd = i;
} else if (lastInd !== undefined) {
break;
}
}
return (lastInd !== undefined ? tmp.slice(0, lastInd) : tmp) + (opt_html ? '…' : '…');
};
/**
* Returns a new string of repetitions of a string
*
* @param {?} val - source value
* @param {?number=} opt_num - number of repetitions
* @return {string}
*/
Filters['repeat'] = function (val, opt_num) {
return new Array(opt_num != null ? opt_num + 1 : 3).join(val);
};
Snakeskin$1.setFilterParams('repeat', {
safe: true
});
/**
* Removes a slice from a string
*
* @param {?} val - source value
* @param {(string|RegExp)} search - searching slice
* @return {string}
*/
Filters['remove'] = function (val, search) {
return String(val).replace(search, '');
};
/**
* Replaces a slice from a string to a new string
*
* @param {?} val - source value
* @param {(string|!RegExp)} search - searching slice
* @param {string} replace - string for replacing
* @return {string}
*/
Filters['replace'] = function (val, search, replace) {
return String(val).replace(search, replace);
};
var tplRgxp = /\${(.*?)}/g;
/**
* Returns a string result of the specified template
*
* @example
* 'hello ${name}' |tpl {name: 'Kobezzza'}
*
* @param {?} tpl - source template
* @param {!Object} map - map of values
* @return {string}
*/
Filters['tpl'] = function (tpl, map) {
return String(tpl).replace(tplRgxp, function (str, $0) {
return $0 in map ? map[$0] : '';
});
};
/**
* Converts a value to JSON
*
* @param {(Object|Array|string|number|boolean)} val - source value
* @return {string}
*/
Filters['json'] = function (val) {
return JSON.stringify(val);
};
/**
* Converts a value to a string
*
* @param {(Object|Array|string|number|boolean)} val - source value
* @return {string}
*/
Filters['string'] = function (val) {
if ((typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object' && val instanceof String === false) {
return JSON.stringify(val);
}
return String(val);
};
/**
* Parses a string as JSON
*
* @param {?} val - source value
* @return {?}
*/
Filters['parse'] = function (val) {
if (!isString(val)) {
return val;
}
return JSON.parse(val);
};
/**
* Sets a default value for the specified parameter
*
* @param {?} val - source value
* @param {?} def - value
* @return {?}
*/
Filters['default'] = function (val, def) {
return val === undefined ? def : val;
};
Snakeskin$1.setFilterParams('default', {
'!undef': true
});
var nl2brRgxp = /\r?\n|\n/g;
/**
* Replaces EOL symbols from a string to <br>
*
* @param {?} val - source value
* @param {(!Snakeskin.DocumentFragment|!Snakeskin.Element|undefined)} node - source node
* @param {string} renderMode - rendering mode of templates
* @param {boolean} stringResult - if is true, then the output will be saved to __STRING_RESULT__ as a string
* @param {string} doctype - document type
* @return {?}
*/
Filters['nl2br'] = function (val, node, renderMode, stringResult, doctype) {
var arr = val.split(nl2brRgxp);
var res = '';
for (var i = 0; i < arr.length; i++) {
var el = arr[i],
last = i === arr.length - 1;
if (!stringResult && !stringRender[renderMode]) {
Snakeskin$1.appendChild(any(node), el, renderMode);
if (!last) {
Snakeskin$1.appendChild(any(node), new Snakeskin$1.Element('br', renderMode), renderMode);
}
} else {
res += Filters['html'](el);
if (!last) {
res += '<br' + (doctype === 'xml' ? '/' : '') + '>';
}
}
}
return res;
};
Snakeskin$1.setFilterParams('nl2br', {
'!html': true,
bind: ['$0', function (o) {
return '\'' + o.renderMode + '\'';
}, function (o) {
return o.stringResult;
}, '$0', function (o) {
return '\'' + o.doctype + '\'';
}]
});
/**
* @param str
* @return {string}
*/
function dasherize(str) {
var res = str[0].toLowerCase();
for (var i = 1; i < str.length; i++) {
var el = str.charAt(i),
up = el.toUpperCase();
if (up === el && up !== el.toLowerCase()) {
res += '-' + el;
} else {
res += el;
}
}
return res.toLowerCase();
}
/**
* Escapes HTML entities from an attribute name
*
* @param {?} val - source value
* @return {string}
*/
Filters['attrKey'] = function (val) {
var tmp = attrKey.exec(String(val));
return tmp && tmp[1] || 'undefined';
};
/**
* Escapes HTML entities from an attribute group
*
* @param {?} val - source value
* @return {string}
*/
Filters['attrKeyGroup'] = function (val) {
var tmp = attrKey.exec(String(val));
return tmp && tmp[1] || '';
};
var attrValRgxp = /(javascript)(:|;)/g;
/**
* Escapes HTML entities from an attribute value
*
* @param {?} val - source value
* @return {string}
*/
Filters['attrValue'] = function (val) {
return String(val).replace(attrValRgxp, '$1$2');
};
/**
* Sets attributes to a node
*
* @param {?} val - source value
* @param {?} Unsafe - unsafe class constructor
* @param {string} doctype - document type
* @param {string} type - type of attribute declaration
* @param {!Object} cache - attribute cache object
* @param {!Boolean} TRUE - true value
* @param {!Boolean} FALSE - false value
* @return {(string|Unsafe|Snakeskin.HTMLObject)}
*/
Filters['attr'] = function (val, Unsafe, doctype, type, cache, TRUE, FALSE) {
if (type !== 'attrKey' || !isObject(val)) {
if (isFunction(Unsafe) && val instanceof Unsafe) {
return val;
}
return String(val);
}
var localCache = {};
/**
* @param {Object} obj
* @param {?string=} opt_prfx
* @return {Snakeskin.HTMLObject}
*/
function convert(obj, opt_prfx) {
opt_prfx = opt_prfx || '';
Snakeskin$1.forEach(obj, function (el, key) {
if (el === FALSE) {
return;
}
if (isObject(el)) {
var group = Filters['attrKeyGroup'](key);
return convert(el, opt_prfx + (!group.length || attrSeparators[group.slice(-1)] ? group : group + '-'));
}
var tmp = dasherize(opt_prfx + key);
cache[tmp] = localCache[tmp] = [el];
});
return new Snakeskin$1.HTMLObject(localCache, 'attrValue');
}
return convert(val);
};
Snakeskin$1.setFilterParams('attr', {
'!html': true,
bind: ['Unsafe', function (o) {
return '\'' + o.doctype + '\'';
}, '$attrType', function (o) {
return o.getVar('$attrs');
}, 'TRUE', 'FALSE'],
test: function test(val) {
return isNotPrimitive(val);
}
});
/**
* Returns a valid template name for overriding
*
* @param {string} name - base name
* @param {!Object} store - link to a store object
* @param {string} scope - scope string
* @param {boolean} init - true, if a template already defined
* @return {string}
*/
Filters['super'] = function (name, store, scope, init) {
var cache = store.templates = store.templates || {},
nm = scope + name;
cache[nm] = cache[nm] || [name];
if (init) {
return cache[nm].slice(-2)[0] || name;
}
name = name + Math.random().toString().slice(2);
cache[nm].push(name);
return name;
};
Snakeskin$1.setFilterParams('super', {
'!html': true,
bind: [function (o) {
return o.getVar('__STORE__');
}, function (o) {
return JSON.stringify(o.scope[0]);
}, function (o) {
return Boolean(o.vars[o.tplName]);
}]
});
return Snakeskin$1;
})));