UNPKG

wigjs

Version:

Minimalistic, scalable, extensible, dependency-less Front-end factory for HTML5 applications

134 lines (119 loc) 3.9 kB
/** * @class * @classdesc Compiles templates and caches them. */ var Compiler = module.Compiler = Class.extend({ start: '{{', end: '}}', constructor: function () { this.templateCache = new Registry(); /** * RegExp to find the placeholders inside the templates. * @type {RegExp} */ this.regExp = new RegExp( this.start + '\\s*[\\w\\d\\.]+\\s*' + this.end, 'gim' ); }, /** * Discovers the nested/attribute to fetch from attribute passed. * @param {string} sanitized - bound * @param {Object} map - attributes * @returns {String} */ replacer: function (sanitized, map) { var result = map[sanitized[0]], length = sanitized.length, ns = map, i = 0; // digging down the namespace if (length > 1) { while (ns && i < length) { ns = ns[sanitized[i++]]; } result = ns; } return result; }, /** * Memoizes a method for a placeholder to access attributes. * @param {String} placeholder - eg: "{{ myPlaceholder }}" * @type {Function} * @returns {Function} */ compilerMethodFactory: function (placeholder) { var sanitized = placeholder.substring( this.start.length, placeholder.length - this.end.length ); sanitized = sanitized.trim().split("."); return this.replacer.bind(this, sanitized); }, /** * Generates a compiled, cache-able template to reuse. * @param {String} text - eg: "hakuna {{ timon }} matata" * @type {Function} * @returns {Array} */ generateCompiledResult: function (text) { // placeholders to replace var placeholders = text.match(this.regExp), i = 0, splitText, compiledResults; if (placeholders) { // actual template content splitText = text.split(this.regExp); // precompiled array of content compiledResults = []; while (placeholders.length > 0) { compiledResults.push( splitText[i], this.compilerMethodFactory(placeholders.shift()) ); i += 1; } compiledResults.push(splitText[i]); // cache template this.templateCache.set(text, compiledResults); } return (this.templateCache.get(text) || text); }, /** * Pre-compiles and caches the given template. * If attributes is defined, it will compile the template into a String. * @param {String} text - eg: "hakuna {{ timon }} matata" * @param {Object} [context] - context * @returns {String} */ compile: function (text, context) { var compiledTemplate = this.templateCache.get(text), markup = "", item, i, l; if (!compiledTemplate) { compiledTemplate = this.generateCompiledResult(text); } // if a map of key-value pairs is provided, compile too if (context && typeof context === 'object') { for (i = 0, l = compiledTemplate.length; i < l; i++) { item = compiledTemplate[i]; markup += (typeof item === 'function' ? item(context) : item); } } return markup; }, /** * Returns the specified comiled markups. * @param {String} template - eg: "hakuna {{ timon }} matata" * @returns {String} */ getCompiled: function (template) { return this.templateCache.get(template); }, /** * Disposes all previously compiled and cached markups. */ disposeMarkups: function () { this.templateCache.empty(); } });