ejs
Advanced tools
Comparing version 0.8.5 to 0.8.6
21
ejs.js
@@ -147,3 +147,3 @@ ejs = (function(){ | ||
+ err.message; | ||
throw err; | ||
@@ -179,3 +179,3 @@ } | ||
i += open.length | ||
var prefix, postfix, line = (compileDebug ? '__stack.lineno=' : '') + lineno; | ||
@@ -198,4 +198,9 @@ switch (str[i]) { | ||
var end = str.indexOf(close, i) | ||
, js = str.substring(i, end) | ||
var end = str.indexOf(close, i); | ||
if (end < 0){ | ||
throw new Error('Could not find matching close tag "' + close + '".'); | ||
} | ||
var js = str.substring(i, end) | ||
, start = i | ||
@@ -265,3 +270,3 @@ , include = null | ||
var escape = options.escape || utils.escape; | ||
var input = JSON.stringify(str) | ||
@@ -273,3 +278,3 @@ , compileDebug = options.compileDebug !== false | ||
: 'undefined'; | ||
if (compileDebug) { | ||
@@ -289,3 +294,3 @@ // Adds the fancy stack trace meta info | ||
} | ||
if (options.debug) console.log(str); | ||
@@ -642,3 +647,3 @@ if (client) str = 'escape = escape || ' + escape.toString() + ';\n' + str; | ||
return String(html) | ||
.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&') | ||
.replace(/&/g, '&') | ||
.replace(/</g, '<') | ||
@@ -645,0 +650,0 @@ .replace(/>/g, '>') |
@@ -1,1 +0,1 @@ | ||
ejs=function(){function require(p){if("fs"==p)return{};if("path"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');if(!mod.exports){mod.exports={};mod.call(mod.exports,mod,mod.exports,require.relative(path))}return mod.exports}require.modules={};require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig};require.register=function(path,fn){require.modules[path]=fn};require.relative=function(parent){return function(p){if("."!=p.substr(0,1))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i<segs.length;i++){var seg=segs[i];if(".."==seg)path.pop();else if("."!=seg)path.push(seg)}return require(path.join("/"))}};require.register("ejs.js",function(module,exports,require){var utils=require("./utils"),path=require("path"),dirname=path.dirname,extname=path.extname,join=path.join,fs=require("fs"),read=fs.readFileSync;var filters=exports.filters=require("./filters");var cache={};exports.clearCache=function(){cache={}};function filtered(js){return js.substr(1).split("|").reduce(function(js,filter){var parts=filter.split(":"),name=parts.shift(),args=parts.join(":")||"";if(args)args=", "+args;return"filters."+name+"("+js+args+")"})}function rethrow(err,str,filename,lineno){var lines=str.split("\n"),start=Math.max(lineno-3,0),end=Math.min(lines.length,lineno+3);var context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" >> ":" ")+curr+"| "+line}).join("\n");err.path=filename;err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message;throw err}var parse=exports.parse=function(str,options){var options=options||{},open=options.open||exports.open||"<%",close=options.close||exports.close||"%>",filename=options.filename,compileDebug=options.compileDebug!==false,buf="";buf+="var buf = [];";if(false!==options._with)buf+="\nwith (locals || {}) { (function(){ ";buf+="\n buf.push('";var lineno=1;var consumeEOL=false;for(var i=0,len=str.length;i<len;++i){var stri=str[i];if(str.slice(i,open.length+i)==open){i+=open.length;var prefix,postfix,line=(compileDebug?"__stack.lineno=":"")+lineno;switch(str[i]){case"=":prefix="', escape(("+line+", ";postfix=")), '";++i;break;case"-":prefix="', ("+line+", ";postfix="), '";++i;break;default:prefix="');"+line+";";postfix="; buf.push('"}var end=str.indexOf(close,i),js=str.substring(i,end),start=i,include=null,n=0;if("-"==js[js.length-1]){js=js.substring(0,js.length-2);consumeEOL=true}if(0==js.trim().indexOf("include")){var name=js.trim().slice(7).trim();if(!filename)throw new Error("filename option is required for includes");var path=resolveInclude(name,filename);include=read(path,"utf8");include=exports.parse(include,{filename:path,_with:false,open:open,close:close,compileDebug:compileDebug});buf+="' + (function(){"+include+"})() + '";js=""}while(~(n=js.indexOf("\n",n)))n++,lineno++;if(js.substr(0,1)==":")js=filtered(js);if(js){if(js.lastIndexOf("//")>js.lastIndexOf("\n"))js+="\n";buf+=prefix;buf+=js;buf+=postfix}i+=end-start+close.length-1}else if(stri=="\\"){buf+="\\\\"}else if(stri=="'"){buf+="\\'"}else if(stri=="\r"){}else if(stri=="\n"){if(consumeEOL){consumeEOL=false}else{buf+="\\n";lineno++}}else{buf+=stri}}if(false!==options._with)buf+="'); })();\n} \nreturn buf.join('');";else buf+="');\nreturn buf.join('');";return buf};var compile=exports.compile=function(str,options){options=options||{};var escape=options.escape||utils.escape;var input=JSON.stringify(str),compileDebug=options.compileDebug!==false,client=options.client,filename=options.filename?JSON.stringify(options.filename):"undefined";if(compileDebug){str=["var __stack = { lineno: 1, input: "+input+", filename: "+filename+" };",rethrow.toString(),"try {",exports.parse(str,options),"} catch (err) {"," rethrow(err, __stack.input, __stack.filename, __stack.lineno);","}"].join("\n")}else{str=exports.parse(str,options)}if(options.debug)console.log(str);if(client)str="escape = escape || "+escape.toString()+";\n"+str;try{var fn=new Function("locals, filters, escape, rethrow",str)}catch(err){if("SyntaxError"==err.name){err.message+=options.filename?" in "+filename:" while compiling ejs"}throw err}if(client)return fn;return function(locals){return fn.call(this,locals,filters,escape,rethrow)}};exports.render=function(str,options){var fn,options=options||{};if(options.cache){if(options.filename){fn=cache[options.filename]||(cache[options.filename]=compile(str,options))}else{throw new Error('"cache" option requires "filename".')}}else{fn=compile(str,options)}options.__proto__=options.locals;return fn.call(options.scope,options)};exports.renderFile=function(path,options,fn){var key=path+":string";if("function"==typeof options){fn=options,options={}}options.filename=path;var str;try{str=options.cache?cache[key]||(cache[key]=read(path,"utf8")):read(path,"utf8")}catch(err){fn(err);return}fn(null,exports.render(str,options))};function resolveInclude(name,filename){var path=join(dirname(filename),name);var ext=extname(name);if(!ext)path+=".ejs";return path}exports.__express=exports.renderFile;if(require.extensions){require.extensions[".ejs"]=function(module,filename){filename=filename||module.filename;var options={filename:filename,client:true},template=fs.readFileSync(filename).toString(),fn=compile(template,options);module._compile("module.exports = "+fn.toString()+";",filename)}}else if(require.registerExtension){require.registerExtension(".ejs",function(src){return compile(src,{})})}});require.register("filters.js",function(module,exports,require){exports.first=function(obj){return obj[0]};exports.last=function(obj){return obj[obj.length-1]};exports.capitalize=function(str){str=String(str);return str[0].toUpperCase()+str.substr(1,str.length)};exports.downcase=function(str){return String(str).toLowerCase()};exports.upcase=function(str){return String(str).toUpperCase()};exports.sort=function(obj){return Object.create(obj).sort()};exports.sort_by=function(obj,prop){return Object.create(obj).sort(function(a,b){a=a[prop],b=b[prop];if(a>b)return 1;if(a<b)return-1;return 0})};exports.size=exports.length=function(obj){return obj.length};exports.plus=function(a,b){return Number(a)+Number(b)};exports.minus=function(a,b){return Number(a)-Number(b)};exports.times=function(a,b){return Number(a)*Number(b)};exports.divided_by=function(a,b){return Number(a)/Number(b)};exports.join=function(obj,str){return obj.join(str||", ")};exports.truncate=function(str,len,append){str=String(str);if(str.length>len){str=str.slice(0,len);if(append)str+=append}return str};exports.truncate_words=function(str,n){var str=String(str),words=str.split(/ +/);return words.slice(0,n).join(" ")};exports.replace=function(str,pattern,substitution){return String(str).replace(pattern,substitution||"")};exports.prepend=function(obj,val){return Array.isArray(obj)?[val].concat(obj):val+obj};exports.append=function(obj,val){return Array.isArray(obj)?obj.concat(val):obj+val};exports.map=function(arr,prop){return arr.map(function(obj){return obj[prop]})};exports.reverse=function(obj){return Array.isArray(obj)?obj.reverse():String(obj).split("").reverse().join("")};exports.get=function(obj,prop){return obj[prop]};exports.json=function(obj){return JSON.stringify(obj)}});require.register("utils.js",function(module,exports,require){exports.escape=function(html){return String(html).replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")}});return require("ejs")}(); | ||
ejs=function(){function require(p){if("fs"==p)return{};if("path"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');if(!mod.exports){mod.exports={};mod.call(mod.exports,mod,mod.exports,require.relative(path))}return mod.exports}require.modules={};require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig};require.register=function(path,fn){require.modules[path]=fn};require.relative=function(parent){return function(p){if("."!=p.substr(0,1))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i<segs.length;i++){var seg=segs[i];if(".."==seg)path.pop();else if("."!=seg)path.push(seg)}return require(path.join("/"))}};require.register("ejs.js",function(module,exports,require){var utils=require("./utils"),path=require("path"),dirname=path.dirname,extname=path.extname,join=path.join,fs=require("fs"),read=fs.readFileSync;var filters=exports.filters=require("./filters");var cache={};exports.clearCache=function(){cache={}};function filtered(js){return js.substr(1).split("|").reduce(function(js,filter){var parts=filter.split(":"),name=parts.shift(),args=parts.join(":")||"";if(args)args=", "+args;return"filters."+name+"("+js+args+")"})}function rethrow(err,str,filename,lineno){var lines=str.split("\n"),start=Math.max(lineno-3,0),end=Math.min(lines.length,lineno+3);var context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" >> ":" ")+curr+"| "+line}).join("\n");err.path=filename;err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message;throw err}var parse=exports.parse=function(str,options){var options=options||{},open=options.open||exports.open||"<%",close=options.close||exports.close||"%>",filename=options.filename,compileDebug=options.compileDebug!==false,buf="";buf+="var buf = [];";if(false!==options._with)buf+="\nwith (locals || {}) { (function(){ ";buf+="\n buf.push('";var lineno=1;var consumeEOL=false;for(var i=0,len=str.length;i<len;++i){var stri=str[i];if(str.slice(i,open.length+i)==open){i+=open.length;var prefix,postfix,line=(compileDebug?"__stack.lineno=":"")+lineno;switch(str[i]){case"=":prefix="', escape(("+line+", ";postfix=")), '";++i;break;case"-":prefix="', ("+line+", ";postfix="), '";++i;break;default:prefix="');"+line+";";postfix="; buf.push('"}var end=str.indexOf(close,i);if(end<0){throw new Error('Could not find matching close tag "'+close+'".')}var js=str.substring(i,end),start=i,include=null,n=0;if("-"==js[js.length-1]){js=js.substring(0,js.length-2);consumeEOL=true}if(0==js.trim().indexOf("include")){var name=js.trim().slice(7).trim();if(!filename)throw new Error("filename option is required for includes");var path=resolveInclude(name,filename);include=read(path,"utf8");include=exports.parse(include,{filename:path,_with:false,open:open,close:close,compileDebug:compileDebug});buf+="' + (function(){"+include+"})() + '";js=""}while(~(n=js.indexOf("\n",n)))n++,lineno++;if(js.substr(0,1)==":")js=filtered(js);if(js){if(js.lastIndexOf("//")>js.lastIndexOf("\n"))js+="\n";buf+=prefix;buf+=js;buf+=postfix}i+=end-start+close.length-1}else if(stri=="\\"){buf+="\\\\"}else if(stri=="'"){buf+="\\'"}else if(stri=="\r"){}else if(stri=="\n"){if(consumeEOL){consumeEOL=false}else{buf+="\\n";lineno++}}else{buf+=stri}}if(false!==options._with)buf+="'); })();\n} \nreturn buf.join('');";else buf+="');\nreturn buf.join('');";return buf};var compile=exports.compile=function(str,options){options=options||{};var escape=options.escape||utils.escape;var input=JSON.stringify(str),compileDebug=options.compileDebug!==false,client=options.client,filename=options.filename?JSON.stringify(options.filename):"undefined";if(compileDebug){str=["var __stack = { lineno: 1, input: "+input+", filename: "+filename+" };",rethrow.toString(),"try {",exports.parse(str,options),"} catch (err) {"," rethrow(err, __stack.input, __stack.filename, __stack.lineno);","}"].join("\n")}else{str=exports.parse(str,options)}if(options.debug)console.log(str);if(client)str="escape = escape || "+escape.toString()+";\n"+str;try{var fn=new Function("locals, filters, escape, rethrow",str)}catch(err){if("SyntaxError"==err.name){err.message+=options.filename?" in "+filename:" while compiling ejs"}throw err}if(client)return fn;return function(locals){return fn.call(this,locals,filters,escape,rethrow)}};exports.render=function(str,options){var fn,options=options||{};if(options.cache){if(options.filename){fn=cache[options.filename]||(cache[options.filename]=compile(str,options))}else{throw new Error('"cache" option requires "filename".')}}else{fn=compile(str,options)}options.__proto__=options.locals;return fn.call(options.scope,options)};exports.renderFile=function(path,options,fn){var key=path+":string";if("function"==typeof options){fn=options,options={}}options.filename=path;var str;try{str=options.cache?cache[key]||(cache[key]=read(path,"utf8")):read(path,"utf8")}catch(err){fn(err);return}fn(null,exports.render(str,options))};function resolveInclude(name,filename){var path=join(dirname(filename),name);var ext=extname(name);if(!ext)path+=".ejs";return path}exports.__express=exports.renderFile;if(require.extensions){require.extensions[".ejs"]=function(module,filename){filename=filename||module.filename;var options={filename:filename,client:true},template=fs.readFileSync(filename).toString(),fn=compile(template,options);module._compile("module.exports = "+fn.toString()+";",filename)}}else if(require.registerExtension){require.registerExtension(".ejs",function(src){return compile(src,{})})}});require.register("filters.js",function(module,exports,require){exports.first=function(obj){return obj[0]};exports.last=function(obj){return obj[obj.length-1]};exports.capitalize=function(str){str=String(str);return str[0].toUpperCase()+str.substr(1,str.length)};exports.downcase=function(str){return String(str).toLowerCase()};exports.upcase=function(str){return String(str).toUpperCase()};exports.sort=function(obj){return Object.create(obj).sort()};exports.sort_by=function(obj,prop){return Object.create(obj).sort(function(a,b){a=a[prop],b=b[prop];if(a>b)return 1;if(a<b)return-1;return 0})};exports.size=exports.length=function(obj){return obj.length};exports.plus=function(a,b){return Number(a)+Number(b)};exports.minus=function(a,b){return Number(a)-Number(b)};exports.times=function(a,b){return Number(a)*Number(b)};exports.divided_by=function(a,b){return Number(a)/Number(b)};exports.join=function(obj,str){return obj.join(str||", ")};exports.truncate=function(str,len,append){str=String(str);if(str.length>len){str=str.slice(0,len);if(append)str+=append}return str};exports.truncate_words=function(str,n){var str=String(str),words=str.split(/ +/);return words.slice(0,n).join(" ")};exports.replace=function(str,pattern,substitution){return String(str).replace(pattern,substitution||"")};exports.prepend=function(obj,val){return Array.isArray(obj)?[val].concat(obj):val+obj};exports.append=function(obj,val){return Array.isArray(obj)?obj.concat(val):obj+val};exports.map=function(arr,prop){return arr.map(function(obj){return obj[prop]})};exports.reverse=function(obj){return Array.isArray(obj)?obj.reverse():String(obj).split("").reverse().join("")};exports.get=function(obj,prop){return obj[prop]};exports.json=function(obj){return JSON.stringify(obj)}});require.register("utils.js",function(module,exports,require){exports.escape=function(html){return String(html).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""")}});return require("ejs")}(); |
0.8.6 / 2014-03-21 | ||
================== | ||
* fix: Escape & even if it looks like an HTML entity. Don't try to prevent double-escaping. | ||
0.8.5 / 2013-11-21 | ||
@@ -9,3 +14,3 @@ ================== | ||
0.8.4 / 2013-05-08 | ||
0.8.4 / 2013-05-08 | ||
================== | ||
@@ -17,3 +22,3 @@ | ||
0.8.3 / 2012-09-13 | ||
0.8.3 / 2012-09-13 | ||
================== | ||
@@ -23,3 +28,3 @@ | ||
0.8.2 / 2012-08-16 | ||
0.8.2 / 2012-08-16 | ||
================== | ||
@@ -29,3 +34,3 @@ | ||
0.8.1 / 2012-08-11 | ||
0.8.1 / 2012-08-11 | ||
================== | ||
@@ -35,3 +40,3 @@ | ||
0.8.0 / 2012-07-25 | ||
0.8.0 / 2012-07-25 | ||
================== | ||
@@ -42,3 +47,3 @@ | ||
0.7.3 / 2012-04-25 | ||
0.7.3 / 2012-04-25 | ||
================== | ||
@@ -48,3 +53,3 @@ | ||
0.7.1 / 2012-03-26 | ||
0.7.1 / 2012-03-26 | ||
================== | ||
@@ -54,3 +59,3 @@ | ||
0.7.0 / 2012-03-24 | ||
0.7.0 / 2012-03-24 | ||
================== | ||
@@ -60,3 +65,3 @@ | ||
0.6.1 / 2011-12-09 | ||
0.6.1 / 2011-12-09 | ||
================== | ||
@@ -66,3 +71,3 @@ | ||
0.6.0 / 2011-12-09 | ||
0.6.0 / 2011-12-09 | ||
================== | ||
@@ -72,3 +77,3 @@ | ||
0.5.0 / 2011-11-20 | ||
0.5.0 / 2011-11-20 | ||
================== | ||
@@ -81,3 +86,3 @@ | ||
0.4.3 / 2011-06-20 | ||
0.4.3 / 2011-06-20 | ||
================== | ||
@@ -87,3 +92,3 @@ | ||
0.4.2 / 2011-05-11 | ||
0.4.2 / 2011-05-11 | ||
================== | ||
@@ -93,3 +98,3 @@ | ||
0.4.1 / 2011-04-21 | ||
0.4.1 / 2011-04-21 | ||
================== | ||
@@ -99,3 +104,3 @@ | ||
0.4.0 / 2011-04-21 | ||
0.4.0 / 2011-04-21 | ||
================== | ||
@@ -105,3 +110,3 @@ | ||
0.3.1 / 2011-02-23 | ||
0.3.1 / 2011-02-23 | ||
================== | ||
@@ -111,3 +116,3 @@ | ||
0.3.0 / 2011-02-14 | ||
0.3.0 / 2011-02-14 | ||
================== | ||
@@ -118,3 +123,3 @@ | ||
0.2.1 / 2010-10-07 | ||
0.2.1 / 2010-10-07 | ||
================== | ||
@@ -125,3 +130,3 @@ | ||
0.2.0 / 2010-08-05 | ||
0.2.0 / 2010-08-05 | ||
================== | ||
@@ -128,0 +133,0 @@ |
@@ -95,3 +95,3 @@ | ||
+ err.message; | ||
throw err; | ||
@@ -127,3 +127,3 @@ } | ||
i += open.length | ||
var prefix, postfix, line = (compileDebug ? '__stack.lineno=' : '') + lineno; | ||
@@ -146,4 +146,9 @@ switch (str[i]) { | ||
var end = str.indexOf(close, i) | ||
, js = str.substring(i, end) | ||
var end = str.indexOf(close, i); | ||
if (end < 0){ | ||
throw new Error('Could not find matching close tag "' + close + '".'); | ||
} | ||
var js = str.substring(i, end) | ||
, start = i | ||
@@ -213,3 +218,3 @@ , include = null | ||
var escape = options.escape || utils.escape; | ||
var input = JSON.stringify(str) | ||
@@ -221,3 +226,3 @@ , compileDebug = options.compileDebug !== false | ||
: 'undefined'; | ||
if (compileDebug) { | ||
@@ -237,3 +242,3 @@ // Adds the fancy stack trace meta info | ||
} | ||
if (options.debug) console.log(str); | ||
@@ -240,0 +245,0 @@ if (client) str = 'escape = escape || ' + escape.toString() + ';\n' + str; |
@@ -18,3 +18,3 @@ | ||
return String(html) | ||
.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&') | ||
.replace(/&/g, '&') | ||
.replace(/</g, '<') | ||
@@ -21,0 +21,0 @@ .replace(/>/g, '>') |
{ | ||
"name": "ejs", | ||
"description": "Embedded JavaScript templates", | ||
"version": "0.8.5", | ||
"version": "0.8.6", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -6,0 +6,0 @@ "keywords": ["template", "engine", "ejs"], |
@@ -132,6 +132,8 @@ /** | ||
describe('<%=', function(){ | ||
it('should escape <script>', function(){ | ||
ejs.render('<%= name %>', { name: '<script>' }) | ||
.should.equal('<script>'); | ||
it('should escape &<script>', function(){ | ||
ejs.render('<%= name %>', { name: ' <script>' }) | ||
.should.equal('&nbsp;<script>'); | ||
}) | ||
it("should escape '", function(){ | ||
@@ -141,10 +143,3 @@ ejs.render('<%= name %>', { name: "The Jones's" }) | ||
}) | ||
it("shouldn't escape &", function(){ | ||
ejs.render('<%= name %>', { name: "Us & Them" }) | ||
.should.equal('Us & Them'); | ||
}) | ||
it("shouldn't escape ]", function(){ | ||
ejs.render('<%= name %>', { name: "The Jones's" }) | ||
.should.equal('The Jones's'); | ||
}) | ||
it("should escape &foo_bar;", function(){ | ||
@@ -161,2 +156,11 @@ ejs.render('<%= name %>', { name: "&foo_bar;" }) | ||
}) | ||
it('should terminate gracefully if no close tag is found', function(){ | ||
try { | ||
ejs.compile('<h1>oops</h1><%- name ->') | ||
throw new Error('Expected parse failure'); | ||
} catch (err) { | ||
err.message.should.equal('Could not find matching close tag "%>".'); | ||
} | ||
}) | ||
}) | ||
@@ -163,0 +167,0 @@ |
58588
1464