Skip to content
Browse files

bugfix for evaluate blocks with multiple nested closing } } } separat…

…ed by newlines only
  • Loading branch information...
1 parent aa43131 commit 719140a03db37897603d8c6f4e88587dd6aa6490 @olado committed Sep 5, 2013
Showing with 37 additions and 33 deletions.
  1. +34 −30 benchmarks/templating/doT.js
  2. +2 −2 doT.js
  3. +1 −1 doT.min.js
View
64 benchmarks/templating/doT.js
@@ -1,53 +1,51 @@
// doT.js
// 2011, Laura Doktorova, https://github.com/olado/doT
-//
-// doT.js is an open source component of http://bebedo.com
// Licensed under the MIT license.
-//
+
(function() {
"use strict";
var doT = {
- version: '0.2.0',
+ version: '1.0.1',
templateSettings: {
- evaluate: /\{\{([\s\S]+?)\}\}/g,
+ evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
+ useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
+ defineParams:/^\s*([\w$]+):([\s\S]+)/,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
- varname: 'it',
- strip: true,
- append: true,
+ varname: 'it',
+ strip: true,
+ append: true,
selfcontained: false
},
template: undefined, //fn, compile template
compile: undefined //fn, for express
};
- var global = (function(){ return this || (0,eval)('this'); }());
-
if (typeof module !== 'undefined' && module.exports) {
module.exports = doT;
} else if (typeof define === 'function' && define.amd) {
define(function(){return doT;});
} else {
- global.doT = doT;
+ (function(){ return this || (0,eval)('this'); }()).doT = doT;
}
function encodeHTMLSource() {
var encodeHTMLRules = { "&": "&#38;", "<": "&#60;", ">": "&#62;", '"': '&#34;', "'": '&#39;', "/": '&#47;' },
matchHTML = /&(?!#?\w+;)|<|>|"|'|\//g;
- return function(code) {
- return code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : code;
+ return function() {
+ return this ? this.replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : this;
};
}
- global.encodeHTML = encodeHTMLSource();
+ String.prototype.encodeHTML = encodeHTMLSource();
var startend = {
- append: { start: "'+(", end: ")+'", startencode: "'+encodeHTML(" },
- split: { start: "';out+=(", end: ");out+='", startencode: "';out+=encodeHTML("}
+ append: { start: "'+(", end: ")+'", endencode: "||'').toString().encodeHTML()+'" },
+ split: { start: "';out+=(", end: ");out+='", endencode: "||'').toString().encodeHTML();out+='"}
}, skip = /$^/;
function resolveDefs(c, block, def) {
@@ -58,15 +56,26 @@
}
if (!(code in def)) {
if (assign === ':') {
- def[code]= value;
+ if (c.defineParams) value.replace(c.defineParams, function(m, param, v) {
+ def[code] = {arg: param, text: v};
+ });
+ if (!(code in def)) def[code]= value;
} else {
- eval("def['"+code+"']=" + value);
+ new Function("def", "def['"+code+"']=" + value)(def);
}
}
return '';
})
.replace(c.use || skip, function(m, code) {
- var v = eval(code);
+ if (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
+ if (def[d] && def[d].arg && param) {
+ var rw = (d+":"+param).replace(/'|\\/g, '_');
+ def.__exp = def.__exp || {};
+ def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
+ return s + "def.__exp['"+rw+"']";
+ }
+ });
+ var v = new Function("def", "return " + code)(def);
return v ? resolveDefs(c, v, def) : v;
});
}
@@ -77,13 +86,8 @@
doT.template = function(tmpl, c, def) {
c = c || doT.templateSettings;
- var cse = c.append ? startend.append : startend.split, str, needhtmlencode, sid=0, indv;
-
- if (c.use || c.define) {
- var olddef = global.def; global.def = def || {}; // workaround minifiers
- str = resolveDefs(c, tmpl, global.def);
- global.def = olddef;
- } else str = tmpl;
+ var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,
+ str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g,' ')
.replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,''): str)
@@ -93,7 +97,7 @@
})
.replace(c.encode || skip, function(m, code) {
needhtmlencode = true;
- return cse.startencode + unescape(code) + cse.end;
+ return cse.start + unescape(code) + cse.endencode;
})
.replace(c.conditional || skip, function(m, elsecase, code) {
return elsecase ?
@@ -111,11 +115,11 @@
})
+ "';return out;")
.replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/\r/g, '\\r')
- .replace(/(\s|;|}|^|{)out\+='';/g, '$1').replace(/\+''/g, '')
- .replace(/(\s|;|}|^|{)out\+=''\+/g,'$1out+=');
+ .replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, '')
+ .replace(/(\s|;|\}|^|\{)out\+=''\+/g,'$1out+=');
if (needhtmlencode && c.selfcontained) {
- str = "var encodeHTML=(" + encodeHTMLSource.toString() + "());" + str;
+ str = "String.prototype.encodeHTML=(" + encodeHTMLSource.toString() + "());" + str;
}
try {
return new Function(c.varname, str);
View
4 doT.js
@@ -6,9 +6,9 @@
"use strict";
var doT = {
- version: '1.0.0',
+ version: '1.0.1',
templateSettings: {
- evaluate: /\{\{([\s\S]+?\}?)\}\}/g,
+ evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
View
2 doT.min.js
@@ -1,5 +1,5 @@
/* Laura Doktorova https://github.com/olado/doT */(function(){function o(){var a={"&":"&#38;","<":"&#60;",">":"&#62;",'"':"&#34;","'":"&#39;","/":"&#47;"},b=/&(?!#?\w+;)|<|>|"|'|\//g;return function(){return this?this.replace(b,function(c){return a[c]||c}):this}}function p(a,b,c){return(typeof b==="string"?b:b.toString()).replace(a.define||i,function(l,e,f,g){if(e.indexOf("def.")===0)e=e.substring(4);if(!(e in c))if(f===":"){a.defineParams&&g.replace(a.defineParams,function(n,h,d){c[e]={arg:h,text:d}});e in c||(c[e]=g)}else(new Function("def","def['"+
-e+"']="+g))(c);return""}).replace(a.use||i,function(l,e){if(a.useParams)e=e.replace(a.useParams,function(g,n,h,d){if(c[h]&&c[h].arg&&d){g=(h+":"+d).replace(/'|\\/g,"_");c.__exp=c.__exp||{};c.__exp[g]=c[h].text.replace(RegExp("(^|[^\\w$])"+c[h].arg+"([^\\w$])","g"),"$1"+d+"$2");return n+"def.__exp['"+g+"']"}});var f=(new Function("def","return "+e))(c);return f?p(a,f,c):f})}function m(a){return a.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}var j={version:"1.0.0",templateSettings:{evaluate:/\{\{([\s\S]+?\}?)\}\}/g,
+e+"']="+g))(c);return""}).replace(a.use||i,function(l,e){if(a.useParams)e=e.replace(a.useParams,function(g,n,h,d){if(c[h]&&c[h].arg&&d){g=(h+":"+d).replace(/'|\\/g,"_");c.__exp=c.__exp||{};c.__exp[g]=c[h].text.replace(RegExp("(^|[^\\w$])"+c[h].arg+"([^\\w$])","g"),"$1"+d+"$2");return n+"def.__exp['"+g+"']"}});var f=(new Function("def","return "+e))(c);return f?p(a,f,c):f})}function m(a){return a.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}var j={version:"1.0.1",templateSettings:{evaluate:/\{\{([\s\S]+?(\}?)+)\}\}/g,
interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,useParams:/(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,defineParams:/^\s*([\w$]+):([\s\S]+)/,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:true,append:true,selfcontained:false},template:undefined,
compile:undefined};if(typeof module!=="undefined"&&module.exports)module.exports=j;else if(typeof define==="function"&&define.amd)define(function(){return j});else(function(){return this||(0,eval)("this")})().doT=j;String.prototype.encodeHTML=o();var q={append:{start:"'+(",end:")+'",endencode:"||'').toString().encodeHTML()+'"},split:{start:"';out+=(",end:");out+='",endencode:"||'').toString().encodeHTML();out+='"}},i=/$^/;j.template=function(a,b,c){b=b||j.templateSettings;var l=b.append?q.append:
q.split,e,f=0,g;a=b.use||b.define?p(b,a,c||{}):a;a=("var out='"+(b.strip?a.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):a).replace(/'|\\/g,"\\$&").replace(b.interpolate||i,function(h,d){return l.start+m(d)+l.end}).replace(b.encode||i,function(h,d){e=true;return l.start+m(d)+l.endencode}).replace(b.conditional||i,function(h,d,k){return d?k?"';}else if("+m(k)+"){out+='":"';}else{out+='":k?"';if("+m(k)+"){out+='":"';}out+='"}).replace(b.iterate||i,function(h,

0 comments on commit 719140a

Please sign in to comment.
Something went wrong with that request. Please try again.