muu

DEPRECATED lightweight JS framework
git clone https://git.ce9e.org/muu.git

commit
cddee052173f6a3a7ab401963a9f78f92016f8ad
parent
37db3ac93095dea97f496ba0f0fa94bc03440395
Author
Tobias Bengfort <tobias.bengfort@gmx.net>
Date
2015-08-28 19:31
Merge branch 'feature-refactor-template'

Diffstat

M src/muu-template.js 194 +++++++++++++++++++++++++++++++------------------------------

1 files changed, 100 insertions, 94 deletions


diff --git a/src/muu-template.js b/src/muu-template.js

@@ -68,19 +68,28 @@ define('muu-template', ['muu-js-helpers', 'muu-dom-helpers'], function(_, $) {
   68    68     var openTag = '{{';
   69    69     var closeTag = '}}';
   70    70 
   -1    71     /**
   -1    72      * @param {string} key
   -1    73      * @param {Object} data
   -1    74      * @return {*}
   -1    75      * @nosideeffects
   -1    76      */
   71    77     var getValue = function(key, data) {
   72    78         return key === 'this' ? data : data[key];
   73    79     };
   74    80 
   75    -1     var parseVariableTemplate = function(template) {
   76    -1         var content = template.slice(2, -2);
   77    -1 
   78    -1         if (template.indexOf(':') === -1) {
   -1    81     /**
   -1    82      * @param {string} tag
   -1    83      * @return {function(*): string}
   -1    84      * @nosideeffects
   -1    85      */
   -1    86     var parseVariable = function(tag) {
   -1    87         if (tag.indexOf(':') === -1) {
   79    88             return function(data) {
   80    -1                 return $.escapeHtml(getValue(content, data) || '');
   -1    89                 return $.escapeHtml(getValue(tag, data) || '');
   81    90             };
   82    91         } else {
   83    -1             var pairs = content.split(',').map(function(pair) {
   -1    92             var pairs = _.map(tag.split(','), function(pair) {
   84    93                 var v = pair.split(':');
   85    94                 var key = v[0].trim();
   86    95                 var value = v.slice(1).join(':').trim();
@@ -88,81 +97,65 @@ define('muu-template', ['muu-js-helpers', 'muu-dom-helpers'], function(_, $) {
   88    97             });
   89    98 
   90    99             return function(data) {
   91    -1                 var results = [];
   92    -1 
   93    -1                 for (var i = 0; i < pairs.length; i++) {
   94    -1                     var key = pairs[i][0];
   95    -1                     var value = pairs[i][1];
   96    -1 
   97    -1                     if (getValue(value, data)) {
   98    -1                         results.push(key);
   99    -1                     }
  100    -1                 }
   -1   100                 var results = _.map(_.filter(pairs, function(pair) {
   -1   101                     return getValue(pair[1], data);
   -1   102                 }), function(pair) {
   -1   103                     return pair[0];
   -1   104                 });
  101   105 
  102   106                 return $.escapeHtml(results.join(' '));
  103   107             };
  104   108         }
  105   109     };
  106   110 
  107    -1     var parseLoopTemplate = function(tag, afterTag, inverted) {
  108    -1         var tagName = tag.slice(3, -2);
  109    -1 
  110    -1         var v = parseTemplate(afterTag, tagName);
  111    -1         var inner = v[0];
  112    -1         var afterLoop = v[1];
  113    -1 
  114    -1         var render = function(data) {
  115    -1             if (inverted) {
  116    -1                 if (getValue(tagName, data)) {
  117    -1                     return '';
  118    -1                 } else {
  119    -1                     return inner(data);
  120    -1                 }
  121    -1             } else {
  122    -1                 if (_.isArray(getValue(tagName, data))) {
  123    -1                     var result = '';
  124    -1                     for (var i = 0; i < getValue(tagName, data).length; i++) {
  125    -1                         result += inner(getValue(tagName, data)[i]);
   -1   111     /**
   -1   112      * @param {string} tag
   -1   113      * @param {string} afterTag
   -1   114      * @param {boolean} [inverted]
   -1   115      * @return {{render: function(*): string, afterBlock: string}}
   -1   116      * @nosideeffects
   -1   117      */
   -1   118     var parseLoop = function(tag, afterTag, inverted) {
   -1   119         var inner = parseTemplate(afterTag, tag);
   -1   120 
   -1   121         return {
   -1   122             render: function(data) {
   -1   123                 var value = getValue(tag, data);
   -1   124                 var result = '';
   -1   125 
   -1   126                 if (inverted) {
   -1   127                     if (!value) {
   -1   128                         result += inner.render(data);
  126   129                     }
  127    -1                     return result;
  128    -1                 } else if (getValue(tagName, data)) {
  129    -1                     return inner(data);
  130   130                 } else {
  131    -1                     return '';
   -1   131                     if (_.isArray(value)) {
   -1   132                         for (var i = 0; i < value.length; i++) {
   -1   133                             result += inner.render(value[i]);
   -1   134                         }
   -1   135                     } else if (value) {
   -1   136                         result += inner.render(data);
   -1   137                     }
  132   138                 }
  133    -1             }
  134    -1         };
  135   139 
  136    -1         return [render, afterLoop];
  137    -1     };
  138    -1 
  139    -1     var concat = function(a) {
  140    -1         var last = a.pop();
  141    -1 
  142    -1         if (_.isArray(last)) {
  143    -1             a.push(last[0]);
  144    -1             return [concat(a), last[1]];
  145    -1         } else {
  146    -1             a.push(last);
  147    -1 
  148    -1             return function(data) {
  149    -1                 return a.map(function(item) {
  150    -1                     if (_.isString(item)) {
  151    -1                         return item;
  152    -1                     } else if (_.isFunction(item)) {
  153    -1                         return item(data);
  154    -1                     }
  155    -1                 }).join('');
  156    -1             };
  157    -1         }
   -1   140                 return result;
   -1   141             },
   -1   142             afterBlock: inner.afterBlock
   -1   143         };
  158   144     };
  159   145 
   -1   146     /**
   -1   147      * @param {string} template
   -1   148      * @param {string} [loopName]
   -1   149      * @return {{render: function(*): string, afterBlock: string}}
   -1   150      * @nosideeffects
   -1   151      */
  160   152     var parseTemplate = function(template, loopName) {
  161   153         var openIndex = template.indexOf(openTag);
  162   154         if (openIndex === -1) {
  163   155             if (loopName === undefined) {
  164    -1                 return function() {
  165    -1                     return template;
   -1   156                 return {
   -1   157                     render: function() { return template; },
   -1   158                     afterBlock: ''
  166   159                 };
  167   160             } else {
  168   161                 throw new Error('unclosed loop: ' + loopName);
@@ -171,44 +164,57 @@ define('muu-template', ['muu-js-helpers', 'muu-dom-helpers'], function(_, $) {
  171   164             var beforeTag = template.slice(0, openIndex);
  172   165             var tmp = template.slice(openIndex);
  173   166 
  174    -1             var closeIndex = tmp.indexOf(closeTag) + 2;
  175    -1             if (closeIndex === 1) {
   -1   167             var closeIndex = tmp.indexOf(closeTag);
   -1   168             if (closeIndex === -1) {
  176   169                 throw new Error('unclosed tag: ' + tmp);
  177   170             }
  178    -1             var tag = tmp.slice(0, closeIndex);
  179    -1             var afterTag = tmp.slice(closeIndex);
  180    -1 
  181    -1             if (tag.lastIndexOf('{{#', 0) === 0) {
  182    -1                 var v = parseLoopTemplate(tag, afterTag);
  183    -1                 var loop = v[0];
  184    -1                 var after = parseTemplate(v[1], loopName);
  185    -1                 return concat([beforeTag, loop, after]);
  186    -1             } else if (tag.lastIndexOf('{{^', 0) === 0) {
  187    -1                 var v = parseLoopTemplate(tag, afterTag, true);
  188    -1                 var loop = v[0];
  189    -1                 var after = parseTemplate(v[1], loopName);
  190    -1                 return concat([beforeTag, loop, after]);
  191    -1             } else if (tag.lastIndexOf('{{!', 0) === 0) {
  192    -1                 var after = parseTemplate(afterTag, loopName);
  193    -1                 return concat([beforeTag, after]);
  194    -1             } else if (tag.lastIndexOf('{{/', 0) === 0) {
  195    -1                 if (tag.slice(3, -2) === loopName) {
  196    -1                     var render = function() {
  197    -1                         return beforeTag;
  198    -1                     };
  199    -1                     return [render, afterTag];
  200    -1                 } else {
   -1   171             var tag = tmp.slice(openTag.length, closeIndex);
   -1   172             var afterTag = tmp.slice(closeIndex + closeTag.length);
   -1   173 
   -1   174             var loadNext = true;
   -1   175             var current = {
   -1   176                 render: function() { return ''; },
   -1   177                 afterBlock: afterTag
   -1   178             };
   -1   179 
   -1   180             if (tag.lastIndexOf('#', 0) === 0) {
   -1   181                 current = parseLoop(tag.substr(1), afterTag);
   -1   182             } else if (tag.lastIndexOf('^', 0) === 0) {
   -1   183                 current = parseLoop(tag.substr(1), afterTag, true);
   -1   184             } else if (tag.lastIndexOf('/', 0) === 0) {
   -1   185                 loadNext = false;
   -1   186                 if (tag.substr(1) !== loopName) {
  201   187                     throw new Error('unexpected closing loop: ' + tag);
  202   188                 }
   -1   189             } else if (tag.lastIndexOf('!', 0) !== 0) {
   -1   190                 current.render = parseVariable(tag);
   -1   191             }
   -1   192 
   -1   193             if (loadNext) {
   -1   194                 var next = parseTemplate(current.afterBlock, loopName);
   -1   195                 return {
   -1   196                     render: function(data) {
   -1   197                         return beforeTag + current.render(data) + next.render(data);
   -1   198                     },
   -1   199                     afterBlock: next.afterBlock
   -1   200                 };
  203   201             } else {
  204    -1                 var render = parseVariableTemplate(tag);
  205    -1                 var after = parseTemplate(afterTag, loopName);
  206    -1                 return concat([beforeTag, render, after]);
   -1   202                 return {
   -1   203                     render: function(data) {
   -1   204                         return beforeTag + current.render(data);
   -1   205                     },
   -1   206                     afterBlock: current.afterBlock
   -1   207                 };
  207   208             }
  208   209         }
  209   210     };
  210   211 
   -1   212     var cache = {};
   -1   213 
  211   214     return function(template, data) {
  212    -1         return parseTemplate(template)(data);
   -1   215         if (cache[template] === undefined) {
   -1   216             cache[template] = parseTemplate(template);
   -1   217         }
   -1   218         return cache[template].render(data);
  213   219     };
  214   220 });