UNPKG

starplate

Version:

View engine built on incremental-dom

261 lines (217 loc) 6.12 kB
'use strict'; /** * Module dependencies. */ Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _view = require('./view'); /** * Ensures an object. * * @private * @function * @name ensureObject * @param {Mixed} o * @return {Object} */ var ensureObject = function ensureObject(o) { return null != o && 'object' == typeof o ? o : {}; }; /** * Recursively makes an object safe for partial * usage. * * @private * @function * @name makeSafeObject * @param {Mixed} o * @return {Mixed} */ function makeSafeObject(o) { var out = String(); if ('function' == typeof o) { return o; } if (null == o || 'object' != typeof o) { if ('string' == typeof o) { try { return JSON.stringify(JSON.parse(o)); } catch (e) {} } return JSON.stringify(o); } if ('object' == typeof o) { for (var k in o) { o[k] = makeSafeObject(o[k]); }if (Array.isArray(o)) { out += '['; for (var k in o) { out += o[k] + ', '; }out += ']'; } else { out += '{'; for (var k in o) { out += k + ': ' + o[k] + ', '; }out += '}'; } } return out; } /** * Template class. * * @public * @class Template */ var Template = (function () { _createClass(Template, null, [{ key: 'createPartial', /** * Creates a function that accepts an optional * object creating a variable scope for the * template string. You may pass a string or * function. If a function is passed it is * called when the partial is created. All * data is propagated to functions passed to * this function. * * @public * @static * @method * @name createPartial * @param {String|Function} * @return {Function} (data) => {String} */ value: function createPartial(string) { var _this = this; if ('string' == typeof string) string = string.replace(RegExp('`', 'g', '\\`')); /** * Partial template function that accepts * an optional variable scope object. * * @public * @function * @param {Object} [data = {}] * @return {String} */ return function (data, scope) { data = ensureObject(data); scope = scope || _this; var wrap = string; var header = Object.keys(data).filter(function (key) { return false == _view.helpers.has(key); }).map(function (key) { var value = makeSafeObject(data[key]); return key + ' = ' + value; }); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _view.helpers.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var kv = _step.value; header.push(kv[0] + ' = ' + makeSafeObject(kv[1])); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } header = header.length ? 'var ' + header.join(', ') + ';' : ''; // allow use of #{} inside of ES6 template strings if ('string' == typeof string) string = string.replace(/\#\{/g, '${'); if ('function' != typeof wrap) wrap = new Function('data', '\'use strict\'; ' + header + ' return `' + string + '`'); var src = '\'use strict\'; return wrap.call(this, data);'; var fn = new Function('data', 'wrap', src); return String(fn.call(scope, data, wrap) || ''); }; } /** * Template class constructor. * * @public * @constructor * @param {String|Function} source */ }]); function Template(source) { _classCallCheck(this, Template); /** * The template source. * * @public * @type {Function|String} * @name source */ this.source = null; /** * A partial function used to * render a template. * * @public * @method * @name render * @param {Object} [data = {}] */ this.render = null; // intial definition this.define(source); } /** * Defines the template source. * * @public * @method * @name define * @param {String|Function} source */ _createClass(Template, [{ key: 'define', value: function define(source) { this.source = source; this.render = Template.createPartial(source); return this; } /** * Implements toString. * * @public * @method * @name toString * @return {String} */ }, { key: 'toString', value: function toString() { return String(this.source || ''); } /** * Implements valueOf. * * @public * @method * @name valueOf * @return {Element} */ }, { key: 'valueOf', value: function valueOf() { return this.source; } }]); return Template; })(); exports['default'] = Template; module.exports = exports['default'];