htmljs-parser
Advanced tools
Comparing version 1.0.5 to 1.0.6
@@ -25,2 +25,35 @@ var CODE_NEWLINE = 10; | ||
/** | ||
* Takes a string expression such as `"foo"` or `'foo "bar"'` | ||
* and returns the literal String value. | ||
*/ | ||
function evaluateStringExpression(expression) { | ||
// We could just use eval(expression) to get the literal String value, | ||
// but there is a small chance we could be introducing a security threat | ||
// by accidently running malicous code. Instead, we will use | ||
// JSON.parse(expression). JSON.parse() only allows strings | ||
// that use double quotes so we have to do extra processing if | ||
// we detect that the String uses single quotes | ||
if (expression.charAt(0) === "'") { | ||
expression = expression.substring(1, expression.length - 1); | ||
// Make sure there are no unescaped double quotes in the string expression... | ||
expression = expression.replace(/\\\\|\\["]|["]/g, function(match) { | ||
if (match === '"'){ | ||
// Return an escaped double quote if we encounter an | ||
// unescaped double quote | ||
return '\\"'; | ||
} else { | ||
// Return the escape sequence | ||
return match; | ||
} | ||
}); | ||
expression = '"' + expression + '"'; | ||
} | ||
return JSON.parse(expression); | ||
} | ||
exports.createNotifiers = function(parser, listeners) { | ||
@@ -71,3 +104,3 @@ return { | ||
notifyOpenTag(tagName, attributes, elementArguments, selfClosed) { | ||
notifyOpenTag(tagName, attributes, elementArguments, selfClosed, pos) { | ||
if (listeners.onopentag) { | ||
@@ -84,6 +117,7 @@ if (elementArguments) { | ||
// if possib | ||
// If the expression evaluates to a literal value then add the | ||
// `literalValue` property to the attribute | ||
if (attr.isStringLiteral) { | ||
var expression = attr.expression; | ||
attr.literalValue = expression.substring(1, expression.length - 1); | ||
attr.literalValue = evaluateStringExpression(expression); | ||
} else if (attr.isSimpleLiteral) { | ||
@@ -104,3 +138,4 @@ _updateAttributeLiteralValue(attr); | ||
tagName: tagName, | ||
attributes: attributes | ||
attributes: attributes, | ||
pos: pos | ||
}; | ||
@@ -107,0 +142,0 @@ |
{ | ||
"name": "htmljs-parser", | ||
"description": "An HTML parser recognizes content and string placeholders and allows JavaScript expressions as attribute values", | ||
"keywords": [ | ||
"HTML", | ||
"parser", | ||
"JavaScript", | ||
"expressions", | ||
"browser", | ||
"server", | ||
"nodejs", | ||
"template", | ||
"compiler" | ||
], | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha --ui bdd --reporter spec ./test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/philidem/htmljs-parser.git" | ||
}, | ||
"author": "Phillip Gates-Idem <phillip.idem@gmail.com>", | ||
"maintainers": "Phillip Gates-Idem <phillip.idem@gmail.com>", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"chai": "^3.2.0", | ||
"colors": "^1.1.2", | ||
"jshint": "^2.8.0", | ||
"mocha": "^2.3.0" | ||
}, | ||
"license": "MIT", | ||
"publishConfig": { | ||
"registry": "https://registry.npmjs.org/" | ||
}, | ||
"version": "1.0.5" | ||
} | ||
"name": "htmljs-parser", | ||
"description": "An HTML parser recognizes content and string placeholders and allows JavaScript expressions as attribute values", | ||
"keywords": [ | ||
"HTML", | ||
"parser", | ||
"JavaScript", | ||
"expressions", | ||
"browser", | ||
"server", | ||
"nodejs", | ||
"template", | ||
"compiler" | ||
], | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node_modules/.bin/mocha --ui bdd --reporter spec ./test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/philidem/htmljs-parser.git" | ||
}, | ||
"author": "Phillip Gates-Idem <phillip.idem@gmail.com>", | ||
"maintainers": "Phillip Gates-Idem <phillip.idem@gmail.com>", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"chai": "^3.2.0", | ||
"colors": "^1.1.2", | ||
"jshint": "^2.8.0", | ||
"mocha": "^2.3.0" | ||
}, | ||
"license": "MIT", | ||
"publishConfig": { | ||
"registry": "https://registry.npmjs.org/" | ||
}, | ||
"version": "1.0.6" | ||
} |
@@ -31,2 +31,3 @@ 'use strict'; | ||
var CODE_NEWLINE = 10; | ||
var CODE_CARRIAGE_RETURN = 13; | ||
var CODE_DASH = 45; | ||
@@ -131,3 +132,8 @@ var CODE_DOLLAR = 36; | ||
_notifyOpenTag(tagName, attributes, elementArgument, false /* not selfClosed */); | ||
_notifyOpenTag( | ||
tagName, | ||
attributes, | ||
elementArgument, | ||
false, /* not selfClosed */ | ||
tagPos); | ||
@@ -150,3 +156,3 @@ // Did the parser stay in the same state after | ||
function _afterSelfClosingTag() { | ||
_notifyOpenTag(tagName, attributes, elementArgument, true /* selfClosed */); | ||
_notifyOpenTag(tagName, attributes, elementArgument, true /* selfClosed */, tagPos); | ||
_notifyCloseTag(tagName, true /* selfClosed */); | ||
@@ -388,3 +394,2 @@ parser.enterHtmlContentState(); | ||
if (code === CODE_LEFT_ANGLE_BRACKET) { | ||
tagPos = parser.pos; | ||
@@ -1017,2 +1022,10 @@ | ||
currentExpression.currentStringPart += ch + nextCh; | ||
} else if (code === CODE_NEWLINE) { | ||
// Add an escape sequence for a new line if an actual new line | ||
// is found before the string is ended | ||
currentExpression.currentStringPart += '\\n'; | ||
} else if (code === CODE_CARRIAGE_RETURN) { | ||
// Add an escape sequence for a carriage return if an actual carriage return | ||
// is found before the string is ended | ||
currentExpression.currentStringPart += '\\r'; | ||
} else if (code === stringDelimiterCode) { | ||
@@ -1105,2 +1118,10 @@ // We encountered the end delimiter | ||
commentHandler.end(); | ||
} else if (code === CODE_CARRIAGE_RETURN) { | ||
// Handle Windows new line sequence: '\r\n' | ||
var nextCode = parser.lookAtCharCodeAhead(1); | ||
if (nextCode === CODE_NEWLINE) { | ||
parser.skip(1); | ||
} | ||
commentHandler.end(); | ||
} | ||
@@ -1107,0 +1128,0 @@ } |
@@ -265,3 +265,3 @@ htmljs-parser | ||
**EXAMPLE: Attribute an argument** | ||
**EXAMPLE: Attribute with an argument** | ||
@@ -467,3 +467,3 @@ INPUT: | ||
The `oncontentplaceholder` function will be called each time a placeholder | ||
The `onattributeplaceholder` function will be called each time a placeholder | ||
is encountered within an attribute string value. This event will be emitted | ||
@@ -470,0 +470,0 @@ before `onopentag` so by changing the `expression` property of the event, |
@@ -5,3 +5,4 @@ var chai = require('chai'); | ||
var expect = require('chai').expect; | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
var htmljs = require('../'); | ||
@@ -13,3 +14,3 @@ | ||
if (arguments.length === 2) { | ||
if (Array.isArray(options)) { | ||
expectedEvents = arguments[1]; | ||
@@ -85,3 +86,7 @@ options = undefined; | ||
expect(actualEvents).to.deep.equal(expectedEvents); | ||
if (expectedEvents) { | ||
expect(actualEvents).to.deep.equal(expectedEvents); | ||
} | ||
return actualEvents; | ||
} | ||
@@ -187,3 +192,4 @@ | ||
tagName: 'html', | ||
attributes: [] | ||
attributes: [], | ||
pos: 0 | ||
}, | ||
@@ -193,3 +199,4 @@ { | ||
tagName: 'javascript', | ||
attributes: [] | ||
attributes: [], | ||
pos: 6 | ||
}, | ||
@@ -207,3 +214,4 @@ { | ||
tagName: 'css', | ||
attributes: [] | ||
attributes: [], | ||
pos: 95 | ||
}, | ||
@@ -221,3 +229,4 @@ { | ||
tagName: 'text', | ||
attributes: [] | ||
attributes: [], | ||
pos: 142 | ||
}, | ||
@@ -235,3 +244,4 @@ { | ||
tagName: 'parsedtext', | ||
attributes: [] | ||
attributes: [], | ||
pos: 202 | ||
}, | ||
@@ -318,2 +328,3 @@ { | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -339,2 +350,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -368,2 +380,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'style', | ||
@@ -391,2 +404,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -421,2 +435,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -459,2 +474,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -484,2 +500,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -510,2 +527,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -537,2 +555,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -561,2 +580,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -585,2 +605,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -607,2 +628,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -627,2 +649,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -654,2 +677,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -659,3 +683,3 @@ attributes: [ | ||
name: 'data', | ||
expression: '"\nabc\n124"', | ||
expression: '"\\nabc\\n124"', | ||
literalValue: '\nabc\n124' | ||
@@ -675,2 +699,3 @@ } | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -694,2 +719,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -713,2 +739,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -732,2 +759,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -751,2 +779,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -849,2 +878,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -898,2 +928,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -921,2 +952,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -946,3 +978,4 @@ attributes: [] | ||
attributes: [], | ||
selfClosed: true | ||
selfClosed: true, | ||
pos: 0 | ||
}, | ||
@@ -985,2 +1018,3 @@ { | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1016,2 +1050,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1047,2 +1082,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1073,2 +1109,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1099,2 +1136,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1136,2 +1174,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1167,2 +1206,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1198,2 +1238,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1216,2 +1257,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1234,2 +1276,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1252,2 +1295,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1314,2 +1358,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'custom', | ||
@@ -1334,2 +1379,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -1355,2 +1401,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'for', | ||
@@ -1369,2 +1416,3 @@ argument: 'x in y', | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'for', | ||
@@ -1383,2 +1431,3 @@ argument: 'x in y', | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'for', | ||
@@ -1397,2 +1446,3 @@ argument: 'x in [("Hello "+(name)+"!"), "(World)"]', | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -1415,2 +1465,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -1433,2 +1484,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'for', | ||
@@ -1460,2 +1512,3 @@ argument: 'var i = 0; i < 10; i++', | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'for', | ||
@@ -1482,2 +1535,3 @@ argument: 'var i = 0; i < 10; i++', | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'div', | ||
@@ -1502,2 +1556,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -1521,2 +1576,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -1540,2 +1596,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -1559,2 +1616,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'a', | ||
@@ -1601,2 +1659,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1660,2 +1719,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'style', | ||
@@ -1720,2 +1780,3 @@ attributes: [ | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1745,2 +1806,3 @@ attributes: [] | ||
type: 'opentag', | ||
pos: 0, | ||
tagName: 'script', | ||
@@ -1813,2 +1875,11 @@ attributes: [] | ||
}); | ||
require('./autotest').scanDir( | ||
path.join(__dirname, 'fixtures/autotest'), | ||
function (dir) { | ||
var inputPath = path.join(dir, 'input.htmljs'); | ||
var inputHtmlJs = fs.readFileSync(inputPath, {encoding: 'utf8'}); | ||
var parserEvents = parse(inputHtmlJs); | ||
return parserEvents; | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
143600
17
3678
3
1