[Pkg-javascript-commits] [node-ejs] 01/03: New upstream version 2.5.2

Thorsten Alteholz alteholz at moszumanska.debian.org
Sat Nov 5 10:43:31 UTC 2016


This is an automated email from the git hooks/post-receive script.

alteholz pushed a commit to branch master
in repository node-ejs.

commit 19fc9de3ee0ae9d4d12da6c6f7fad55466fea1aa
Author: Thorsten Alteholz <debian at alteholz.de>
Date:   Fri Nov 4 22:56:03 2016 +0100

    New upstream version 2.5.2
---
 .eslintrc.json                                     |  31 +++
 .travis.yml                                        |   4 +-
 CHANGELOG.md                                       |  21 +-
 Jakefile                                           |   4 +-
 README.md                                          |  38 +--
 docs/jsdoc/options.jsdoc                           |   6 +-
 docs/syntax.md                                     |  22 +-
 lib/ejs.js                                         | 306 ++++++++++++---------
 package.json                                       |  16 +-
 sample/body.html                                   |   2 -
 sample/header.html                                 |   3 -
 sample/index.html                                  |  20 --
 sample/index.js                                    |  11 -
 test/ejs.js                                        |  30 ++
 test/fixtures/include-root.ejs                     |   1 +
 test/fixtures/include_preprocessor_line_slurp.ejs  |   1 +
 test/fixtures/include_preprocessor_line_slurp.html |   5 +
 .../include_preprocessor_line_slurp_child.ejs      |   5 +
 test/fixtures/strict.ejs                           |   5 +
 19 files changed, 318 insertions(+), 213 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..ee48f8e
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,31 @@
+{
+    "env": {
+        "browser": true,
+        "commonjs": true,
+        "node": true
+    },
+    "extends": "eslint:recommended",
+    "rules": {
+        "linebreak-style": [
+            "error",
+            "unix"
+        ],
+        "quotes": [
+            "error",
+            "single"
+        ],
+        "semi": [
+            "error",
+            "always"
+        ],
+        "comma-style": [
+            "error",
+            "last"
+        ],
+        "one-var": [
+            "error",
+            "never"
+        ],
+        "no-console": 0
+    }
+}
diff --git a/.travis.yml b/.travis.yml
index d826a40..595b83a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,8 +3,8 @@ sudo: false
 node_js:
   - "0.10"
   - "0.12"
-  - "iojs-1.1"
-  - "iojs-1.2"
+  - "4"
+  - "6"
 before_install:
   - npm update -g npm
   - npm --version
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1572a5f..520e5e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,23 @@
-## v2.4.1: 2016-05-24
+## v2.5.2: 2016-07-25
 
-+ Added LICENCSE file to release package
++ Added link to EJS Playground (@RyanZim)
+- Revert express auto 'root' option (@RyanZim)
+
+## v2.5.1: 2016-07-25
+
++ Output literal `%>` with `%%>` (Roy Miloh)
++ Allow setting project root for includes (@cnwhy)
++ UMD support for the browser (@RyanZim)
++ Exported `escapeXML` method to allow manual escaping of output (@mde)
++ Tests for strict mode (@RyanZim, @mde)
++ Added ESLint for project source code (@mde)
+* Whitespace slurp in preprocessor include (@mmis1000)
+* Improved line-number handling in errors (@Spikef)
+* Various doc improvements (@RyanZim, Ionică Bizău)
+
+## v2.4.2: 2016-05-24
+
++ Added LICENSE file to release package
 * Various documentation improvements (@RyanZim)
 * Better line-numbers in errors (@dgofman)
 
diff --git a/Jakefile b/Jakefile
index 28defba..3789eee 100644
--- a/Jakefile
+++ b/Jakefile
@@ -15,7 +15,7 @@ task('clean', ['clobber'], function () {
 });
 
 task('browserify', {async: true}, function () {
-  jake.exec('./node_modules/browserify/bin/cmd.js lib/ejs.js > ejs.js',
+  jake.exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js',
       buildOpts, function () {
     console.log('Browserification completed.');
     setTimeout(complete, 0);
@@ -42,5 +42,3 @@ publishTask('ejs', ['build'], function () {
   , 'test/**'
   ]);
 });
-
-
diff --git a/README.md b/README.md
index b88b7b4..1dd860f 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 Embedded JavaScript templates
 
 [![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs)
-[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs#info=devDependencies)
+[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs?type=dev)
 
 ## Installation
 
@@ -18,7 +18,7 @@ $ npm install ejs
   * Unescaped raw output with `<%- %>`
   * Newline-trim mode ('newline slurping') with `-%>` ending tag
   * Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>`
-  * Custom delimiters (e.g., use '<? ?>' instead of '<% %>')
+  * Custom delimiters (e.g., use `<? ?>` instead of `<% %>`)
   * Includes
   * Client-side support
   * Static caching of intermediate JavaScript
@@ -33,6 +33,8 @@ $ npm install ejs
 <% } %>
 ```
 
+Try EJS online at: https://ionicabizau.github.io/ejs-playground/.
+
 ## Usage
 
 ```javascript
@@ -50,19 +52,20 @@ ejs.renderFile(filename, data, options, function(err, str){
 
 It is also possible to use `ejs.render(dataAndOptions);` where you pass
 everything in a single object. In that case, you'll end up with local variables
-for all the passed options. However, be aware that your code could break if we 
+for all the passed options. However, be aware that your code could break if we
 add an option with the same name as one of your data object's properties.
 Therefore, we do not recommend using this shortcut.
 
 ## Options
 
   - `cache`           Compiled functions are cached, requires `filename`
-  - `filename`        The name of the file being rendered. Not required if you 
+  - `filename`        The name of the file being rendered. Not required if you
     are using `renderFile()`. Used by `cache` to key caches, and for includes.
+  - `root`            Set project root for includes with an absolute path (/file.ejs).
   - `context`         Function execution context
   - `compileDebug`    When `false` no debug instrumentation is compiled
-  - `client`          When `true`, compiles a function that can be rendered 
-    in the browser without needing to load the EJS Runtime 
+  - `client`          When `true`, compiles a function that can be rendered
+    in the browser without needing to load the EJS Runtime
     ([ejs.min.js](https://github.com/mde/ejs/releases/latest)).
   - `delimiter`       Character to use with angle brackets for open/close
   - `debug`           Output generated function body
@@ -76,9 +79,9 @@ Therefore, we do not recommend using this shortcut.
   - `escape`          The escaping function used with `<%=` construct. It is
     used in rendering and is `.toString()`ed in the generation of client functions. (By default escapes XML).
 
-This project uses [JSDoc](http://usejsdoc.org/). For the full public API 
-documentation, clone the repository and run `npm run doc`. This will run JSDoc 
-with the proper options and output the documentation to `out/`. If you want 
+This project uses [JSDoc](http://usejsdoc.org/). For the full public API
+documentation, clone the repository and run `npm run doc`. This will run JSDoc
+with the proper options and output the documentation to `out/`. If you want
 the both the public & private API docs, run `npm run devdoc` instead.
 
 ## Tags
@@ -89,6 +92,7 @@ the both the public & private API docs, run `npm run devdoc` instead.
   - `<%-`             Outputs the unescaped value into the template
   - `<%#`             Comment tag, no execution, no output
   - `<%%`             Outputs a literal '<%'
+  - `%%>`             Outputs a literal '%>'
   - `%>`              Plain ending tag
   - `-%>`             Trim-mode ('newline slurp') tag, trims following newline
   - `_%>`             'Whitespace Slurping' ending tag, removes all whitespace after it
@@ -98,11 +102,11 @@ For the full syntax documentation, please see [docs/syntax.md](https://github.co
 ## Includes
 
 Includes either have to be an absolute path, or, if not, are assumed as
-relative to the template with the `include` call. For example if you are 
-including `./views/user/show.ejs` from `./views/users.ejs` you would 
+relative to the template with the `include` call. For example if you are
+including `./views/user/show.ejs` from `./views/users.ejs` you would
 use `<%- include('user/show') %>`.
 
-You must specify the `filename` option for the template with the `include` 
+You must specify the `filename` option for the template with the `include`
 call unless you are using `renderFile()`.
 
 You'll likely want to use the raw output tag (`<%-`) with your include to avoid
@@ -178,8 +182,8 @@ including headers and footers, like so:
 ## Client-side support
 
 Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download
-`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning 
-the repository and running `jake build` (or `$(npm bin)/jake build` if jake is 
+`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning
+the repository and running `jake build` (or `$(npm bin)/jake build` if jake is
 not installed globally).
 
 Include one of these files on your page, and `ejs` should be available globally.
@@ -208,11 +212,11 @@ Most of EJS will work as expected; however, there are a few things to note:
   ```javascript
   var str = "Hello <%= include('file', {person: 'John'}); %>",
       fn = ejs.compile(str, {client: true});
-  
+
   fn(data, null, function(path, d){ // IncludeCallback
     // path -> 'file'
     // d -> {person: 'John'}
-    // Put your code here 
+    // Put your code here
     // Return the contents of file as a string
   }); // returns rendered string
   ```
@@ -235,5 +239,3 @@ Licensed under the Apache License, Version 2.0
 - - -
 EJS Embedded JavaScript templates copyright 2112
 mde at fleegix.org.
-
-
diff --git a/docs/jsdoc/options.jsdoc b/docs/jsdoc/options.jsdoc
index 3a531a3..8579c8e 100644
--- a/docs/jsdoc/options.jsdoc
+++ b/docs/jsdoc/options.jsdoc
@@ -32,10 +32,14 @@
  * The escaping function used with `<%=` construct. It is used in rendering
  * and is `.toString()`ed in the generation of client functions.
  *
- * @property {String}  [filename='undefined']
+ * @property {String}  [filename=undefined]
  * The filename of the template. Required for inclusion and caching unless 
  * you are using {@link module:ejs.renderFile}. Also used for error reporting.
  * 
+ * @property {String}  [root=undefined]
+ * The path to the project root. When this is set, absolute paths for includes 
+ * (/filename.ejs) will be relative to the project root.
+ * 
  * @property {String}  [delimiter='%']
  * The delimiter used in template compilation.
  *
diff --git a/docs/syntax.md b/docs/syntax.md
index a77c87d..61975f4 100644
--- a/docs/syntax.md
+++ b/docs/syntax.md
@@ -19,7 +19,7 @@ Table of contents
   - `%>`: Regular ending tag
   - `-%>`: Removes trailing newline
   - `_%>`: Removes all trailing whitespace
-- Literal tag
+- Literal tags
 - Including other files
   - “Preprocessor” directive
   - JavaScript `include()` function
@@ -30,7 +30,7 @@ Basic format
 ------------
 
 An EJS “tag” is the primary functioning unit in an EJS template. With the
-exception of the literal tag, all tags are formed by the following format:
+exception of the literal tags, all tags are formed by the following format:
 
 <pre><<em>starting</em> <em>content</em> <em>closing</em>></pre>
 
@@ -393,28 +393,29 @@ End of template
 
 `_%>` removes all whitespace after it.
 
-Literal tag
------------
+Literal tags
+------------
 
-To output a literal `<%`, use `<%%`. If a customized delimiter is used, use
+To output literal `<%` or `%>`, use `<%%` or `%%>`, respectively. If a customized delimiter is used, use
 the same syntax. E.g. use `<$$` to get `<$` if the delimiter is `$`.
 
-In regards to all the other tags, the literal tag is special as it does not
+In regards to all the other tags, the literal tags are special as they do not
 need a closing tag to function.
 
-However, think twice before you use this tag because the `<` character might
-need to be escaped as `<`.
+However, think twice before you use these tags because `<` and `>` characters might
+need to be escaped as `<` and `>`, respectively.
 
 #### Example
 
-The following example wrap `<%` in a `<pre>`, where it is not necessary to
-escape `<`.
+The following example wrap `<%` and `%>` in a `<pre>`, where it is not necessary to
+escape `<` or `>` at all.
 
 ##### EJS
 
 ```html
 <pre>This is literal: <%%</pre>
 <pre>This is literal too: <%% %></pre>
+<pre>This is literal as well: %%></pre>
 ```
 
 ##### HTML
@@ -422,6 +423,7 @@ escape `<`.
 ```html
 <pre>This is literal: <%</pre>
 <pre>This is literal too: <% %></pre>
+<pre>This is literal as well: %></pre>
 ```
 
 ## Including other files
diff --git a/lib/ejs.js b/lib/ejs.js
index c0566a6..39a7b73 100644
--- a/lib/ejs.js
+++ b/lib/ejs.js
@@ -44,19 +44,20 @@
  * @public
  */
 
-var fs = require('fs')
-  , utils = require('./utils')
-  , scopeOptionWarned = false
-  , _VERSION_STRING = require('../package.json').version
-  , _DEFAULT_DELIMITER = '%'
-  , _DEFAULT_LOCALS_NAME = 'locals'
-  , _REGEX_STRING = '(<%%|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'
-  , _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context'
-            , 'debug', 'compileDebug', 'client', '_with', 'rmWhitespace'
-            , 'strict', 'localsName'
-            ]
-  , _TRAILING_SEMCOL = /;\s*$/
-  , _BOM = /^\uFEFF/;
+var fs = require('fs');
+var path = require('path');
+var utils = require('./utils');
+
+var scopeOptionWarned = false;
+var _VERSION_STRING = require('../package.json').version;
+var _DEFAULT_DELIMITER = '%';
+var _DEFAULT_LOCALS_NAME = 'locals';
+var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
+var _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context',
+        'debug', 'compileDebug', 'client', '_with', 'root', 'rmWhitespace',
+        'strict', 'localsName'];
+var _TRAILING_SEMCOL = /;\s*$/;
+var _BOM = /^\uFEFF/;
 
 /**
  * EJS template function cache. This can be a LRU object from lru-cache NPM
@@ -84,18 +85,17 @@ exports.localsName = _DEFAULT_LOCALS_NAME;
  * Get the path to the included file from the parent file path and the
  * specified path.
  *
- * @param {String} name     specified path
- * @param {String} filename parent file path
+ * @param {String}  name     specified path
+ * @param {String}  filename parent file path
+ * @param {Boolean} isDir    parent file path whether is directory
  * @return {String}
  */
-
-exports.resolveInclude = function(name, filename) {
-  var path = require('path')
-    , dirname = path.dirname
-    , extname = path.extname
-    , resolve = path.resolve
-    , includePath = resolve(dirname(filename), name)
-    , ext = extname(name);
+exports.resolveInclude = function(name, filename, isDir) {
+  var dirname = path.dirname;
+  var extname = path.extname;
+  var resolve = path.resolve;
+  var includePath = resolve(isDir ? filename : dirname(filename), name);
+  var ext = extname(name);
   if (!ext) {
     includePath += '.ejs';
   }
@@ -103,6 +103,27 @@ exports.resolveInclude = function(name, filename) {
 };
 
 /**
+ * Get the path to the included file by Options
+ * 
+ * @param  {String}  path    specified path
+ * @param  {Options} options compilation options
+ * @return {String}
+ */
+function getIncludePath(path, options){
+  var includePath;
+  if (path.charAt(0) == '/') {
+    includePath = exports.resolveInclude(path.replace(/^\/*/,''), options.root || '/', true);
+  }
+  else {
+    if (!options.filename) {
+      throw new Error('`include` use relative path requires the \'filename\' option.');
+    }
+    includePath = exports.resolveInclude(path, options.filename);  
+  }
+  return includePath;
+}
+
+/**
  * Get the template from a string or a file, either compiled on-the-fly or
  * read from cache (if enabled), and cache the template if needed.
  *
@@ -121,35 +142,35 @@ exports.resolveInclude = function(name, filename) {
  */
 
 function handleCache(options, template) {
-  var fn
-    , path = options.filename
-    , hasTemplate = arguments.length > 1;
+  var func;
+  var filename = options.filename;
+  var hasTemplate = arguments.length > 1;
 
   if (options.cache) {
-    if (!path) {
+    if (!filename) {
       throw new Error('cache option requires a filename');
     }
-    fn = exports.cache.get(path);
-    if (fn) {
-      return fn;
+    func = exports.cache.get(filename);
+    if (func) {
+      return func;
     }
     if (!hasTemplate) {
-      template = fs.readFileSync(path).toString().replace(_BOM, '');
+      template = fs.readFileSync(filename).toString().replace(_BOM, '');
     }
   }
   else if (!hasTemplate) {
     // istanbul ignore if: should not happen at all
-    if (!path) {
+    if (!filename) {
       throw new Error('Internal EJS error: no file name or template '
                     + 'provided');
     }
-    template = fs.readFileSync(path).toString().replace(_BOM, '');
+    template = fs.readFileSync(filename).toString().replace(_BOM, '');
   }
-  fn = exports.compile(template, options);
+  func = exports.compile(template, options);
   if (options.cache) {
-    exports.cache.set(path, fn);
+    exports.cache.set(filename, func);
   }
-  return fn;
+  return func;
 }
 
 /**
@@ -167,10 +188,7 @@ function handleCache(options, template) {
 
 function includeFile(path, options) {
   var opts = utils.shallowCopy({}, options);
-  if (!opts.filename) {
-    throw new Error('`include` requires the \'filename\' option.');
-  }
-  opts.filename = exports.resolveInclude(path, opts.filename);
+  opts.filename = getIncludePath(path, opts);
   return handleCache(opts);
 }
 
@@ -180,24 +198,24 @@ function includeFile(path, options) {
  * @memberof module:ejs-internal
  * @param {String}  path    path for the specified file
  * @param {Options} options compilation options
- * @return {String}
+ * @return {Object}
  * @static
  */
 
 function includeSource(path, options) {
-  var opts = utils.shallowCopy({}, options)
-    , includePath
-    , template;
-  if (!opts.filename) {
-    throw new Error('`include` requires the \'filename\' option.');
-  }
-  includePath = exports.resolveInclude(path, opts.filename);
+  var opts = utils.shallowCopy({}, options);
+  var includePath;
+  var template;
+  includePath = getIncludePath(path,opts);
   template = fs.readFileSync(includePath).toString().replace(_BOM, '');
-
   opts.filename = includePath;
   var templ = new Template(template, opts);
   templ.generateSource();
-  return templ.source;
+  return {
+    source: templ.source,
+    filename: includePath,
+    template: template
+  };
 }
 
 /**
@@ -214,10 +232,9 @@ function includeSource(path, options) {
  */
 
 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 lines = str.split('\n');
+  var start = Math.max(lineno - 3, 0);
+  var end = Math.min(lines.length, lineno + 3);
   // Error context
   var context = lines.slice(start, end).map(function (line, i){
     var curr = i + start + 1;
@@ -302,10 +319,9 @@ exports.compile = function compile(template, opts) {
  * @public
  */
 
-exports.render = function (template, data, opts) {
-  data = data || {};
-  opts = opts || {};
-  var fn;
+exports.render = function (template, d, o) {
+  var data = d || {};
+  var opts = o || {};
 
   // No options object -- if there are optiony names
   // in the data, copy them to options
@@ -330,12 +346,12 @@ exports.render = function (template, data, opts) {
  */
 
 exports.renderFile = function () {
-  var args = Array.prototype.slice.call(arguments)
-    , path = args.shift()
-    , cb = args.pop()
-    , data = args.shift() || {}
-    , opts = args.pop() || {}
-    , result;
+  var args = Array.prototype.slice.call(arguments);
+  var filename = args.shift();
+  var cb = args.pop();
+  var data = args.shift() || {};
+  var opts = args.pop() || {};
+  var result;
 
   // Don't pollute passed in opts obj with new vals
   opts = utils.shallowCopy({}, opts);
@@ -352,7 +368,7 @@ exports.renderFile = function () {
       cpOptsInData(data, opts);
     }
   }
-  opts.filename = path;
+  opts.filename = filename;
 
   try {
     result = handleCache(opts)(data);
@@ -391,6 +407,7 @@ function Template(text, opts) {
   options.context = opts.context;
   options.cache = opts.cache || false;
   options.rmWhitespace = opts.rmWhitespace;
+  options.root = opts.root;
   options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
 
   if (options.strict) {
@@ -406,39 +423,28 @@ function Template(text, opts) {
 }
 
 Template.modes = {
-  EVAL: 'eval'
-, ESCAPED: 'escaped'
-, RAW: 'raw'
-, COMMENT: 'comment'
-, LITERAL: 'literal'
+  EVAL: 'eval',
+  ESCAPED: 'escaped',
+  RAW: 'raw',
+  COMMENT: 'comment',
+  LITERAL: 'literal'
 };
 
 Template.prototype = {
   createRegex: function () {
-    var str = _REGEX_STRING
-      , delim = utils.escapeRegExpChars(this.opts.delimiter);
+    var str = _REGEX_STRING;
+    var delim = utils.escapeRegExpChars(this.opts.delimiter);
     str = str.replace(/%/g, delim);
     return new RegExp(str);
-  }
-
-, compile: function () {
-    var src
-      , fn
-      , opts = this.opts
-      , prepended = ''
-      , appended = ''
-      , escape = opts.escapeFunction;
-
-    if (opts.rmWhitespace) {
-      // Have to use two separate replace here as `^` and `$` operators don't
-      // work well with `\r`.
-      this.templateText =
-        this.templateText.replace(/\r/g, '').replace(/^\s+|\s+$/gm, '');
-    }
+  },
 
-    // Slurp spaces and tabs before <%_ and after _%>
-    this.templateText =
-      this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
+  compile: function () {
+    var src;
+    var fn;
+    var opts = this.opts;
+    var prepended = '';
+    var appended = '';
+    var escape = opts.escapeFunction;
 
     if (!this.source) {
       this.generateSource();
@@ -515,24 +521,34 @@ Template.prototype = {
     };
     returnedFn.dependencies = this.dependencies;
     return returnedFn;
-  }
+  },
 
-, generateSource: function () {
-    var self = this
-      , matches = this.parseTemplateText()
-      , d = this.opts.delimiter;
+  generateSource: function () {
+    var opts = this.opts;
+
+    if (opts.rmWhitespace) {
+      // Have to use two separate replace here as `^` and `$` operators don't
+      // work well with `\r`.
+      this.templateText =
+        this.templateText.replace(/\r/g, '').replace(/^\s+|\s+$/gm, '');
+    }
+
+    // Slurp spaces and tabs before <%_ and after _%>
+    this.templateText =
+      this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
+
+    var self = this;
+    var matches = this.parseTemplateText();
+    var d = this.opts.delimiter;
 
     if (matches && matches.length) {
-      if (this.opts.compileDebug && this.opts.filename) {
-        this.source =  '    ; __lines = ' + JSON.stringify(this.templateText) + '\n';
-        this.source += '    ; __filename = "' + this.opts.filename.replace(/\\/g,  '/') + '"\n';
-      }
       matches.forEach(function (line, index) {
-        var opening
-          , closing
-          , include
-          , includeOpts
-          , includeSrc;
+        var opening;
+        var closing;
+        var include;
+        var includeOpts;
+        var includeObj;
+        var includeSrc;
         // If this is an opening tag, check for closing tags
         // FIXME: May end up with some false positives here
         // Better to store modes as k/v with '<' + delimiter as key
@@ -550,9 +566,23 @@ Template.prototype = {
           // Must be in EVAL or RAW mode
           if (opening && (opening == '<' + d || opening == '<' + d + '-' || opening == '<' + d + '_')) {
             includeOpts = utils.shallowCopy({}, self.opts);
-            includeSrc = includeSource(include[1], includeOpts);
-            includeSrc = '    ; (function(){' + '\n' + includeSrc +
-                '    ; })()' + '\n';
+            includeObj = includeSource(include[1], includeOpts);
+            if (self.opts.compileDebug) {
+              includeSrc =
+                  '    ; (function(){' + '\n'
+                  + '      var __line = 1' + '\n'
+                  + '      , __lines = ' + JSON.stringify(includeObj.template) + '\n'
+                  + '      , __filename = ' + JSON.stringify(includeObj.filename) + ';' + '\n'
+                  + '      try {' + '\n'
+                  + includeObj.source
+                  + '      } catch (e) {' + '\n'
+                  + '        rethrow(e, __lines, __filename, __line);' + '\n'
+                  + '      }' + '\n'
+                  + '    ; }).call(this)' + '\n';
+            }else{
+              includeSrc = '    ; (function(){' + '\n' + includeObj.source +
+                  '    ; }).call(this)' + '\n';
+            }
             self.source += includeSrc;
             self.dependencies.push(exports.resolveInclude(include[1],
                 includeOpts.filename));
@@ -563,19 +593,17 @@ Template.prototype = {
       });
     }
 
-  }
+  },
 
-, parseTemplateText: function () {
-    var str = this.templateText
-      , pat = this.regex
-      , result = pat.exec(str)
-      , arr = []
-      , firstPos
-      , lastPos;
+  parseTemplateText: function () {
+    var str = this.templateText;
+    var pat = this.regex;
+    var result = pat.exec(str);
+    var arr = [];
+    var firstPos;
 
     while (result) {
       firstPos = result.index;
-      lastPos = pat.lastIndex;
 
       if (firstPos !== 0) {
         arr.push(str.substring(0, firstPos));
@@ -592,12 +620,12 @@ Template.prototype = {
     }
 
     return arr;
-  }
+  },
 
-, scanLine: function (line) {
-    var self = this
-      , d = this.opts.delimiter
-      , newLineCount = 0;
+  scanLine: function (line) {
+    var self = this;
+    var d = this.opts.delimiter;
+    var newLineCount = 0;
 
     function _addOutput() {
       if (self.truncate) {
@@ -606,7 +634,7 @@ Template.prototype = {
         // after the tag that the truncation mode replaces
         // Handle Win / Unix / old Mac linebreaks -- do the \r\n
         // combo first in the regex-or
-        line = line.replace(/^(?:\r\n|\r|\n)/, '')
+        line = line.replace(/^(?:\r\n|\r|\n)/, '');
         self.truncate = false;
       }
       else if (self.opts.rmWhitespace) {
@@ -652,6 +680,10 @@ Template.prototype = {
         this.mode = Template.modes.LITERAL;
         this.source += '    ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n';
         break;
+      case d + d + '>':
+        this.mode = Template.modes.LITERAL;
+        this.source += '    ; __append("' + line.replace(d + d + '>', d + '>') + '")' + '\n';
+        break;
       case d + '>':
       case '-' + d + '>':
       case '_' + d + '>':
@@ -711,9 +743,17 @@ Template.prototype = {
   }
 };
 
-/*
- * Export the internal function for escaping XML so people
- * can use for manual escaping if needed
+/**
+ * Escape characters reserved in XML.
+ *
+ * This is simply an export of {@link module:utils.escapeXML}.
+ *
+ * If `markup` is `undefined` or `null`, the empty string is returned.
+ *
+ * @param {String} markup Input string
+ * @return {String} Escaped string
+ * @public
+ * @func
  * */
 exports.escapeXML = utils.escapeXML;
 
@@ -731,14 +771,14 @@ exports.__express = exports.renderFile;
 // Add require support
 /* istanbul ignore else */
 if (require.extensions) {
-  require.extensions['.ejs'] = function (module, filename) {
-    filename = filename || /* istanbul ignore next */ module.filename;
+  require.extensions['.ejs'] = function (module, flnm) {
+    var filename = flnm || /* istanbul ignore next */ module.filename;
     var options = {
-          filename: filename
-        , client: true
-        }
-      , template = fs.readFileSync(filename).toString()
-      , fn = exports.compile(template, options);
+          filename: filename,
+          client: true
+        };
+    var template = fs.readFileSync(filename).toString();
+    var fn = exports.compile(template, options);
     module._compile('module.exports = ' + fn.toString() + ';', filename);
   };
 }
diff --git a/package.json b/package.json
index c311f1c..fb178ba 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
     "engine",
     "ejs"
   ],
-  "version": "2.4.2",
+  "version": "2.5.2",
   "author": "Matthew Eernisse <mde at fleegix.org> (http://fleegix.org)",
   "contributors": [
     "Timothy Gu <timothygu99 at gmail.com> (https://timothygu.github.io)"
@@ -21,21 +21,21 @@
   "homepage": "https://github.com/mde/ejs",
   "dependencies": {},
   "devDependencies": {
-    "browserify": "^8.0.3",
-    "istanbul": "~0.3.5",
+    "browserify": "^13.0.1",
+    "eslint": "^3.0.0",
+    "istanbul": "~0.4.3",
     "jake": "^8.0.0",
-    "jsdoc": "^3.3.0-beta1",
-    "lru-cache": "^2.5.0",
-    "mocha": "^2.1.0",
+    "jsdoc": "^3.4.0",
+    "lru-cache": "^4.0.1",
+    "mocha": "^3.0.2",
     "rimraf": "^2.2.8",
-    "uglify-js": "^2.4.16"
+    "uglify-js": "^2.6.2"
   },
   "engines": {
     "node": ">=0.10.0"
   },
   "scripts": {
     "test": "mocha",
-    "sample": "npm install express && node sample/index.js",
     "coverage": "istanbul cover node_modules/mocha/bin/_mocha",
     "doc": "rimraf out && jsdoc -c jsdoc.json lib/* docs/jsdoc/*",
     "devdoc": "rimraf out && jsdoc -p -c jsdoc.json lib/* docs/jsdoc/*"
diff --git a/sample/body.html b/sample/body.html
deleted file mode 100644
index 84b9905..0000000
--- a/sample/body.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!-- Execute an exception -->
-<p><%= this_variable_is_not_defined %></p>
\ No newline at end of file
diff --git a/sample/header.html b/sample/header.html
deleted file mode 100644
index afc41bf..0000000
--- a/sample/header.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<head>
-<title><%= header %></title>
-</head>
\ No newline at end of file
diff --git a/sample/index.html b/sample/index.html
deleted file mode 100644
index f19ec67..0000000
--- a/sample/index.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html>
-<head>
-<% include header.html %>
-</head>
-<body>
-<!--
-	Without fix output is confusing
-
-	ReferenceError: ./ejs/test/sample/index.html:2
-   1| <html> 
->> 2| <head> 
-   3| <% include header.html %> 
-   4| </head> 
-   5| <body> 
-
-this_variable_is_not_defined is not defined
--->
-<% include body.html %>
-</body>
-</html>
\ No newline at end of file
diff --git a/sample/index.js b/sample/index.js
deleted file mode 100644
index 08284af..0000000
--- a/sample/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-var express = require('express'),
-    ejs = require('../lib/ejs.js');
-var app = express();
-app.engine('.html', ejs.__express);
-app.set('view engine', 'ejs');
-app.get('/', function(req, res) {
-	res.render(__dirname + '/index.html', {header: 'Hello EJS'});
-});
-var server = app.listen(3000, function () {
-  console.log('Example app listening at http://localhost:3000');
-});
\ No newline at end of file
diff --git a/test/ejs.js b/test/ejs.js
index 1baf07f..a2d593d 100644
--- a/test/ejs.js
+++ b/test/ejs.js
@@ -161,6 +161,10 @@ suite('ejs.compile(str, options)', function () {
     }
   });
 
+  test('strict mode works', function () {
+    assert.equal(ejs.render(fixture('strict.ejs'), {}, {strict: true}), 'true');
+  });
+
 });
 
 suite('ejs.render(str, data, opts)', function () {
@@ -591,6 +595,15 @@ suite('<%%', function () {
   });
 });
 
+suite('%%>', function () {
+  test('produce literal', function () {
+    assert.equal(ejs.render('%%>'),
+        '%>');
+    assert.equal(ejs.render('  >', {}, {delimiter: ' '}),
+        ' >');
+  });
+});
+
 suite('<%_ and _%>', function () {
   test('slurps spaces and tabs', function () {
     assert.equal(ejs.render(fixture('space-and-tab-slurp.ejs'), {users: users}),
@@ -727,6 +740,14 @@ suite('include()', function () {
         fixture('include.html'));
   });
 
+  test('include ejs with set root path', function () {
+    var file = 'test/fixtures/include-root.ejs',
+        viewsPath = path.join(__dirname, 'fixtures');
+    assert.equal(ejs.render(fixture('include-root.ejs'), {pets: users}, {filename: file, delimiter: '@',root:viewsPath}),
+      fixture('include.html'));
+
+  });
+
   test('work when nested', function () {
     var file = 'test/fixtures/menu.ejs';
     assert.equal(ejs.render(fixture('menu.ejs'), {pets: users}, {filename: file}),
@@ -884,6 +905,15 @@ suite('preprocessor include', function () {
     assert.equal(out, expected);
   });
 
+  test('whitespace slurp and rmWhitespace work', function() {
+    var file = 'test/fixtures/include_preprocessor_line_slurp.ejs'
+      , template = fixture('include_preprocessor_line_slurp.ejs')
+      , expected = fixture('include_preprocessor_line_slurp.html')
+      , options = {rmWhitespace: true, filename: file};
+    assert.equal(ejs.render(template, options),
+        expected);
+  })
+
 });
 
 suite('comments', function () {
diff --git a/test/fixtures/include-root.ejs b/test/fixtures/include-root.ejs
new file mode 100644
index 0000000..395d6a1
--- /dev/null
+++ b/test/fixtures/include-root.ejs
@@ -0,0 +1 @@
+<@- include('/include'); @>
\ No newline at end of file
diff --git a/test/fixtures/include_preprocessor_line_slurp.ejs b/test/fixtures/include_preprocessor_line_slurp.ejs
new file mode 100644
index 0000000..fd1765c
--- /dev/null
+++ b/test/fixtures/include_preprocessor_line_slurp.ejs
@@ -0,0 +1 @@
+<% include include_preprocessor_line_slurp_child %>
\ No newline at end of file
diff --git a/test/fixtures/include_preprocessor_line_slurp.html b/test/fixtures/include_preprocessor_line_slurp.html
new file mode 100644
index 0000000..7ab7998
--- /dev/null
+++ b/test/fixtures/include_preprocessor_line_slurp.html
@@ -0,0 +1,5 @@
+<div>
+12
+3
+45
+</div>
\ No newline at end of file
diff --git a/test/fixtures/include_preprocessor_line_slurp_child.ejs b/test/fixtures/include_preprocessor_line_slurp_child.ejs
new file mode 100644
index 0000000..1c4a7c6
--- /dev/null
+++ b/test/fixtures/include_preprocessor_line_slurp_child.ejs
@@ -0,0 +1,5 @@
+<div>
+1   <%_ if (true) { _%> 2
+        3
+4   <%_ } _%> 5
+</div>
\ No newline at end of file
diff --git a/test/fixtures/strict.ejs b/test/fixtures/strict.ejs
new file mode 100644
index 0000000..408ebcf
--- /dev/null
+++ b/test/fixtures/strict.ejs
@@ -0,0 +1,5 @@
+<%
+// Unspecified execution context should be `undefined` in strict mode
+var isReallyStrict = !((function () { return this; })())
+-%>
+<%= isReallyStrict -%>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-ejs.git



More information about the Pkg-javascript-commits mailing list