From 8d3c890f90c6bb48cb1951da4a54f653edddbd97 Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Mon, 29 Jul 2013 17:13:57 -0500 Subject: [PATCH 01/99] Allow the modulo operator in evaluation context. Closes #30 --- README.md | 2 +- bower.json | 2 +- js/tmpl.js | 10 +++++----- js/tmpl.min.js | 2 +- package.json | 2 +- test/test.js | 13 ++++++++++++- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 294599b..de42e76 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,7 @@ The template contents are matched and replaced using the regular expression **tm To use different tags for the template syntax, override **tmpl.regexp** with a modified regular expression, by exchanging all occurrences of "{%" and "%}", e.g. with "[%" and "%]": ```js -tmpl.regexp = /([\s'\\])(?![^%]*%\])|(?:\[%(=|#)([\s\S]+?)%\])|(\[%)|(%\])/g; +tmpl.regexp = /([\s'\\])(?!(?:[^[]|\[(?!%))*%\])|(?:\[%(=|#)([\s\S]+?)%\])|(\[%)|(%\])/g; ``` By default, the plugin preserves whitespace (newlines, carriage returns, tabs and spaces). To strip unnecessary whitespace, you can override the **tmpl.func** function, e.g. with the following code: diff --git a/bower.json b/bower.json index de43e17..460e6a4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.2.2", + "version": "2.3.0", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ diff --git a/js/tmpl.js b/js/tmpl.js index c7b1f4f..02144fd 100644 --- a/js/tmpl.js +++ b/js/tmpl.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates 2.2.0 + * JavaScript Templates 2.3.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -12,7 +12,7 @@ * http://ejohn.org/blog/javascript-micro-templating/ */ -/*jslint evil: true, regexp: true */ +/*jslint evil: true, regexp: true, unparam: true */ /*global document, define */ (function ($) { @@ -34,15 +34,15 @@ tmpl.load = function (id) { return document.getElementById(id).innerHTML; }; - tmpl.regexp = /([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g; + tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g; tmpl.func = function (s, p1, p2, p3, p4, p5) { - if (p1) { // whitespace, quote and backspace in interpolation context + if (p1) { // whitespace, quote and backspace in HTML context return { "\n": "\\n", "\r": "\\r", "\t": "\\t", " " : " " - }[s] || "\\" + s; + }[p1] || "\\" + p1; } if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%} if (p2 === "=") { diff --git a/js/tmpl.min.js b/js/tmpl.min.js index 2c19a7f..a7cae52 100644 --- a/js/tmpl.min.js +++ b/js/tmpl.min.js @@ -1 +1 @@ -!function(e){"use strict";var n=function(e,t){var r=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?r(t,n):function(e){return r(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,r,c,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[e]||"\\"+e:t?"="===t?"'+_e("+r+")+'":"'+"+r+"+'":c?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},n.encode=function(e){return String(e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):e.tmpl=n}(this); \ No newline at end of file +!function(e){"use strict";var n=function(e,t){var r=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?r(t,n):function(e){return r(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,r,c,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+r+")+'":"'+"+r+"+'":c?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},n.encode=function(e){return String(e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):e.tmpl=n}(this); \ No newline at end of file diff --git a/package.json b/package.json index de43e17..460e6a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.2.2", + "version": "2.3.0", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ diff --git a/test/test.js b/test/test.js index 461d391..0d5093e 100644 --- a/test/test.js +++ b/test/test.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates Test 2.2.0 + * JavaScript Templates Test 2.3.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -250,6 +250,17 @@ ); }); + it('Modulo operator', function () { + expect( + tmpl( + '{% if (o.list.length % 5 === 0) { %}5 list items{% } %}', + data + ).replace(/[\r\n]/g, '') + ).to.be( + '5 list items' + ); + }); + }); }( From 508e6ef7f719232bd899b328164e1b89eeec3a6c Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Thu, 15 Aug 2013 11:04:34 -0500 Subject: [PATCH 02/99] Removed scripts and bin section from bower.json. Closes #32 --- bower.json | 8 +------- package.json | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/bower.json b/bower.json index 460e6a4..175a7e0 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.3.0", + "version": "2.3.1", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ @@ -35,11 +35,5 @@ "expect.js": "0.2.0", "uglify-js": "2.3.6" }, - "scripts": { - "test": "mocha --reporter spec" - }, - "bin": { - "tmpl.js": "js/compile.js" - }, "main": "js/tmpl.js" } diff --git a/package.json b/package.json index 460e6a4..4660cee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.3.0", + "version": "2.3.1", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ From eb72edb85f517627bbbcade738a71f2b499284ec Mon Sep 17 00:00:00 2001 From: Sebastian Tschan Date: Fri, 6 Sep 2013 10:23:24 -0500 Subject: [PATCH 03/99] Print out falsy values except undefined and null. Closes #35 --- bower.json | 2 +- css/demo.css | 2 +- index.html | 4 ++-- js/compile.js | 2 +- js/demo.js | 2 +- js/runtime.js | 4 ++-- js/tmpl.js | 8 ++++---- js/tmpl.min.js | 2 +- package.json | 6 +++--- test/index.html | 2 +- test/test.js | 54 +++++++++++++++++++++++++++++++++++++------------ 11 files changed, 58 insertions(+), 30 deletions(-) diff --git a/bower.json b/bower.json index 175a7e0..364ff05 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.3.1", + "version": "2.4.0", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ diff --git a/css/demo.css b/css/demo.css index 0b7fca8..186844a 100644 --- a/css/demo.css +++ b/css/demo.css @@ -1,5 +1,5 @@ /* - * JavaScript Templates Demo CSS 2.2.1 + * JavaScript Templates Demo CSS 2.4.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2013, Sebastian Tschan diff --git a/index.html b/index.html index 6a94eb2..01ed76c 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - + diff --git a/js/compile.js b/js/compile.js index 0c285bf..84ff2ce 100755 --- a/js/compile.js +++ b/js/compile.js @@ -1,6 +1,6 @@ #!/usr/bin/env node /* - * JavaScript Templates Compiler 2.2.0 + * JavaScript Templates Compiler 2.4.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan diff --git a/js/demo.js b/js/demo.js index a7ab261..afcedc2 100644 --- a/js/demo.js +++ b/js/demo.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates Demo JS 2.2.1 + * JavaScript Templates Demo JS 2.4.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2013, Sebastian Tschan diff --git a/js/runtime.js b/js/runtime.js index 514454a..672fcc4 100644 --- a/js/runtime.js +++ b/js/runtime.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates Runtime 2.2.0 + * JavaScript Templates Runtime 2.4.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -29,7 +29,7 @@ "'" : "'" }; tmpl.encode = function (s) { - return String(s).replace( + return (s == null ? "" : "" + s).replace( tmpl.encReg, function (c) { return tmpl.encMap[c] || ""; diff --git a/js/tmpl.js b/js/tmpl.js index 02144fd..bb3d4cd 100644 --- a/js/tmpl.js +++ b/js/tmpl.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates 2.3.0 + * JavaScript Templates 2.4.0 * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -48,7 +48,7 @@ if (p2 === "=") { return "'+_e(" + p3 + ")+'"; } - return "'+" + p3 + "+'"; + return "'+(" + p3 + "==null?'':" + p3 + ")+'"; } if (p4) { // evaluation start tag: {% return "';"; @@ -66,7 +66,7 @@ "'" : "'" }; tmpl.encode = function (s) { - return String(s).replace( + return (s == null ? "" : "" + s).replace( tmpl.encReg, function (c) { return tmpl.encMap[c] || ""; @@ -74,7 +74,7 @@ ); }; tmpl.arg = "o"; - tmpl.helper = ",print=function(s,e){_s+=e&&(s||'')||_e(s);}" + + tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" + ",include=function(s,d){_s+=tmpl(s,d);}"; if (typeof define === "function" && define.amd) { define(function () { diff --git a/js/tmpl.min.js b/js/tmpl.min.js index a7cae52..bd82354 100644 --- a/js/tmpl.min.js +++ b/js/tmpl.min.js @@ -1 +1 @@ -!function(e){"use strict";var n=function(e,t){var r=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?r(t,n):function(e){return r(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,r,c,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+r+")+'":"'+"+r+"+'":c?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},n.encode=function(e){return String(e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):e.tmpl=n}(this); \ No newline at end of file +!function(e){"use strict";var n=function(e,t){var c=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?c(t,n):function(e){return c(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,c,r,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+c+")+'":"'+("+c+"==null?'':"+c+")+'":r?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"<",">":">","&":"&",'"':""","'":"'"},n.encode=function(e){return(null==e?"":""+e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):e.tmpl=n}(this); \ No newline at end of file diff --git a/package.json b/package.json index 4660cee..4525ccf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-tmpl", - "version": "2.3.1", + "version": "2.4.0", "title": "JavaScript Templates", "description": "< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.", "keywords": [ @@ -31,9 +31,9 @@ } ], "devDependencies": { - "mocha": "1.11.0", + "mocha": "1.12.1", "expect.js": "0.2.0", - "uglify-js": "2.3.6" + "uglify-js": "2.4.0" }, "scripts": { "test": "mocha --reporter spec" diff --git a/test/index.html b/test/index.html index dcca834..89f5391 100644 --- a/test/index.html +++ b/test/index.html @@ -1,7 +1,7 @@ - + - + diff --git a/js/compile.js b/js/compile.js index 84ff2ce..0bf0144 100755 --- a/js/compile.js +++ b/js/compile.js @@ -1,6 +1,6 @@ #!/usr/bin/env node /* - * JavaScript Templates Compiler 2.4.0 + * JavaScript Templates Compiler * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -53,7 +53,7 @@ if (index > 1) { stats = fs.statSync(file); if (!stats.isFile()) { - console.error(file + ' is not a file.'); + console.error(file + " is not a file."); return; } content = fs.readFileSync(file, "utf8"); @@ -74,7 +74,7 @@ } }); if (!list.length) { - console.error('Missing input file.'); + console.error("Missing input file."); return; } // Combine the generated functions as cache of the minimal runtime: diff --git a/js/demo.js b/js/demo.js index afcedc2..2862415 100644 --- a/js/demo.js +++ b/js/demo.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates Demo JS 2.4.0 + * JavaScript Templates Demo * https://github.com/blueimp/JavaScript-Templates * * Copyright 2013, Sebastian Tschan diff --git a/js/runtime.js b/js/runtime.js index c4121fd..cb4c27e 100644 --- a/js/runtime.js +++ b/js/runtime.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates Runtime 2.4.1 + * JavaScript Templates Runtime * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -9,10 +9,10 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint sloppy: true */ /*global define */ (function ($) { + "use strict"; var tmpl = function (id, data) { var f = tmpl.cache[id]; return data ? f(data, tmpl) : function (data) { diff --git a/js/tmpl.js b/js/tmpl.js index 9380053..90b9e42 100644 --- a/js/tmpl.js +++ b/js/tmpl.js @@ -1,5 +1,5 @@ /* - * JavaScript Templates 2.4.1 + * JavaScript Templates * https://github.com/blueimp/JavaScript-Templates * * Copyright 2011, Sebastian Tschan @@ -12,7 +12,7 @@ * http://ejohn.org/blog/javascript-micro-templating/ */ -/*jslint evil: true, regexp: true, unparam: true */ +/*jshint evil: true */ /*global document, define */ (function ($) { @@ -21,7 +21,7 @@ var f = !/[^\w\-\.:]/.test(str) ? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str)) : new Function( - tmpl.arg + ',tmpl', + tmpl.arg + ",tmpl", "var _e=tmpl.encode" + tmpl.helper + ",_s='" + str.replace(tmpl.regexp, tmpl.func) + "';return _s;" diff --git a/test/index.html b/test/index.html index 9bdd78b..5be1e78 100644 --- a/test/index.html +++ b/test/index.html @@ -1,7 +1,7 @@ JavaScript Templates Demo - +

JavaScript Templates Demo

-

< 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
-Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.

+

1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
+Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.