diff options
| author | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
| commit | 686106d544ecc3b6ffd4db2b665d3bc879a58d8c (patch) | |
| tree | a5b5e50237cef70e12f0745371896e96f5f6d578 /node_modules/ejs | |
ok
Diffstat (limited to 'node_modules/ejs')
| -rw-r--r-- | node_modules/ejs/.gitmodules | 0 | ||||
| -rw-r--r-- | node_modules/ejs/.npmignore | 4 | ||||
| -rw-r--r-- | node_modules/ejs/History.md | 98 | ||||
| -rw-r--r-- | node_modules/ejs/Makefile | 23 | ||||
| -rw-r--r-- | node_modules/ejs/Readme.md | 151 | ||||
| -rw-r--r-- | node_modules/ejs/benchmark.js | 14 | ||||
| -rw-r--r-- | node_modules/ejs/ejs.js | 567 | ||||
| -rw-r--r-- | node_modules/ejs/ejs.min.js | 2 | ||||
| -rw-r--r-- | node_modules/ejs/examples/client.html | 24 | ||||
| -rw-r--r-- | node_modules/ejs/examples/list.ejs | 7 | ||||
| -rw-r--r-- | node_modules/ejs/examples/list.js | 14 | ||||
| -rw-r--r-- | node_modules/ejs/index.js | 2 | ||||
| -rw-r--r-- | node_modules/ejs/lib/ejs.js | 298 | ||||
| -rw-r--r-- | node_modules/ejs/lib/filters.js | 198 | ||||
| -rw-r--r-- | node_modules/ejs/lib/utils.js | 23 | ||||
| -rw-r--r-- | node_modules/ejs/package.json | 32 | ||||
| -rw-r--r-- | node_modules/ejs/support/compile.js | 174 | ||||
| -rw-r--r-- | node_modules/ejs/test/ejs.test.js | 329 | ||||
| -rw-r--r-- | node_modules/ejs/test/fixtures/user.ejs | 1 |
19 files changed, 1961 insertions, 0 deletions
diff --git a/node_modules/ejs/.gitmodules b/node_modules/ejs/.gitmodules new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/node_modules/ejs/.gitmodules diff --git a/node_modules/ejs/.npmignore b/node_modules/ejs/.npmignore new file mode 100644 index 0000000..020ddac --- /dev/null +++ b/node_modules/ejs/.npmignore @@ -0,0 +1,4 @@ +# ignore any vim files: +*.sw[a-z] +vim/.netrwhist +node_modules diff --git a/node_modules/ejs/History.md b/node_modules/ejs/History.md new file mode 100644 index 0000000..75dc16f --- /dev/null +++ b/node_modules/ejs/History.md @@ -0,0 +1,98 @@ + +0.7.1 / 2012-03-26 +================== + + * Fixed exception when using express in production caused by typo. [slaskis] + +0.7.0 / 2012-03-24 +================== + + * Added newline consumption support (`-%>`) [whoatemydomain] + +0.6.1 / 2011-12-09 +================== + + * Fixed `ejs.renderFile()` + +0.6.0 / 2011-12-09 +================== + + * Changed: you no longer need `{ locals: {} }` + +0.5.0 / 2011-11-20 +================== + + * Added express 3.x support + * Added ejs.renderFile() + * Added 'json' filter + * Fixed tests for 0.5.x + +0.4.3 / 2011-06-20 +================== + + * Fixed stacktraces line number when used multiline js expressions [Octave] + +0.4.2 / 2011-05-11 +================== + + * Added client side support + +0.4.1 / 2011-04-21 +================== + + * Fixed error context + +0.4.0 / 2011-04-21 +================== + + * Added; ported jade's error reporting to ejs. [slaskis] + +0.3.1 / 2011-02-23 +================== + + * Fixed optional `compile()` options + +0.3.0 / 2011-02-14 +================== + + * Added 'json' filter [Yuriy Bogdanov] + * Use exported version of parse function to allow monkey-patching [Anatoliy Chakkaev] + +0.2.1 / 2010-10-07 +================== + + * Added filter support + * Fixed _cache_ option. ~4x performance increase + +0.2.0 / 2010-08-05 +================== + + * Added support for global tag config + * Added custom tag support. Closes #5 + * Fixed whitespace bug. Closes #4 + +0.1.0 / 2010-08-04 +================== + + * Faster implementation [ashleydev] + +0.0.4 / 2010-08-02 +================== + + * Fixed single quotes for content outside of template tags. [aniero] + * Changed; `exports.compile()` now expects only "locals" + +0.0.3 / 2010-07-15 +================== + + * Fixed single quotes + +0.0.2 / 2010-07-09 +================== + + * Fixed newline preservation + +0.0.1 / 2010-07-09 +================== + + * Initial release diff --git a/node_modules/ejs/Makefile b/node_modules/ejs/Makefile new file mode 100644 index 0000000..14b9304 --- /dev/null +++ b/node_modules/ejs/Makefile @@ -0,0 +1,23 @@ + +SRC = $(shell find lib -name "*.js" -type f) +UGLIFY_FLAGS = --no-mangle + +all: ejs.min.js + +test: + @./node_modules/.bin/mocha \ + --ui exports + +ejs.js: $(SRC) + @node support/compile.js $^ + +ejs.min.js: ejs.js + @uglifyjs $(UGLIFY_FLAGS) $< > $@ \ + && du ejs.min.js \ + && du ejs.js + +clean: + rm -f ejs.js + rm -f ejs.min.js + +.PHONY: test
\ No newline at end of file diff --git a/node_modules/ejs/Readme.md b/node_modules/ejs/Readme.md new file mode 100644 index 0000000..8e398fd --- /dev/null +++ b/node_modules/ejs/Readme.md @@ -0,0 +1,151 @@ + +# EJS + +Embedded JavaScript templates. + +## Installation + + $ npm install ejs + +## Features + + * Complies with the [Express](http://expressjs.com) view system + * Static caching of intermediate JavaScript + * Unbuffered code for conditionals etc `<% code %>` + * Escapes html by default with `<%= code %>` + * Unescaped buffering with `<%- code %>` + * Supports tag customization + * Filter support for designer-friendly templates + * Client-side support + * Newline slurping with `<% code -%>` or `<% -%>` or `<%= code -%>` or `<%- code -%>` + +## Example + + <% if (user) { %> + <h2><%= user.name %></h2> + <% } %> + +## Usage + + ejs.compile(str, options); + // => Function + + ejs.render(str, options); + // => str + +## Options + + - `cache` Compiled functions are cached, requires `filename` + - `filename` Used by `cache` to key caches + - `scope` Function execution context + - `debug` Output generated function body + - `open` Open tag, defaulting to "<%" + - `close` Closing tag, defaulting to "%>" + - * All others are template-local variables + +## Custom tags + +Custom tags can also be applied globally: + + var ejs = require('ejs'); + ejs.open = '{{'; + ejs.close = '}}'; + +Which would make the following a valid template: + + <h1>{{= title }}</h1> + +## Filters + +EJS conditionally supports the concept of "filters". A "filter chain" +is a designer friendly api for manipulating data, without writing JavaScript. + +Filters can be applied by supplying the _:_ modifier, so for example if we wish to take the array `[{ name: 'tj' }, { name: 'mape' }, { name: 'guillermo' }]` and output a list of names we can do this simply with filters: + +Template: + + <p><%=: users | map:'name' | join %></p> + +Output: + + <p>Tj, Mape, Guillermo</p> + +Render call: + + ejs.render(str, { + users: [ + { name: 'tj' }, + { name: 'mape' }, + { name: 'guillermo' } + ] + }); + +Or perhaps capitalize the first user's name for display: + + <p><%=: users | first | capitalize %></p> + +## Filter list + +Currently these filters are available: + + - first + - last + - capitalize + - downcase + - upcase + - sort + - sort_by:'prop' + - size + - length + - plus:n + - minus:n + - times:n + - divided_by:n + - join:'val' + - truncate:n + - truncate_words:n + - replace:pattern,substitution + - prepend:val + - append:val + - map:'prop' + - reverse + - get:'prop' + +## Adding filters + + To add a filter simply add a method to the `.filters` object: + +```js +ejs.filters.last = function(obj) { + return obj[obj.length - 1]; +}; +``` + +## client-side support + + include `./ejs.js` or `./ejs.min.js` and `require("ejs").compile(str)`. + +## License + +(The MIT License) + +Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/ejs/benchmark.js b/node_modules/ejs/benchmark.js new file mode 100644 index 0000000..7b267e1 --- /dev/null +++ b/node_modules/ejs/benchmark.js @@ -0,0 +1,14 @@ + + +var ejs = require('./lib/ejs'), + str = '<% if (foo) { %><p><%= foo %></p><% } %>', + times = 50000; + +console.log('rendering ' + times + ' times'); + +var start = new Date; +while (times--) { + ejs.render(str, { cache: true, filename: 'test', locals: { foo: 'bar' }}); +} + +console.log('took ' + (new Date - start) + 'ms');
\ No newline at end of file diff --git a/node_modules/ejs/ejs.js b/node_modules/ejs/ejs.js new file mode 100644 index 0000000..b0fa93b --- /dev/null +++ b/node_modules/ejs/ejs.js @@ -0,0 +1,567 @@ + +// CommonJS require() + +function require(p){ + if ('fs' == 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] && 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){ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils') + , fs = require('fs'); + +/** + * Library version. + */ + +exports.version = '0.6.1'; + +/** + * Filters. + * + * @type Object + */ + +var filters = exports.filters = require('./filters'); + +/** + * Intermediate js cache. + * + * @type Object + */ + +var cache = {}; + +/** + * Clear intermediate js cache. + * + * @api public + */ + +exports.clearCache = function(){ + cache = {}; +}; + +/** + * Translate filtered code into function calls. + * + * @param {String} js + * @return {String} + * @api private + */ + +function filtered(js) { + return js.substr(1).split('|').reduce(function(js, filter){ + var parts = filter.split(':') + , name = parts.shift() + , args = parts.shift() || ''; + if (args) args = ', ' + args; + return 'filters.' + name + '(' + js + args + ')'; + }); +}; + +/** + * Re-throw the given `err` in context to the + * `str` of ejs, `filename`, and `lineno`. + * + * @param {Error} err + * @param {String} str + * @param {String} filename + * @param {String} lineno + * @api private + */ + +function rethrow(err, str, filename, lineno){ + var lines = str.split('\n') + , start = Math.max(lineno - 3, 0) + , end = Math.min(lines.length, lineno + 3); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' >> ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'ejs') + ':' + + lineno + '\n' + + context + '\n\n' + + err.message; + + throw err; +} + +/** + * Parse the given `str` of ejs, returning the function body. + * + * @param {String} str + * @return {String} + * @api public + */ + +var parse = exports.parse = function(str, options){ + var options = options || {} + , open = options.open || exports.open || '<%' + , close = options.close || exports.close || '%>'; + + var buf = [ + "var buf = [];" + , "\nwith (locals) {" + , "\n buf.push('" + ]; + + var lineno = 1; + + for (var i = 0, len = str.length; i < len; ++i) { + if (str.slice(i, open.length + i) == open) { + i += open.length + + var prefix, postfix, line = '__stack.lineno=' + lineno; + switch (str.substr(i, 1)) { + 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 + , n = 0; + + while (~(n = js.indexOf("\n", n))) n++, lineno++; + if (js.substr(0, 1) == ':') js = filtered(js); + buf.push(prefix, js, postfix); + i += end - start + close.length - 1; + + } else if (str.substr(i, 1) == "\\") { + buf.push("\\\\"); + } else if (str.substr(i, 1) == "'") { + buf.push("\\'"); + } else if (str.substr(i, 1) == "\r") { + buf.push(" "); + } else if (str.substr(i, 1) == "\n") { + buf.push("\\n"); + lineno++; + } else { + buf.push(str.substr(i, 1)); + } + } + + buf.push("');\n}\nreturn buf.join('');"); + return buf.join(''); +}; + +/** + * Compile the given `str` of ejs into a `Function`. + * + * @param {String} str + * @param {Object} options + * @return {Function} + * @api public + */ + +var compile = exports.compile = function(str, options){ + options = options || {}; + + var input = JSON.stringify(str) + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined'; + + // Adds the fancy stack trace meta info + 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"); + + if (options.debug) console.log(str); + var fn = new Function('locals, filters, escape', str); + return function(locals){ + return fn.call(this, locals, filters, utils.escape); + } +}; + +/** + * Render the given `str` of ejs. + * + * Options: + * + * - `locals` Local variables object + * - `cache` Compiled functions are cached, requires `filename` + * - `filename` Used by `cache` to key caches + * - `scope` Function execution context + * - `debug` Output generated function body + * - `open` Open tag, defaulting to "<%" + * - `close` Closing tag, defaulting to "%>" + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api public + */ + +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); +}; + +/** + * Render an EJS file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + + try { + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + fn(null, exports.render(str, options)); + } catch (err) { + fn(err); + } +}; + +// express support + +exports.__express = exports.renderFile; + +/** + * Expose to require(). + */ + +if (require.extensions) { + require.extensions['.ejs'] = function(module, filename) { + source = require('fs').readFileSync(filename, 'utf-8'); + module._compile(compile(source, {}), filename); + }; +} else if (require.registerExtension) { + require.registerExtension('.ejs', function(src) { + return compile(src, {}); + }); +} + +}); // module: ejs.js + +require.register("filters.js", function(module, exports, require){ + +/*! + * EJS - Filters + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * First element of the target `obj`. + */ + +exports.first = function(obj) { + return obj[0]; +}; + +/** + * Last element of the target `obj`. + */ + +exports.last = function(obj) { + return obj[obj.length - 1]; +}; + +/** + * Capitalize the first letter of the target `str`. + */ + +exports.capitalize = function(str){ + str = String(str); + return str[0].toUpperCase() + str.substr(1, str.length); +}; + +/** + * Downcase the target `str`. + */ + +exports.downcase = function(str){ + return String(str).toLowerCase(); +}; + +/** + * Uppercase the target `str`. + */ + +exports.upcase = function(str){ + return String(str).toUpperCase(); +}; + +/** + * Sort the target `obj`. + */ + +exports.sort = function(obj){ + return Object.create(obj).sort(); +}; + +/** + * Sort the target `obj` by the given `prop` ascending. + */ + +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; + }); +}; + +/** + * Size or length of the target `obj`. + */ + +exports.size = exports.length = function(obj) { + return obj.length; +}; + +/** + * Add `a` and `b`. + */ + +exports.plus = function(a, b){ + return Number(a) + Number(b); +}; + +/** + * Subtract `b` from `a`. + */ + +exports.minus = function(a, b){ + return Number(a) - Number(b); +}; + +/** + * Multiply `a` by `b`. + */ + +exports.times = function(a, b){ + return Number(a) * Number(b); +}; + +/** + * Divide `a` by `b`. + */ + +exports.divided_by = function(a, b){ + return Number(a) / Number(b); +}; + +/** + * Join `obj` with the given `str`. + */ + +exports.join = function(obj, str){ + return obj.join(str || ', '); +}; + +/** + * Truncate `str` to `len`. + */ + +exports.truncate = function(str, len){ + str = String(str); + return str.substr(0, len); +}; + +/** + * Truncate `str` to `n` words. + */ + +exports.truncate_words = function(str, n){ + var str = String(str) + , words = str.split(/ +/); + return words.slice(0, n).join(' '); +}; + +/** + * Replace `pattern` with `substitution` in `str`. + */ + +exports.replace = function(str, pattern, substitution){ + return String(str).replace(pattern, substitution || ''); +}; + +/** + * Prepend `val` to `obj`. + */ + +exports.prepend = function(obj, val){ + return Array.isArray(obj) + ? [val].concat(obj) + : val + obj; +}; + +/** + * Append `val` to `obj`. + */ + +exports.append = function(obj, val){ + return Array.isArray(obj) + ? obj.concat(val) + : obj + val; +}; + +/** + * Map the given `prop`. + */ + +exports.map = function(arr, prop){ + return arr.map(function(obj){ + return obj[prop]; + }); +}; + +/** + * Reverse the given `obj`. + */ + +exports.reverse = function(obj){ + return Array.isArray(obj) + ? obj.reverse() + : String(obj).split('').reverse().join(''); +}; + +/** + * Get `prop` of the given `obj`. + */ + +exports.get = function(obj, prop){ + return obj[prop]; +}; + +/** + * Packs the given `obj` into json string + */ +exports.json = function(obj){ + return JSON.stringify(obj); +}; +}); // module: filters.js + +require.register("utils.js", function(module, exports, require){ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"'); +}; + +}); // module: utils.js diff --git a/node_modules/ejs/ejs.min.js b/node_modules/ejs/ejs.min.js new file mode 100644 index 0000000..b878813 --- /dev/null +++ b/node_modules/ejs/ejs.min.js @@ -0,0 +1,2 @@ +// CommonJS require() +function require(p){if("fs"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');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];".."==seg?path.pop():"."!=seg&&path.push(seg)}return require(path.join("/"))}},require.register("ejs.js",function(module,exports,require){var utils=require("./utils"),fs=require("fs");exports.version="0.6.1";var filters=exports.filters=require("./filters"),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.shift()||"";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),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||"%>",buf=["var buf = [];","\nwith (locals) {","\n buf.push('"],lineno=1;for(var i=0,len=str.length;i<len;++i)if(str.slice(i,open.length+i)==open){i+=open.length;var prefix,postfix,line="__stack.lineno="+lineno;switch(str.substr(i,1)){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,n=0;while(~(n=js.indexOf("\n",n)))n++,lineno++;js.substr(0,1)==":"&&(js=filtered(js)),buf.push(prefix,js,postfix),i+=end-start+close.length-1}else str.substr(i,1)=="\\"?buf.push("\\\\"):str.substr(i,1)=="'"?buf.push("\\'"):str.substr(i,1)=="\r"?buf.push(" "):str.substr(i,1)=="\n"?(buf.push("\\n"),lineno++):buf.push(str.substr(i,1));buf.push("');\n}\nreturn buf.join('');");return buf.join("")},compile=exports.compile=function(str,options){options=options||{};var input=JSON.stringify(str),filename=options.filename?JSON.stringify(options.filename):"undefined";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"),options.debug&&console.log(str);var fn=new Function("locals, filters, escape",str);return function(locals){return fn.call(this,locals,filters,utils.escape)}};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";"function"==typeof options&&(fn=options,options={}),options.filename=path;try{var str=options.cache?exports.cache[key]||(exports.cache[key]=fs.readFileSync(path,"utf8")):fs.readFileSync(path,"utf8");fn(null,exports.render(str,options))}catch(err){fn(err)}},exports.__express=exports.renderFile,require.extensions?require.extensions[".ejs"]=function(module,filename){source=require("fs").readFileSync(filename,"utf-8"),module._compile(compile(source,{}),filename)}: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){str=String(str);return str.substr(0,len)},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(/&(?!\w+;)/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}})
\ No newline at end of file diff --git a/node_modules/ejs/examples/client.html b/node_modules/ejs/examples/client.html new file mode 100644 index 0000000..51ce0b4 --- /dev/null +++ b/node_modules/ejs/examples/client.html @@ -0,0 +1,24 @@ +<html> + <head> + <script src="../ejs.js"></script> + <script id="users" type="text/template"> + <% if (names.length) { %> + <ul> + <% names.forEach(function(name){ %> + <li><%= name %></li> + <% }) %> + </ul> + <% } %> + </script> + <script> + onload = function(){ + var users = document.getElementById('users').innerHTML; + var names = ['loki', 'tobi', 'jane']; + var html = require('ejs').render(users, { names: names }); + document.body.innerHTML = html; + } + </script> + </head> + <body> + </body> +</html>
\ No newline at end of file diff --git a/node_modules/ejs/examples/list.ejs b/node_modules/ejs/examples/list.ejs new file mode 100644 index 0000000..d571330 --- /dev/null +++ b/node_modules/ejs/examples/list.ejs @@ -0,0 +1,7 @@ +<% if (names.length) { %> + <ul> + <% names.forEach(function(name){ %> + <li><%= name %></li> + <% }) %> + </ul> +<% } %>
\ No newline at end of file diff --git a/node_modules/ejs/examples/list.js b/node_modules/ejs/examples/list.js new file mode 100644 index 0000000..ec614ed --- /dev/null +++ b/node_modules/ejs/examples/list.js @@ -0,0 +1,14 @@ + +/** + * Module dependencies. + */ + +var ejs = require('../') + , fs = require('fs') + , str = fs.readFileSync(__dirname + '/list.ejs', 'utf8'); + +var ret = ejs.render(str, { + names: ['foo', 'bar', 'baz'] +}); + +console.log(ret);
\ No newline at end of file diff --git a/node_modules/ejs/index.js b/node_modules/ejs/index.js new file mode 100644 index 0000000..20bf71a --- /dev/null +++ b/node_modules/ejs/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/ejs');
\ No newline at end of file diff --git a/node_modules/ejs/lib/ejs.js b/node_modules/ejs/lib/ejs.js new file mode 100644 index 0000000..e87b98e --- /dev/null +++ b/node_modules/ejs/lib/ejs.js @@ -0,0 +1,298 @@ + +/*! + * EJS + * Copyright(c) 2012 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils') + , fs = require('fs'); + +/** + * Library version. + */ + +exports.version = '0.7.1'; + +/** + * Filters. + * + * @type Object + */ + +var filters = exports.filters = require('./filters'); + +/** + * Intermediate js cache. + * + * @type Object + */ + +var cache = {}; + +/** + * Clear intermediate js cache. + * + * @api public + */ + +exports.clearCache = function(){ + cache = {}; +}; + +/** + * Translate filtered code into function calls. + * + * @param {String} js + * @return {String} + * @api private + */ + +function filtered(js) { + return js.substr(1).split('|').reduce(function(js, filter){ + var parts = filter.split(':') + , name = parts.shift() + , args = parts.shift() || ''; + if (args) args = ', ' + args; + return 'filters.' + name + '(' + js + args + ')'; + }); +}; + +/** + * Re-throw the given `err` in context to the + * `str` of ejs, `filename`, and `lineno`. + * + * @param {Error} err + * @param {String} str + * @param {String} filename + * @param {String} lineno + * @api private + */ + +function rethrow(err, str, filename, lineno){ + var lines = str.split('\n') + , start = Math.max(lineno - 3, 0) + , end = Math.min(lines.length, lineno + 3); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' >> ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'ejs') + ':' + + lineno + '\n' + + context + '\n\n' + + err.message; + + throw err; +} + +/** + * Parse the given `str` of ejs, returning the function body. + * + * @param {String} str + * @return {String} + * @api public + */ + +var parse = exports.parse = function(str, options){ + var options = options || {} + , open = options.open || exports.open || '<%' + , close = options.close || exports.close || '%>'; + + var buf = [ + "var buf = [];" + , "\nwith (locals) {" + , "\n buf.push('" + ]; + + var lineno = 1; + + var consumeEOL = false; + for (var i = 0, len = str.length; i < len; ++i) { + if (str.slice(i, open.length + i) == open) { + i += open.length + + var prefix, postfix, line = '__stack.lineno=' + lineno; + switch (str.substr(i, 1)) { + 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 + , n = 0; + + if ('-' == js[js.length-1]){ + js = js.substring(0, js.length - 2); + consumeEOL = true; + } + + while (~(n = js.indexOf("\n", n))) n++, lineno++; + if (js.substr(0, 1) == ':') js = filtered(js); + buf.push(prefix, js, postfix); + i += end - start + close.length - 1; + + } else if (str.substr(i, 1) == "\\") { + buf.push("\\\\"); + } else if (str.substr(i, 1) == "'") { + buf.push("\\'"); + } else if (str.substr(i, 1) == "\r") { + buf.push(" "); + } else if (str.substr(i, 1) == "\n") { + if (consumeEOL) { + consumeEOL = false; + } else { + buf.push("\\n"); + lineno++; + } + } else { + buf.push(str.substr(i, 1)); + } + } + + buf.push("');\n}\nreturn buf.join('');"); + return buf.join(''); +}; + +/** + * Compile the given `str` of ejs into a `Function`. + * + * @param {String} str + * @param {Object} options + * @return {Function} + * @api public + */ + +var compile = exports.compile = function(str, options){ + options = options || {}; + + var input = JSON.stringify(str) + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined'; + + // Adds the fancy stack trace meta info + 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"); + + if (options.debug) console.log(str); + var fn = new Function('locals, filters, escape', str); + return function(locals){ + return fn.call(this, locals, filters, utils.escape); + } +}; + +/** + * Render the given `str` of ejs. + * + * Options: + * + * - `locals` Local variables object + * - `cache` Compiled functions are cached, requires `filename` + * - `filename` Used by `cache` to key caches + * - `scope` Function execution context + * - `debug` Output generated function body + * - `open` Open tag, defaulting to "<%" + * - `close` Closing tag, defaulting to "%>" + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api public + */ + +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); +}; + +/** + * Render an EJS file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + + try { + var str = options.cache + ? cache[key] || (cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + fn(null, exports.render(str, options)); + } catch (err) { + fn(err); + } +}; + +// express support + +exports.__express = exports.renderFile; + +/** + * Expose to require(). + */ + +if (require.extensions) { + require.extensions['.ejs'] = function(module, filename) { + source = require('fs').readFileSync(filename, 'utf-8'); + module._compile(compile(source, {}), filename); + }; +} else if (require.registerExtension) { + require.registerExtension('.ejs', function(src) { + return compile(src, {}); + }); +} diff --git a/node_modules/ejs/lib/filters.js b/node_modules/ejs/lib/filters.js new file mode 100644 index 0000000..d425c8d --- /dev/null +++ b/node_modules/ejs/lib/filters.js @@ -0,0 +1,198 @@ + +/*! + * EJS - Filters + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * First element of the target `obj`. + */ + +exports.first = function(obj) { + return obj[0]; +}; + +/** + * Last element of the target `obj`. + */ + +exports.last = function(obj) { + return obj[obj.length - 1]; +}; + +/** + * Capitalize the first letter of the target `str`. + */ + +exports.capitalize = function(str){ + str = String(str); + return str[0].toUpperCase() + str.substr(1, str.length); +}; + +/** + * Downcase the target `str`. + */ + +exports.downcase = function(str){ + return String(str).toLowerCase(); +}; + +/** + * Uppercase the target `str`. + */ + +exports.upcase = function(str){ + return String(str).toUpperCase(); +}; + +/** + * Sort the target `obj`. + */ + +exports.sort = function(obj){ + return Object.create(obj).sort(); +}; + +/** + * Sort the target `obj` by the given `prop` ascending. + */ + +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; + }); +}; + +/** + * Size or length of the target `obj`. + */ + +exports.size = exports.length = function(obj) { + return obj.length; +}; + +/** + * Add `a` and `b`. + */ + +exports.plus = function(a, b){ + return Number(a) + Number(b); +}; + +/** + * Subtract `b` from `a`. + */ + +exports.minus = function(a, b){ + return Number(a) - Number(b); +}; + +/** + * Multiply `a` by `b`. + */ + +exports.times = function(a, b){ + return Number(a) * Number(b); +}; + +/** + * Divide `a` by `b`. + */ + +exports.divided_by = function(a, b){ + return Number(a) / Number(b); +}; + +/** + * Join `obj` with the given `str`. + */ + +exports.join = function(obj, str){ + return obj.join(str || ', '); +}; + +/** + * Truncate `str` to `len`. + */ + +exports.truncate = function(str, len){ + str = String(str); + return str.substr(0, len); +}; + +/** + * Truncate `str` to `n` words. + */ + +exports.truncate_words = function(str, n){ + var str = String(str) + , words = str.split(/ +/); + return words.slice(0, n).join(' '); +}; + +/** + * Replace `pattern` with `substitution` in `str`. + */ + +exports.replace = function(str, pattern, substitution){ + return String(str).replace(pattern, substitution || ''); +}; + +/** + * Prepend `val` to `obj`. + */ + +exports.prepend = function(obj, val){ + return Array.isArray(obj) + ? [val].concat(obj) + : val + obj; +}; + +/** + * Append `val` to `obj`. + */ + +exports.append = function(obj, val){ + return Array.isArray(obj) + ? obj.concat(val) + : obj + val; +}; + +/** + * Map the given `prop`. + */ + +exports.map = function(arr, prop){ + return arr.map(function(obj){ + return obj[prop]; + }); +}; + +/** + * Reverse the given `obj`. + */ + +exports.reverse = function(obj){ + return Array.isArray(obj) + ? obj.reverse() + : String(obj).split('').reverse().join(''); +}; + +/** + * Get `prop` of the given `obj`. + */ + +exports.get = function(obj, prop){ + return obj[prop]; +}; + +/** + * Packs the given `obj` into json string + */ +exports.json = function(obj){ + return JSON.stringify(obj); +};
\ No newline at end of file diff --git a/node_modules/ejs/lib/utils.js b/node_modules/ejs/lib/utils.js new file mode 100644 index 0000000..8d569d6 --- /dev/null +++ b/node_modules/ejs/lib/utils.js @@ -0,0 +1,23 @@ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca> + * MIT Licensed + */ + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"'); +}; +
\ No newline at end of file diff --git a/node_modules/ejs/package.json b/node_modules/ejs/package.json new file mode 100644 index 0000000..e6e59df --- /dev/null +++ b/node_modules/ejs/package.json @@ -0,0 +1,32 @@ +{ + "name": "ejs", + "description": "Embedded JavaScript templates", + "version": "0.7.1", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "keywords": [ + "template", + "engine", + "ejs" + ], + "devDependencies": { + "mocha": "*" + }, + "main": "./lib/ejs.js", + "_id": "ejs@0.7.1", + "dependencies": {}, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "_engineSupported": true, + "_npmVersion": "1.1.12", + "_nodeVersion": "v0.6.14", + "_defaultsLoaded": true, + "dist": { + "shasum": "76261bc960735bee0897c8a4278ab852a4627eb2" + }, + "_from": "ejs@0.7.1" +} diff --git a/node_modules/ejs/support/compile.js b/node_modules/ejs/support/compile.js new file mode 100644 index 0000000..95cafc8 --- /dev/null +++ b/node_modules/ejs/support/compile.js @@ -0,0 +1,174 @@ + +/** + * Module dependencies. + */ + +var fs = require('fs'); + +/** + * Arguments. + */ + +var args = process.argv.slice(2) + , pending = args.length + , files = {}; + +console.log(''); + +// parse arguments + +args.forEach(function(file){ + var mod = file.replace('lib/', ''); + fs.readFile(file, 'utf8', function(err, js){ + if (err) throw err; + console.log(' \033[90mcompile : \033[0m\033[36m%s\033[0m', file); + files[file] = parse(js); + --pending || compile(); + }); +}); + +/** + * Parse the given `js`. + */ + +function parse(js) { + return parseInheritance(parseConditionals(js)); +} + +/** + * Parse __proto__. + */ + +function parseInheritance(js) { + return js + .replace(/^ *(\w+)\.prototype\.__proto__ * = *(\w+)\.prototype *;?/gm, function(_, child, parent){ + return child + '.prototype = new ' + parent + ';\n' + + child + '.prototype.constructor = '+ child + ';\n'; + }); +} + +/** + * Parse the given `js`, currently supporting: + * + * 'if' ['node' | 'browser'] + * 'end' + * + */ + +function parseConditionals(js) { + var lines = js.split('\n') + , len = lines.length + , buffer = true + , browser = false + , buf = [] + , line + , cond; + + for (var i = 0; i < len; ++i) { + line = lines[i]; + if (/^ *\/\/ *if *(node|browser)/gm.exec(line)) { + cond = RegExp.$1; + buffer = browser = 'browser' == cond; + } else if (/^ *\/\/ *end/.test(line)) { + buffer = true; + browser = false; + } else if (browser) { + buf.push(line.replace(/^( *)\/\//, '$1')); + } else if (buffer) { + buf.push(line); + } + } + + return buf.join('\n'); +} + +/** + * Compile the files. + */ + +function compile() { + var buf = ''; + buf += '\n// CommonJS require()\n\n'; + buf += browser.require + '\n\n'; + buf += 'require.modules = {};\n\n'; + buf += 'require.resolve = ' + browser.resolve + ';\n\n'; + buf += 'require.register = ' + browser.register + ';\n\n'; + buf += 'require.relative = ' + browser.relative + ';\n\n'; + args.forEach(function(file){ + var js = files[file]; + file = file.replace('lib/', ''); + buf += '\nrequire.register("' + file + '", function(module, exports, require){\n'; + buf += js; + buf += '\n}); // module: ' + file + '\n'; + }); + fs.writeFile('ejs.js', buf, function(err){ + if (err) throw err; + console.log(' \033[90m create : \033[0m\033[36m%s\033[0m', 'ejs.js'); + console.log(); + }); +} + +// refactored version of weepy's +// https://github.com/weepy/brequire/blob/master/browser/brequire.js + +var browser = { + + /** + * Require a module. + */ + + require: function require(p){ + if ('fs' == 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; + }, + + /** + * Resolve module path. + */ + + resolve: function(path){ + var orig = path + , reg = path + '.js' + , index = path + '/index.js'; + return require.modules[reg] && reg + || require.modules[index] && index + || orig; + }, + + /** + * Return relative 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('/')); + }; + }, + + /** + * Register a module. + */ + + register: function(path, fn){ + require.modules[path] = fn; + } +};
\ No newline at end of file diff --git a/node_modules/ejs/test/ejs.test.js b/node_modules/ejs/test/ejs.test.js new file mode 100644 index 0000000..54b8d2d --- /dev/null +++ b/node_modules/ejs/test/ejs.test.js @@ -0,0 +1,329 @@ + +/** + * Module dependencies. + */ + +var ejs = require('../') + , assert = require('assert'); + +module.exports = { + 'test .version': function(){ + assert.ok(/^\d+\.\d+\.\d+$/.test(ejs.version), 'Test .version format'); + }, + + 'test html': function(){ + assert.equal('<p>yay</p>', ejs.render('<p>yay</p>')); + }, + + 'test renderFile': function(){ + var html = '<h1>tj</h1>', + str = '<p><%= name %></p>', + options = { name: 'tj', open: '{', close: '}' }; + + ejs.renderFile(__dirname + '/fixtures/user.ejs', options, function(err, res){ + assert.ok(!err); + assert.equal(res, html); + }) + }, + + 'test buffered code': function(){ + var html = '<p>tj</p>', + str = '<p><%= name %></p>', + locals = { name: 'tj' }; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test unbuffered code': function(){ + var html = '<p>tj</p>', + str = '<% if (name) { %><p><%= name %></p><% } %>', + locals = { name: 'tj' }; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test `scope` option': function(){ + var html = '<p>tj</p>', + str = '<p><%= this %></p>'; + assert.equal(html, ejs.render(str, { scope: 'tj' })); + }, + + 'test escaping': function(){ + assert.equal('<script>', ejs.render('<%= "<script>" %>')); + assert.equal('<script>', ejs.render('<%- "<script>" %>')); + }, + + 'test newlines': function(){ + var html = '\n<p>tj</p>\n<p>tj@sencha.com</p>', + str = '<% if (name) { %>\n<p><%= name %></p>\n<p><%= email %></p><% } %>', + locals = { name: 'tj', email: 'tj@sencha.com' }; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test single quotes': function(){ + var html = '<p>WAHOO</p>', + str = "<p><%= up('wahoo') %></p>", + locals = { up: function(str){ return str.toUpperCase(); }}; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test single quotes in the html': function(){ + var html = '<p>WAHOO that\'s cool</p>', + str = '<p><%= up(\'wahoo\') %> that\'s cool</p>', + locals = { up: function(str){ return str.toUpperCase(); }}; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test multiple single quotes': function() { + var html = "<p>couldn't shouldn't can't</p>", + str = "<p>couldn't shouldn't can't</p>"; + assert.equal(html, ejs.render(str)); + }, + + 'test single quotes inside tags': function() { + var html = '<p>string</p>', + str = "<p><%= 'string' %></p>"; + assert.equal(html, ejs.render(str)); + }, + + 'test back-slashes in the document': function() { + var html = "<p>backslash: '\\'</p>", + str = "<p>backslash: '\\'</p>"; + assert.equal(html, ejs.render(str)); + }, + + 'test double quotes': function(){ + var html = '<p>WAHOO</p>', + str = '<p><%= up("wahoo") %></p>', + locals = { up: function(str){ return str.toUpperCase(); }}; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test multiple double quotes': function() { + var html = '<p>just a "test" wahoo</p>', + str = '<p>just a "test" wahoo</p>'; + assert.equal(html, ejs.render(str)); + }, + + 'test pass options as locals': function(){ + var html = '<p>foo</p>', + str = '<p><%="foo"%></p>'; + assert.equal(html, ejs.render(str)); + + var html = '<p>foo</p>', + str = '<p><%=bar%></p>'; + assert.equal(html, ejs.render(str, { bar: 'foo' })); + }, + + 'test whitespace': function(){ + var html = '<p>foo</p>', + str = '<p><%="foo"%></p>'; + assert.equal(html, ejs.render(str)); + + var html = '<p>foo</p>', + str = '<p><%=bar%></p>'; + assert.equal(html, ejs.render(str, { locals: { bar: 'foo' }})); + }, + + 'test custom tags': function(){ + var html = '<p>foo</p>', + str = '<p>{{= "foo" }}</p>'; + + assert.equal(html, ejs.render(str, { + open: '{{', + close: '}}' + })); + + var html = '<p>foo</p>', + str = '<p><?= "foo" ?></p>'; + + assert.equal(html, ejs.render(str, { + open: '<?', + close: '?>' + })); + }, + + 'test custom tags over 2 chars': function(){ + var html = '<p>foo</p>', + str = '<p>{{{{= "foo" }>>}</p>'; + + assert.equal(html, ejs.render(str, { + open: '{{{{', + close: '}>>}' + })); + + var html = '<p>foo</p>', + str = '<p><??= "foo" ??></p>'; + + assert.equal(html, ejs.render(str, { + open: '<??', + close: '??>' + })); + }, + + 'test global custom tags': function(){ + var html = '<p>foo</p>', + str = '<p>{{= "foo" }}</p>'; + ejs.open = '{{'; + ejs.close = '}}'; + assert.equal(html, ejs.render(str)); + delete ejs.open; + delete ejs.close; + }, + + 'test iteration': function(){ + var html = '<p>foo</p>', + str = '<% for (var key in items) { %>' + + '<p><%= items[key] %></p>' + + '<% } %>'; + assert.equal(html, ejs.render(str, { + locals: { + items: ['foo'] + } + })); + + var html = '<p>foo</p>', + str = '<% items.forEach(function(item){ %>' + + '<p><%= item %></p>' + + '<% }) %>'; + assert.equal(html, ejs.render(str, { + locals: { + items: ['foo'] + } + })); + }, + + 'test filter support': function(){ + var html = 'Zab', + str = '<%=: items | reverse | first | reverse | capitalize %>'; + assert.equal(html, ejs.render(str, { + locals: { + items: ['foo', 'bar', 'baz'] + } + })); + }, + + 'test filter argument support': function(){ + var html = 'tj, guillermo', + str = '<%=: users | map:"name" | join:", " %>'; + assert.equal(html, ejs.render(str, { + locals: { + users: [ + { name: 'tj' }, + { name: 'guillermo' } + ] + } + })); + }, + + 'test sort_by filter': function(){ + var html = 'tj', + str = '<%=: users | sort_by:"name" | last | get:"name" %>'; + assert.equal(html, ejs.render(str, { + locals: { + users: [ + { name: 'guillermo' }, + { name: 'tj' }, + { name: 'mape' } + ] + } + })); + }, + + 'test custom filters': function(){ + var html = 'Welcome Tj Holowaychuk', + str = '<%=: users | first | greeting %>'; + + ejs.filters.greeting = function(user){ + return 'Welcome ' + user.first + ' ' + user.last + ''; + }; + + assert.equal(html, ejs.render(str, { + locals: { + users: [ + { first: 'Tj', last: 'Holowaychuk' } + ] + } + })); + }, + + 'test useful stack traces': function(){ + var str = [ + "A little somethin'", + "somethin'", + "<% if (name) { %>", // Failing line + " <p><%= name %></p>", + " <p><%= email %></p>", + "<% } %>" + ].join("\n"); + + try { + ejs.render(str) + } catch (err) { + assert.ok(~err.message.indexOf("name is not defined")); + assert.deepEqual(err.name, "ReferenceError"); + var lineno = parseInt(err.toString().match(/ejs:(\d+)\n/)[1]); + assert.deepEqual(lineno,3, "Error should been thrown on line 3, was thrown on line "+lineno); + } + }, + + 'test useful stack traces multiline': function(){ + var str = [ + "A little somethin'", + "somethin'", + "<% var some = 'pretty';", + " var multiline = 'javascript';", + "%>", + "<% if (name) { %>", // Failing line + " <p><%= name %></p>", + " <p><%= email %></p>", + "<% } %>" + ].join("\n"); + + try { + ejs.render(str) + } catch (err) { + assert.ok(~err.message.indexOf("name is not defined")); + assert.deepEqual(err.name, "ReferenceError"); + var lineno = parseInt(err.toString().match(/ejs:(\d+)\n/)[1]); + assert.deepEqual(lineno, 6, "Error should been thrown on line 3, was thrown on line "+lineno); + } + }, + + 'test slurp' : function() { + var expected = 'me\nhere', + str = 'me<% %>\nhere'; + assert.equal(expected, ejs.render(str)); + + var expected = 'mehere', + str = 'me<% -%>\nhere'; + assert.equal(expected, ejs.render(str)); + + var expected = 'me\nhere', + str = 'me<% -%>\n\nhere'; + assert.equal(expected, ejs.render(str)); + + var expected = 'me inbetween \nhere', + str = 'me <%= x %> \nhere'; + assert.equal(expected, ejs.render(str,{x:'inbetween'})); + + var expected = 'me inbetween here', + str = 'me <%= x -%> \nhere'; + assert.equal(expected, ejs.render(str,{x:'inbetween'})); + + var expected = 'me <p>inbetween</p> here', + str = 'me <%- x -%> \nhere'; + assert.equal(expected, ejs.render(str,{x:'<p>inbetween</p>'})); + + var expected = '\n Hallo 0\n\n Hallo 1\n\n', + str = '<% for(var i in [1,2]) { %>\n' + + ' Hallo <%= i %>\n' + + '<% } %>\n'; + assert.equal(expected, ejs.render(str)); + + var expected = ' Hallo 0\n Hallo 1\n', + str = '<% for(var i in [1,2]) { -%>\n' + + ' Hallo <%= i %>\n' + + '<% } -%>\n'; + assert.equal(expected, ejs.render(str)); + } + +}; diff --git a/node_modules/ejs/test/fixtures/user.ejs b/node_modules/ejs/test/fixtures/user.ejs new file mode 100644 index 0000000..b312b5d --- /dev/null +++ b/node_modules/ejs/test/fixtures/user.ejs @@ -0,0 +1 @@ +<h1>{= name}</h1>
\ No newline at end of file |
