Socket
Socket
Sign inDemoInstall

ejs-html

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ejs-html - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

custom-els.md

7

HISTORY.md

@@ -0,1 +1,8 @@

# 3.0.0
## Breaking Changes
* Changed: EJS eval tags `<% %>` are no longer allowed in attribute values, for safety and simplicity, use escaped tags `<%= %>`
* Removed: `standAlone` option to `compile()`. Use new function `compile.standAlone()` for similar effect
* Added: `compile.standAlone()`. It returns the JS render function body as a string. The string can be trasmitted to a client and then the render function reconstructed with `new Function('locals, customRender', code)`
# 2.1.0

@@ -2,0 +9,0 @@ * Added: exposed `getSnippet()`

1

index.js

@@ -12,2 +12,3 @@ 'use strict'

* @param {boolean} [options.standAlone=false]
* @returns {string}
*/

@@ -14,0 +15,0 @@ module.exports.render = function (source, locals, options) {

140

lib/compile.js

@@ -1,2 +0,1 @@

/*jshint evil:true*/
'use strict'

@@ -10,16 +9,2 @@

/**
* Prepare render source for stand-alone function
* @var {string}
*/
let standAloneRenderCode = render.toString()
// Remove function signature and closing '}'
standAloneRenderCode = standAloneRenderCode
.substring(standAloneRenderCode.indexOf('\n') + 1, standAloneRenderCode.length - 2)
// Add stand-alone versions of escapeHTML
standAloneRenderCode = `var escapeHTML = ${escape.html.standAlone.toString()}
${standAloneRenderCode}`
/**
* A function that may transform the parsed tree before the compilation continues.

@@ -34,2 +19,16 @@ * This should return a new array of tokens or `undefined` to use the same (in case

/**
* @callback Render
* @param {Object} locals
* @param {CustomRender} customRender
* @returns {string}
*/
/**
* @callback CustomRender
* @param {string} elementName
* @param {Object} locals
* @returns {string}
*/
/**
* @param {string} source

@@ -39,5 +38,4 @@ * @param {Object} [options]

* @param {string} [options.filename='ejs']
* @param {boolean} [options.standAlone=false]
* @param {TransformerFn} [options.transformer]
* @returns {function(Object):string}
* @returns {Render}
*/

@@ -47,2 +45,54 @@ module.exports = function (source, options) {

let jsCode = prepareInternalJSCode(source, options),
filename = options.filename || 'ejs'
let internalRender
try {
/*jshint evil:true*/
internalRender = new Function('locals, renderCustom, __escape, __line', jsCode)
} catch (e) {
e.message += ` (in ${filename}, while compiling ejs)`
throw e
}
return function (locals, renderCustom) {
let line = {
start: 0,
end: 0
}
try {
return internalRender(locals, renderCustom, escape.html, line)
} catch (err) {
let snippet = getSnippet(source, line.start, line.end)
err.path = filename
err.message = `${filename}:${line.start}\n${snippet}\n\n${err.message}`
throw err
}
}
}
/**
* Much like {@link compile}, but returns a stand-alone JS source code,
* that can be exported to another JS VM. When there, turn this into a function
* with: render = new Function('locals, customRender', returnedCode)
* @returns {string}
*/
module.exports.standAlone = function (source, options) {
let jsCode = prepareInternalJSCode(source, options)
return `var __escape = ${escape.html.standAloneCode}, __line = {}; ${jsCode}`
}
/**
* Common logic for `compile` and `compile.standAlone`
* @private
* @param {string} source
* @param {Object} [options]
* @param {boolean} [options.debug=false]
* @param {string} [options.filename='ejs']
* @param {TransformerFn} [options.transformer]
* @returns {Render}
*/
function prepareInternalJSCode(source, options) {
options = options || {}
// Parse

@@ -57,6 +107,3 @@ let tokens = parse(source)

let reducedTokens = reduce(tokens),
jsCode = createCode(reducedTokens),
escapeHTML = escape.html,
filename = options.filename || 'ejs',
internalRender
jsCode = createCode(reducedTokens)

@@ -67,24 +114,3 @@ if (options.debug) {

if (options.standAlone) {
// internalRender, source, filename
let standAloneCode = `var internalRender = function (locals, __escape, __line) {
${jsCode}
}
var source = "${escape.js(source)}"
var filename = "${escape.js(filename)}"
var getSnippet = ${getSnippet}
${standAloneRenderCode}`
return new Function('locals, renderCustom', standAloneCode)
}
try {
internalRender = new Function('locals, __escape, __line, __renderCustom', jsCode)
} catch (e) {
e.message += ` (in ${filename}, while compiling ejs)`
throw e
}
return function (locals, renderCustom) {
return render(locals, escapeHTML, renderCustom, internalRender, source, filename)
}
return jsCode
}

@@ -130,28 +156,2 @@

module.exports.createCode = createCode
/**
* @param {Object} locals
* @param {function(string):string} escapeHTML
* @param {Function} renderCustom
* @param {Function} internalRender
* @param {string} source
* @param {string} filename
* @returns {string}
*/
function render(locals, escapeHTML, renderCustom, internalRender, source, filename) {
/*jshint esnext:false*/
var line = {
start: 0,
end: 0
}
try {
return internalRender(locals, escapeHTML, line, renderCustom)
} catch (err) {
var snippet = getSnippet(source, line.start, line.end)
err.path = filename
err.message = filename + ':' +
line.start + '\n' + snippet + '\n\n' + err.message
throw err
}
}
module.exports.createCode = createCode

@@ -12,3 +12,3 @@ 'use strict'

module.exports.prepareContent = function (element) {
let jsCode = '__renderCustom('
let jsCode = 'renderCustom('

@@ -15,0 +15,0 @@ // First parameter: tag name

@@ -31,27 +31,13 @@ 'use strict'

/**
* Stand-alone version of html escape function
* This is less efficient then the original version, but can be exported
* to the browser
* @param {string} [str]
* @returns {string}
* @type {string}
*/
module.exports.html.standAlone = function escape(str) {
/*jshint esnext:false*/
var htmlCharMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&#34;',
'\'': '&#39;'
}
module.exports.html.standAloneCode = `function escape(str) {
return str == null ? '' : String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&#39;')
.replace(/"/g, '&#34;')
}`
if (str === undefined || str === null) {
return ''
}
return String(str).replace(/[&<>"']/g, function encodeHTMLChar(c) {
return htmlCharMap[c]
})
}
/**

@@ -58,0 +44,0 @@ * Escape as to make safe to put inside double quotes: x = "..."

@@ -233,7 +233,7 @@ 'use strict'

if (match[1] === '<%-') {
throwSyntaxError('EJS unescaped tags are not allowed here')
throwSyntaxError('EJS unescaped tags are not allowed inside open tags')
} else if (match[1] === '<%=') {
throwSyntaxError('EJS escaped tags are not allowed here')
throwSyntaxError('EJS escaped tags are not allowed inside open tags')
} else if (match[1] === '<%') {
throwSyntaxError('EJS eval tags are not allowed here')
throwSyntaxError('EJS eval tags are not allowed inside open tags')
} else if (match[1] === '>') {

@@ -347,7 +347,7 @@ break

if (match[0] === '<%-') {
throwSyntaxError('Invalid quoted attribute value')
throwSyntaxError('EJS unescaped tags are not allowed inside attribute values')
} else if (match[0] === '<%=') {
parts.push(readSimpleToken('ejs-escaped', ejsEndRegex))
} else if (match[0] === '<%') {
parts.push(readSimpleToken('ejs-eval', ejsEndRegex))
throwSyntaxError('EJS eval tags are not allowed inside attribute values')
} else {

@@ -354,0 +354,0 @@ // End quote

{
"name": "ejs-html",
"version": "2.1.0",
"version": "3.0.0",
"author": "Sitegui <sitegui@sitegui.com.br>",
"description": "Embedded JavaScript HTML templates. Another implementation of EJS, focused on run-time performance, HTML syntax checking and outputting minified HTML.",
"description": "Embedded JavaScript HTML templates. An implementation of EJS focused on run-time performance, HTML syntax checking, minified HTML output and custom HTML elements.",
"main": "./index.js",

@@ -11,3 +11,3 @@ "repository": {

},
"keywords": ["ejs", "html", "template", "engine", "minification"],
"keywords": ["ejs", "html", "template", "engine", "minification", "custom elements", "web components"],
"dependencies": {},

@@ -19,7 +19,5 @@ "license": "MIT",

"scripts": {
"test": "mocha test",
"docs": "jsdoc -d docs -c docs.json -R README.md -t jaguarjs-jsdoc"
"test": "mocha test"
},
"devDependencies": {
"jsdoc": "^3.4.0",
"mocha": "^2.3.4",

@@ -26,0 +24,0 @@ "should": "^8.0.2"

@@ -6,3 +6,3 @@ # EJS HTML

Embedded JavaScript HTML templates. Another implementation of EJS, focused on run-time performance, HTML syntax checking and outputting minified HTML.
Embedded JavaScript HTML templates. An implementation of EJS focused on run-time performance, HTML syntax checking, minified HTML output and custom HTML elements.

@@ -38,3 +38,3 @@ ## Usage

* Normalize attributes spaces: `<input \n required>` → `<input required>`
* Normalize class spaces: `<div class=" a b">` → `<div class="a b">`
* Normalize class spaces: `<div class=" a b ">` → `<div class="a b">`
* Simplify boolean attributes: `<input required="oh-yeah!">` → `<input required>`

@@ -59,3 +59,3 @@ * Remove self-close slash: `<br />` → `<br>`

```js
// change I tags for EM
// change I elements for EM

@@ -111,3 +111,3 @@ var render = ejs.compile('<i>Hi</i> <p><i>Deep</i></p>', {

This is the most basic usage of this feature. For more (like passing JS values and multiple content areas), see [custom-tags.md](https://github.com/sitegui/ejs-html/blob/master/custom-tags.md)
This is the most basic usage of this feature. For more (like passing JS values and multiple content areas), see [custom-els.md](https://github.com/sitegui/ejs-html/blob/master/custom-els.md)

@@ -131,7 +131,18 @@ ## Missing features

* `filename`: used to name the file in render-time error's stack trace
* `standAlone`: if `true`, return a function that can be exported somewhere else, for example, to compile in the server and render in the browser, use this. When `false` (default), the generated function will be optimized to run in the same VM it was compiled
* `transformer`: a function that can transform the parsed HTML element tree, before the minification and compilation. This should return a new array of tokens or `undefined` to use the same (in case of in-place changes). Consult the definition of a `Token` in the [parse.js](https://github.com/sitegui/ejs-html/blob/master/lib/parse.js) file.
This will return a compiled render function that can then be called like: `render(locals[, customRender])`. `locals` is the data object used to fill the template. `customRender` is an optional function used to render custom elements, see [custom-tags.md](https://github.com/sitegui/ejs-html/blob/master/custom-tags.md) for more info about it.
This will return a compiled render function that can then be called like: `render(locals[, customRender])`. `locals` is the data object used to fill the template. `customRender` is an optional function used to render custom elements, see [custom-els.md](https://github.com/sitegui/ejs-html/blob/master/custom-els.md) for more info about it.
### compile.standAlone(source[, options])
Like `compile()`, but returns the function body code as a string, so that it can be exported somewhere else. A use case for this is compile the EJS template in the server, export the function to the client and render in the browser:
```js
// On the server
let functionBody = ejs.compile.standAlone('<p>Hi <%=name%></p>')
// On the client
var render = new Function('locals, customRender', functionBody)
render({name: 'you'}) // <p>Hi you</p>
```
### render(source[, locals[, options]])

@@ -147,8 +158,8 @@ Just a convinience for `compile(source, options)(locals)`.

### escape.html(str)
Make HTML-safe
Return a HTML-safe version of `str`, escaping &, <, >, " and '
### escape.js(str)
Escape as to make safe to put inside double quotes: `x = "..."`
Escape as to make safe to put inside double quotes: `x = "..."`, escaping \, \n, \r and "
### escape.getSnippet(source, lineStart, lineEnd)
Extract the code snippet in the given region (used internally to create error messages)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc