Socket
Socket
Sign inDemoInstall

@riotjs/parser

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@riotjs/parser - npm Package Compare versions

Comparing version 4.3.1 to 5.0.0

399

index.js

@@ -1,5 +0,1 @@

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const JAVASCRIPT_OUTPUT_NAME = 'javascript';

@@ -24,14 +20,14 @@ const CSS_OUTPUT_NAME = 'css';

__proto__: null,
JAVASCRIPT_OUTPUT_NAME: JAVASCRIPT_OUTPUT_NAME,
CSS_OUTPUT_NAME: CSS_OUTPUT_NAME,
TEMPLATE_OUTPUT_NAME: TEMPLATE_OUTPUT_NAME,
JAVASCRIPT_TAG: JAVASCRIPT_TAG,
STYLE_TAG: STYLE_TAG,
TEXTAREA_TAG: TEXTAREA_TAG,
IS_BOOLEAN: IS_BOOLEAN,
IS_CUSTOM: IS_CUSTOM,
IS_RAW: IS_RAW,
IS_SELF_CLOSING: IS_SELF_CLOSING,
IS_SPREAD: IS_SPREAD,
IS_VOID: IS_VOID,
IS_BOOLEAN: IS_BOOLEAN,
IS_CUSTOM: IS_CUSTOM,
IS_SPREAD: IS_SPREAD
JAVASCRIPT_OUTPUT_NAME: JAVASCRIPT_OUTPUT_NAME,
JAVASCRIPT_TAG: JAVASCRIPT_TAG,
STYLE_TAG: STYLE_TAG,
TEMPLATE_OUTPUT_NAME: TEMPLATE_OUTPUT_NAME,
TEXTAREA_TAG: TEXTAREA_TAG
});

@@ -56,10 +52,10 @@

__proto__: null,
TAG: TAG,
ATTR: ATTR,
TEXT: TEXT,
CDATA: CDATA,
COMMENT: COMMENT,
DOCTYPE: DOCTYPE,
DOCUMENT: DOCUMENT,
DOCTYPE: DOCTYPE,
DOCUMENT_FRAGMENT: DOCUMENT_FRAGMENT
DOCUMENT_FRAGMENT: DOCUMENT_FRAGMENT,
TAG: TAG,
TEXT: TEXT
});

@@ -72,3 +68,4 @@

const unclosedNamedBlock = 'Unclosed "%1" block.';
const duplicatedNamedTag = 'Multiple inline "<%1>" tags are not supported.';
const duplicatedNamedTag =
'Multiple inline "<%1>" tags are not supported.';
const unexpectedCharInExpression = 'Unexpected character %1.';

@@ -113,3 +110,3 @@ const unclosedExpression = 'Unclosed expression.';

style: /<\/style\s*>/gi,
textarea: /<\/textarea\s*>/gi
textarea: /<\/textarea\s*>/gi,
};

@@ -182,3 +179,3 @@

let c;
while (re.lastIndex = pos, re.exec(code)) {
while (((re.lastIndex = pos), re.exec(code))) {
pos = re.lastIndex;

@@ -230,3 +227,3 @@ c = code[pos - 1];

'void',
'yield'
'yield',
];

@@ -239,3 +236,4 @@

// The buffer to search must not include line-endings.
const RE_LIT_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/;
const RE_LIT_REGEX =
/^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/;

@@ -262,4 +260,2 @@ // Valid characters for JavaScript variable names and literal numbers.

/**

@@ -278,5 +274,5 @@ * Check if the character in the `start` position within `code` can be a regex

*/
/* istanbul ignore next */
/* c8 ignore next */
function skipRegex(code, start) {
let pos = RE_DOT_CHAR.lastIndex = start++;
let pos = (RE_DOT_CHAR.lastIndex = start++);

@@ -288,3 +284,3 @@ // `exec()` will extract from the slash to the end of the line

if (match) {
const next = pos + match[0].length; // result comes from `re.match`
const next = pos + match[0].length; // result comes from `re.match`

@@ -305,15 +301,16 @@ pos = _prev(code, pos);

}
} else {
if (c === '+' || c === '-') {
// tricky case
if (code[--pos] !== c || // if have a single operator or
(pos = _prev(code, pos)) < 0 || // ...have `++` and no previous token
beforeReSign.includes(c = code[pos])) {
return next // ...this is a regex
if (
code[--pos] !== c || // if have a single operator or
(pos = _prev(code, pos)) < 0 || // ...have `++` and no previous token
beforeReSign.includes((c = code[pos]))
) {
return next // ...this is a regex
}
}
if (wordsEndChar.includes(c)) { // looks like a keyword?
if (wordsEndChar.includes(c)) {
// looks like a keyword?
const end = pos + 1;

@@ -397,22 +394,22 @@

switch (char) {
case '[':
case '(':
case '{':
stack.push(char === '[' ? ']' : char === '(' ? ')' : '}');
break
case ')':
case ']':
case '}':
if (char !== stack.pop()) {
panic(code, unexpectedCharInExpression.replace('%1', char), index);
}
case '[':
case '(':
case '{':
stack.push(char === '[' ? ']' : char === '(' ? ')' : '}');
break
case ')':
case ']':
case '}':
if (char !== stack.pop()) {
panic(code, unexpectedCharInExpression.replace('%1', char), index);
}
if (char === '}' && stack[stack.length - 1] === $_ES6_BQ) {
char = stack.pop();
}
if (char === '}' && stack[stack.length - 1] === $_ES6_BQ) {
char = stack.pop();
}
index = idx + 1;
break
case '/':
index = skipRegex(code, idx);
index = idx + 1;
break
case '/':
index = skipRegex(code, idx);
}

@@ -424,12 +421,12 @@

/**
* Parses the code string searching the end of the expression.
* It skips braces, quoted strings, regexes, and ES6 template literals.
*
* @function exprExtr
* @param {string} code - Buffer to parse
* @param {number} start - Position of the opening brace
* @param {[string,string]} bp - Brackets pair
* @returns {Object} Expression's end (after the closing brace) or -1
* if it is not an expr.
*/
* Parses the code string searching the end of the expression.
* It skips braces, quoted strings, regexes, and ES6 template literals.
*
* @function exprExtr
* @param {string} code - Buffer to parse
* @param {number} start - Position of the opening brace
* @param {[string,string]} bp - Brackets pair
* @returns {Object} Expression's end (after the closing brace) or -1
* if it is not an expr.
*/
function exprExtr(code, start, bp) {

@@ -446,3 +443,4 @@ const [openingBraces, closingBraces] = bp;

while (match = re.exec(code)) { // eslint-disable-line
while ((match = re.exec(code))) {
// eslint-disable-line
const idx = match.index;

@@ -457,3 +455,3 @@ const str = match[0];

start,
end
end,
}

@@ -567,3 +565,3 @@ }

} else {
pushText(state, start, end, {expressions, unescape});
pushText(state, start, end, { expressions, unescape });
}

@@ -609,8 +607,6 @@

expressions,
end: match.index
end: match.index,
}
}
/**

@@ -990,3 +986,3 @@ * Creates a regex for the given string and the left bracket.

*/
const HTML_ELEMENTS_HAVING_VALUE_ATTRIBUTE_RE = listsToRegex(HTML_ELEMENTS_HAVING_VALUE_ATTRIBUTE_LIST);
listsToRegex(HTML_ELEMENTS_HAVING_VALUE_ATTRIBUTE_LIST);

@@ -1063,6 +1059,9 @@ /**

const expressionsContentRe = memoize(brackets => RegExp(`(${brackets[0]}[^${brackets[1]}]*?${brackets[1]})`, 'g'));
const isSpreadAttribute = name => SPREAD_OPERATOR.test(name);
const expressionsContentRe = memoize((brackets) =>
RegExp(`(${brackets[0]}[^${brackets[1]}]*?${brackets[1]})`, 'g'),
);
const isSpreadAttribute = (name) => SPREAD_OPERATOR.test(name);
const isAttributeExpression = (name, brackets) => name[0] === brackets[0];
const getAttributeEnd = (state, attr) => expr(state, attr, '[>/\\s]', attr.start);
const getAttributeEnd = (state, attr) =>
expr(state, attr, '[>/\\s]', attr.start);

@@ -1084,24 +1083,24 @@ /**

switch (true) {
case !ch:
state.pos = data.length; // reaching the end of the buffer with
// NodeTypes.ATTR will generate error
break
case ch[0] === '>':
// closing char found. If this is a self-closing tag with the name of the
// Root tag, we need decrement the counter as we are changing mode.
state.pos = tag.end = _CH.lastIndex;
if (tag[IS_SELF_CLOSING]) {
state.scryle = null; // allow selfClosing script/style tags
if (root && root.name === tag.name) {
state.count--; // "pop" root tag
case !ch:
state.pos = data.length; // reaching the end of the buffer with
// NodeTypes.ATTR will generate error
break
case ch[0] === '>':
// closing char found. If this is a self-closing tag with the name of the
// Root tag, we need decrement the counter as we are changing mode.
state.pos = tag.end = _CH.lastIndex;
if (tag[IS_SELF_CLOSING]) {
state.scryle = null; // allow selfClosing script/style tags
if (root && root.name === tag.name) {
state.count--; // "pop" root tag
}
}
}
return TEXT
case ch[0] === '/':
state.pos = _CH.lastIndex; // maybe. delegate the validation
tag[IS_SELF_CLOSING] = true; // the next loop
break
default:
delete tag[IS_SELF_CLOSING]; // ensure unmark as selfclosing tag
setAttribute(state, ch.index, tag);
return TEXT
case ch[0] === '/':
state.pos = _CH.lastIndex; // maybe. delegate the validation
tag[IS_SELF_CLOSING] = true; // the next loop
break
default:
delete tag[IS_SELF_CLOSING]; // ensure unmark as selfclosing tag
setAttribute(state, ch.index, tag);
}

@@ -1125,6 +1124,11 @@

const re = ATTR_START; // (\S[^>/=\s]*)(?:\s*=\s*([^>/])?)? g
const start = re.lastIndex = expressionContent.lastIndex = pos; // first non-whitespace
const start = (re.lastIndex = expressionContent.lastIndex = pos); // first non-whitespace
const attrMatches = re.exec(data);
const isExpressionName = isAttributeExpression(attrMatches[1], state.options.brackets);
const match = isExpressionName ? [null, expressionContent.exec(data)[1], null] : attrMatches;
const isExpressionName = isAttributeExpression(
attrMatches[1],
state.options.brackets,
);
const match = isExpressionName
? [null, expressionContent.exec(data)[1], null]
: attrMatches;

@@ -1156,3 +1160,3 @@ if (match) {

// If it not, this is an unquoted value and we need adjust the start.
if (quote !== '"' && quote !== '\'') {
if (quote !== '"' && quote !== "'") {
quote = ''; // first char of value is not a quote

@@ -1168,3 +1172,3 @@ valueStart--; // adjust the starting position

valueStart,
end: quote ? ++end : end
end: quote ? ++end : end,
})

@@ -1176,3 +1180,2 @@ }

/**

@@ -1190,6 +1193,8 @@ * Parse expression names <a {href}>

start: attr.start,
expressions: attr.expressions.map(expr => Object.assign(expr, {
text: expr.text.replace(SPREAD_OPERATOR, '').trim()
})),
end: end
expressions: attr.expressions.map((expr) =>
Object.assign(expr, {
text: expr.text.replace(SPREAD_OPERATOR, '').trim(),
}),
),
end: end,
}

@@ -1211,3 +1216,3 @@ }

expressions: attr.expressions,
end: end
end: end,
}

@@ -1230,3 +1235,3 @@ }

start,
end
end,
};

@@ -1237,8 +1242,8 @@

switch (true) {
case isSpreadAttribute(attr.name):
return parseSpreadAttribute(state, attr)
case isExpressionName === true:
return parseExpressionNameAttribute(state, attr)
default:
return parseNomalAttribute(state, attr, quote)
case isSpreadAttribute(attr.name):
return parseSpreadAttribute(state, attr)
case isExpressionName === true:
return parseExpressionNameAttribute(state, attr)
default:
return parseNomalAttribute(state, attr, quote)
}

@@ -1288,3 +1293,3 @@ }

end + str.length,
data.substring(start, end + str.length)
data.substring(start, end + str.length),
);

@@ -1313,3 +1318,3 @@

end,
text
text,
};

@@ -1374,8 +1379,8 @@ }

switch (true) {
case str[0] === '!':
return comment(state, data, start)
case TAG_2C.test(str):
return parseTag(state, start)
default:
return pushText(state, start, pos) // pushes the '<' as text
case str[0] === '!':
return comment(state, data, start)
case TAG_2C.test(str):
return parseTag(state, start)
default:
return pushText(state, start, pos) // pushes the '<' as text
}

@@ -1416,28 +1421,28 @@ }

switch (true) {
case typeof scryle === 'string': {
const name = scryle;
const re = RE_SCRYLE[name];
const match = execFromPos(re, pos, data);
case typeof scryle === 'string': {
const name = scryle;
const re = RE_SCRYLE[name];
const match = execFromPos(re, pos, data);
if (!match) {
panic(data, unclosedNamedBlock.replace('%1', name), pos - 1);
}
if (!match) {
panic(data, unclosedNamedBlock.replace('%1', name), pos - 1);
}
const start = match.index;
const end = re.lastIndex;
state.scryle = null; // reset the script/style flag now
// write the tag content, if any
if (start > pos) {
parseSpecialTagsContent(state, name, match);
const start = match.index;
const end = re.lastIndex;
state.scryle = null; // reset the script/style flag now
// write the tag content, if any
if (start > pos) {
parseSpecialTagsContent(state, name, match);
}
// now the closing tag, either </script> or </style>
pushTag(state, `/${name}`, start, end);
break
}
// now the closing tag, either </script> or </style>
pushTag(state, `/${name}`, start, end);
break
case data[pos] === '<':
state.pos++;
return TAG
default:
expr(state, null, '<', pos);
}
case data[pos] === '<':
state.pos++;
return TAG
default:
expr(state, null, '<', pos);
}

@@ -1492,9 +1497,8 @@ return TEXT

function escapeReturn(string) {
return string
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
return string.replace(/\r/g, '\\r').replace(/\n/g, '\\n')
}
// check whether a tag has the 'src' attribute set like for example `<script src="">`
const hasSrcAttribute = node => (node.attributes || []).some(attr => attr.name === 'src');
const hasSrcAttribute = (node) =>
(node.attributes || []).some((attr) => attr.name === 'src');

@@ -1526,3 +1530,3 @@ /**

[CSS_OUTPUT_NAME]: store[STYLE_TAG],
[JAVASCRIPT_OUTPUT_NAME]: store[JAVASCRIPT_TAG]
[JAVASCRIPT_OUTPUT_NAME]: store[JAVASCRIPT_TAG],
}

@@ -1532,6 +1536,6 @@ },

/**
* Process the current tag or text.
* @param {Object} node - Raw pseudo-node from the parser
* @returns {undefined} void function
*/
* Process the current tag or text.
* @param {Object} node - Raw pseudo-node from the parser
* @returns {undefined} void function
*/
push(node) {

@@ -1541,21 +1545,21 @@ const store = this.store;

switch (node.type) {
case COMMENT:
this.pushComment(store, node);
break
case TEXT:
this.pushText(store, node);
break
case TAG: {
const name = node.name;
const closingTagChar = '/';
const [firstChar] = name;
case COMMENT:
this.pushComment(store, node);
break
case TEXT:
this.pushText(store, node);
break
case TAG: {
const name = node.name;
const closingTagChar = '/';
const [firstChar] = name;
if (firstChar === closingTagChar && !node.isVoid) {
this.closeTag(store, node, name);
} else if (firstChar !== closingTagChar) {
this.openTag(store, node);
if (firstChar === closingTagChar && !node.isVoid) {
this.closeTag(store, node, name);
} else if (firstChar !== closingTagChar) {
this.openTag(store, node);
}
break
}
break
}
}
},

@@ -1585,3 +1589,4 @@ pushComment(store, node) {

const attrs = node.attributes;
const isCoreTag = (JAVASCRIPT_TAG === name && !hasSrcAttribute(node) || name === STYLE_TAG);
const isCoreTag =
(JAVASCRIPT_TAG === name && !hasSrcAttribute(node)) || name === STYLE_TAG;

@@ -1591,3 +1596,7 @@ if (isCoreTag) {

if (store[name]) {
panic(this.store.data, duplicatedNamedTag.replace('%1', name), node.start);
panic(
this.store.data,
duplicatedNamedTag.replace('%1', name),
node.start,
);
}

@@ -1622,3 +1631,3 @@

attrs(attributes) {
attributes.forEach(attr => {
attributes.forEach((attr) => {
if (attr.value) {

@@ -1654,6 +1663,9 @@ this.split(attr, attr.value, attr.valueStart, true);

expressions.forEach(expr => {
expressions.forEach((expr) => {
const text = source.slice(pos, expr.start - start);
const code = expr.text;
parts.push(this.sanitise(node, text, pack), escapeReturn(escapeSlashes(code).trim()));
parts.push(
this.sanitise(node, text, pack),
escapeReturn(escapeSlashes(code).trim()),
);
pos = expr.end - start;

@@ -1669,3 +1681,3 @@ });

node.parts = parts.filter(p => p); // remove the empty strings
node.parts = parts.filter((p) => p); // remove the empty strings
},

@@ -1687,3 +1699,3 @@ // unescape escaped brackets and split prefixes of expressions

return pack ? cleanSpaces(text) : escapeReturn(text)
}
},
});

@@ -1697,3 +1709,3 @@

end: 0,
nodes: []
nodes: [],
};

@@ -1710,4 +1722,4 @@

script: null,
data
}
data,
},
})

@@ -1727,3 +1739,3 @@ }

return {
parse: (data) => parse(state(data))
parse: (data) => parse(state(data)),
}

@@ -1740,5 +1752,8 @@ }

function createParserState(userOptions, builder, data) {
const options = Object.assign({
brackets: ['{', '}']
}, userOptions);
const options = Object.assign(
{
brackets: ['{', '}'],
},
userOptions,
);

@@ -1754,3 +1769,3 @@ return {

builder: builder(data, options),
data
data,
}

@@ -1777,3 +1792,7 @@ }

if (state.count) {
panic(data, state.count > 0 ? unexpectedEndOfFile : rootTagNotFound, state.pos);
panic(
data,
state.count > 0 ? unexpectedEndOfFile : rootTagNotFound,
state.pos,
);
}

@@ -1783,3 +1802,3 @@

data,
output: state.builder.get()
output: state.builder.get(),
}

@@ -1815,8 +1834,8 @@ }

switch (type) {
case TAG:
return tag(state)
case ATTR:
return attr(state)
default:
return text(state)
case TAG:
return tag(state)
case ATTR:
return attr(state)
default:
return text(state)
}

@@ -1835,4 +1854,2 @@ }

exports.constants = constants;
exports.default = parser;
exports.nodeTypes = nodeTypes;
export { constants, parser as default, nodeTypes };
{
"name": "@riotjs/parser",
"version": "4.3.1",
"version": "5.0.0",
"description": "The parser for Riot tags",
"main": "./index.js",
"module": "./src/index.js",
"jsnext:main": "./src/index.js",
"type": "module",
"main": "./index.cjs",
"module": "./index.js",
"exports": {
".": {
"import": "./index.js",
"require": "./index.cjs"
}
},
"license": "MIT",

@@ -14,11 +20,11 @@ "engines": {

"scripts": {
"test": "nyc mocha ./test/index",
"test": "c8 mocha ./test/index",
"test-debug": "mocha --inspect-brk ./test",
"cov": "nyc report --reporter=text-lcov | coveralls",
"cov-html": "nyc report --reporter=html",
"cov": "c8 report --reporter=lcov",
"cov-html": "c8 report --reporter=html",
"pretest": "npm run build",
"lint": "eslint src test",
"lint": "eslint src test && npx prettier --check ./",
"build": "rollup -c",
"samples": "node ./test/samples.js",
"prepublish": "npm run build"
"prepublishOnly": "npm run build"
},

@@ -50,15 +56,16 @@ "files": [

"devDependencies": {
"chai": "^4.2.0",
"coveralls": "^3.1.0",
"eslint": "^7.6.0",
"eslint-config-riot": "^3.0.0",
"mocha": "^8.1.1",
"nyc": "^15.1.0",
"rollup": "^2.23.0",
"@riotjs/prettier-config": "^1.0.1",
"c8": "^7.13.0",
"chai": "^4.3.7",
"eslint": "^8.39.0",
"eslint-config-riot": "^4.0.0",
"mocha": "^10.2.0",
"prettier": "^2.8.8",
"rollup": "^3.21.0",
"rollup-plugin-node-resolve": "^5.2.0"
},
"dependencies": {
"curri": "^1.0.1",
"curri": "^2.0.3",
"dom-nodes": "^1.1.3"
}
}
# parser
[![Build Status][travis-image]][travis-url]
[![Build Status][ci-image]][ci-url]
[![Code Quality][codeclimate-image]][codeclimate-url]

@@ -39,5 +39,5 @@ [![NPM version][npm-version-image]][npm-url]

* Tags - HTMLElements, including SCRIPT and STYLE elements.
* Comments - Ignored by default.
* Text - Text nodes.
- Tags - HTMLElements, including SCRIPT and STYLE elements.
- Comments - Ignored by default.
- Text - Text nodes.

@@ -52,4 +52,4 @@ Opening tags can contain attributes. Text and attribute values can contain expressions.

{
data, // String of the given html fragment with no changes.
output // Array of objects with information about the parsed tags.
data, // String of the given html fragment with no changes.
output // Array of objects with information about the parsed tags.
}

@@ -62,8 +62,7 @@ ```

### Commands
* Build: `npm run build`
* Test: `npm t`
* Samples: `npm run samples`
- Build: `npm run build`
- Test: `npm t`
- Samples: `npm run samples`

@@ -125,20 +124,15 @@ ## Tag names

* `comments` - Pass `true` to preserve the comments.
* `brackets` - Array of two string with the left/right brackets used to extract expressions.
- `comments` - Pass `true` to preserve the comments.
- `brackets` - Array of two string with the left/right brackets used to extract expressions.
[travis-image]:https://img.shields.io/travis/riot/parser.svg?style=flat-square
[travis-url]:https://travis-ci.org/riot/parser
[license-image]:http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]:LICENSE.txt
[npm-version-image]:http://img.shields.io/npm/v/@riotjs/parser.svg?style=flat-square
[npm-downloads-image]:http://img.shields.io/npm/dm/@riotjs/parser.svg?style=flat-square
[npm-url]:https://npmjs.org/package/@riotjs/parser
[coverage-image]:https://img.shields.io/coveralls/riot/parser/master.svg?style=flat-square
[coverage-url]:https://coveralls.io/r/riot/parser/?branch=master
[codeclimate-image]:https://api.codeclimate.com/v1/badges/5db4f1c96a43e3736cf0/maintainability
[codeclimate-url]:https://codeclimate.com/github/riot/parser
[ci-image]: https://img.shields.io/github/actions/workflow/status/riot/parser/test.yml?style=flat-square
[ci-url]: https://github.com/riot/parser/actions
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE.txt
[npm-version-image]: http://img.shields.io/npm/v/@riotjs/parser.svg?style=flat-square
[npm-downloads-image]: http://img.shields.io/npm/dm/@riotjs/parser.svg?style=flat-square
[npm-url]: https://npmjs.org/package/@riotjs/parser
[coverage-image]: https://img.shields.io/coveralls/riot/parser/master.svg?style=flat-square
[coverage-url]: https://coveralls.io/r/riot/parser/?branch=master
[codeclimate-image]: https://api.codeclimate.com/v1/badges/5db4f1c96a43e3736cf0/maintainability
[codeclimate-url]: https://codeclimate.com/github/riot/parser

@@ -5,8 +5,15 @@ import resolve from 'rollup-plugin-node-resolve'

input: 'src/index.js',
output: {
name: 'parser',
format: 'cjs',
file: './index.js'
},
plugins: [resolve()]
}
output: [
{
name: 'parser',
format: 'cjs',
file: './index.cjs',
},
{
name: 'parser',
format: 'esm',
file: './index.js',
},
],
plugins: [resolve()],
}

@@ -19,2 +19,1 @@ import * as c from './constants'

export default parser

@@ -7,5 +7,6 @@ export const rootTagNotFound = 'Root tag not found.'

export const unclosedNamedBlock = 'Unclosed "%1" block.'
export const duplicatedNamedTag = 'Multiple inline "<%1>" tags are not supported.'
export const duplicatedNamedTag =
'Multiple inline "<%1>" tags are not supported.'
export const expectedAndInsteadSaw = 'Expected "</%1>" and instead saw "<%2>".'
export const unexpectedCharInExpression = 'Unexpected character %1.'
export const unclosedExpression = 'Unclosed expression.'
export const unclosedExpression = 'Unclosed expression.'

@@ -14,2 +14,2 @@ /**

export const DOCTYPE = 10 /* DOCTYPE */
export const DOCUMENT_FRAGMENT = 11 /* DOCUMENT_FRAGMENT */
export const DOCUMENT_FRAGMENT = 11 /* DOCUMENT_FRAGMENT */

@@ -1,3 +0,3 @@

import {ATTR, TAG} from './node-types'
import {rootTagNotFound, unexpectedEndOfFile} from './messages'
import { ATTR, TAG } from './node-types'
import { rootTagNotFound, unexpectedEndOfFile } from './messages'
import attr from './parsers/attribute'

@@ -22,3 +22,3 @@ import curry from 'curri'

return {
parse: (data) => parse(state(data))
parse: (data) => parse(state(data)),
}

@@ -35,5 +35,8 @@ }

function createParserState(userOptions, builder, data) {
const options = Object.assign({
brackets: ['{', '}']
}, userOptions)
const options = Object.assign(
{
brackets: ['{', '}'],
},
userOptions,
)

@@ -49,3 +52,3 @@ return {

builder: builder(data, options),
data
data,
}

@@ -72,3 +75,7 @@ }

if (state.count) {
panic(data, state.count > 0 ? unexpectedEndOfFile : rootTagNotFound, state.pos)
panic(
data,
state.count > 0 ? unexpectedEndOfFile : rootTagNotFound,
state.pos,
)
}

@@ -78,3 +85,3 @@

data,
output: state.builder.get()
output: state.builder.get(),
}

@@ -110,9 +117,9 @@ }

switch (type) {
case TAG:
return tag(state)
case ATTR:
return attr(state)
default:
return text(state)
case TAG:
return tag(state)
case ATTR:
return attr(state)
default:
return text(state)
}
}
}

@@ -1,4 +0,4 @@

import {ATTR, TEXT} from '../node-types'
import {ATTR_START, SPREAD_OPERATOR} from '../regex'
import {IS_BOOLEAN, IS_SELF_CLOSING, IS_SPREAD} from '../constants'
import { ATTR, TEXT } from '../node-types'
import { ATTR_START, SPREAD_OPERATOR } from '../regex'
import { IS_BOOLEAN, IS_SELF_CLOSING, IS_SPREAD } from '../constants'
import addToCollection from '../utils/add-to-collection'

@@ -8,9 +8,12 @@ import execFromPos from '../utils/exec-from-pos'

import getChunk from '../utils/get-chunk'
import {isBoolAttribute} from 'dom-nodes'
import { isBoolAttribute } from 'dom-nodes'
import memoize from '../utils/memoize'
const expressionsContentRe = memoize(brackets => RegExp(`(${brackets[0]}[^${brackets[1]}]*?${brackets[1]})`, 'g'))
const isSpreadAttribute = name => SPREAD_OPERATOR.test(name)
const expressionsContentRe = memoize((brackets) =>
RegExp(`(${brackets[0]}[^${brackets[1]}]*?${brackets[1]})`, 'g'),
)
const isSpreadAttribute = (name) => SPREAD_OPERATOR.test(name)
const isAttributeExpression = (name, brackets) => name[0] === brackets[0]
const getAttributeEnd = (state, attr) => expr(state, attr, '[>/\\s]', attr.start)
const getAttributeEnd = (state, attr) =>
expr(state, attr, '[>/\\s]', attr.start)

@@ -32,24 +35,24 @@ /**

switch (true) {
case !ch:
state.pos = data.length // reaching the end of the buffer with
// NodeTypes.ATTR will generate error
break
case ch[0] === '>':
// closing char found. If this is a self-closing tag with the name of the
// Root tag, we need decrement the counter as we are changing mode.
state.pos = tag.end = _CH.lastIndex
if (tag[IS_SELF_CLOSING]) {
state.scryle = null // allow selfClosing script/style tags
if (root && root.name === tag.name) {
state.count-- // "pop" root tag
case !ch:
state.pos = data.length // reaching the end of the buffer with
// NodeTypes.ATTR will generate error
break
case ch[0] === '>':
// closing char found. If this is a self-closing tag with the name of the
// Root tag, we need decrement the counter as we are changing mode.
state.pos = tag.end = _CH.lastIndex
if (tag[IS_SELF_CLOSING]) {
state.scryle = null // allow selfClosing script/style tags
if (root && root.name === tag.name) {
state.count-- // "pop" root tag
}
}
}
return TEXT
case ch[0] === '/':
state.pos = _CH.lastIndex // maybe. delegate the validation
tag[IS_SELF_CLOSING] = true // the next loop
break
default:
delete tag[IS_SELF_CLOSING] // ensure unmark as selfclosing tag
setAttribute(state, ch.index, tag)
return TEXT
case ch[0] === '/':
state.pos = _CH.lastIndex // maybe. delegate the validation
tag[IS_SELF_CLOSING] = true // the next loop
break
default:
delete tag[IS_SELF_CLOSING] // ensure unmark as selfclosing tag
setAttribute(state, ch.index, tag)
}

@@ -73,6 +76,11 @@

const re = ATTR_START // (\S[^>/=\s]*)(?:\s*=\s*([^>/])?)? g
const start = re.lastIndex = expressionContent.lastIndex = pos // first non-whitespace
const start = (re.lastIndex = expressionContent.lastIndex = pos) // first non-whitespace
const attrMatches = re.exec(data)
const isExpressionName = isAttributeExpression(attrMatches[1], state.options.brackets)
const match = isExpressionName ? [null, expressionContent.exec(data)[1], null] : attrMatches
const isExpressionName = isAttributeExpression(
attrMatches[1],
state.options.brackets,
)
const match = isExpressionName
? [null, expressionContent.exec(data)[1], null]
: attrMatches

@@ -104,3 +112,3 @@ if (match) {

// If it not, this is an unquoted value and we need adjust the start.
if (quote !== '"' && quote !== '\'') {
if (quote !== '"' && quote !== "'") {
quote = '' // first char of value is not a quote

@@ -116,3 +124,3 @@ valueStart-- // adjust the starting position

valueStart,
end: quote ? ++end : end
end: quote ? ++end : end,
})

@@ -124,3 +132,2 @@ }

/**

@@ -138,6 +145,8 @@ * Parse expression names <a {href}>

start: attr.start,
expressions: attr.expressions.map(expr => Object.assign(expr, {
text: expr.text.replace(SPREAD_OPERATOR, '').trim()
})),
end: end
expressions: attr.expressions.map((expr) =>
Object.assign(expr, {
text: expr.text.replace(SPREAD_OPERATOR, '').trim(),
}),
),
end: end,
}

@@ -159,3 +168,3 @@ }

expressions: attr.expressions,
end: end
end: end,
}

@@ -178,3 +187,3 @@ }

start,
end
end,
}

@@ -185,9 +194,9 @@

switch (true) {
case isSpreadAttribute(attr.name):
return parseSpreadAttribute(state, attr)
case isExpressionName === true:
return parseExpressionNameAttribute(state, attr)
default:
return parseNomalAttribute(state, attr, quote)
case isSpreadAttribute(attr.name):
return parseSpreadAttribute(state, attr)
case isExpressionName === true:
return parseExpressionNameAttribute(state, attr)
default:
return parseNomalAttribute(state, attr, quote)
}
}

@@ -1,5 +0,5 @@

import {COMMENT, TEXT} from '../node-types'
import { COMMENT, TEXT } from '../node-types'
import flush from '../utils/flush-parser-state'
import panic from '../utils/panic'
import {unclosedComment} from '../messages'
import { unclosedComment } from '../messages'

@@ -30,3 +30,3 @@ /**

end + str.length,
data.substring(start, end + str.length)
data.substring(start, end + str.length),
)

@@ -55,5 +55,5 @@

end,
text
text,
}
}
}

@@ -5,3 +5,3 @@ import escapeStr from '../utils/escape-str'

import pushText from '../utils/push-text'
import {unexpectedEndOfFile} from '../messages'
import { unexpectedEndOfFile } from '../messages'
/**

@@ -34,3 +34,3 @@ * Find the end of the attribute value or text node

} else {
pushText(state, start, end, {expressions, unescape})
pushText(state, start, end, { expressions, unescape })
}

@@ -76,8 +76,6 @@

expressions,
end: match.index
end: match.index,
}
}
/**

@@ -103,2 +101,2 @@ * Creates a regex for the given string and the left bracket.

return state.regexCache[str]
}
}

@@ -1,3 +0,3 @@

import {ATTR, TEXT} from '../node-types'
import {RE_SCRYLE, TAG_2C, TAG_NAME} from '../regex'
import { ATTR, TEXT } from '../node-types'
import { RE_SCRYLE, TAG_2C, TAG_NAME } from '../regex'
import comment from './comment'

@@ -22,8 +22,8 @@ import execFromPos from '../utils/exec-from-pos'

switch (true) {
case str[0] === '!':
return comment(state, data, start)
case TAG_2C.test(str):
return parseTag(state, start)
default:
return pushText(state, start, pos) // pushes the '<' as text
case str[0] === '!':
return comment(state, data, start)
case TAG_2C.test(str):
return parseTag(state, start)
default:
return pushText(state, start, pos) // pushes the '<' as text
}

@@ -50,2 +50,2 @@ }

return TEXT
}
}

@@ -1,4 +0,4 @@

import {TAG, TEXT} from '../node-types'
import {RE_SCRYLE} from '../regex'
import {TEXTAREA_TAG} from '../constants'
import { TAG, TEXT } from '../node-types'
import { RE_SCRYLE } from '../regex'
import { TEXTAREA_TAG } from '../constants'
import execFromPos from '../utils/exec-from-pos'

@@ -9,3 +9,3 @@ import expr from './expression'

import pushText from '../utils/push-text'
import {unclosedNamedBlock} from '../messages'
import { unclosedNamedBlock } from '../messages'

@@ -24,28 +24,28 @@ /**

switch (true) {
case typeof scryle === 'string': {
const name = scryle
const re = RE_SCRYLE[name]
const match = execFromPos(re, pos, data)
case typeof scryle === 'string': {
const name = scryle
const re = RE_SCRYLE[name]
const match = execFromPos(re, pos, data)
if (!match) {
panic(data, unclosedNamedBlock.replace('%1', name), pos - 1)
}
if (!match) {
panic(data, unclosedNamedBlock.replace('%1', name), pos - 1)
}
const start = match.index
const end = re.lastIndex
state.scryle = null // reset the script/style flag now
// write the tag content, if any
if (start > pos) {
parseSpecialTagsContent(state, name, match)
const start = match.index
const end = re.lastIndex
state.scryle = null // reset the script/style flag now
// write the tag content, if any
if (start > pos) {
parseSpecialTagsContent(state, name, match)
}
// now the closing tag, either </script> or </style>
pushTag(state, `/${name}`, start, end)
break
}
// now the closing tag, either </script> or </style>
pushTag(state, `/${name}`, start, end)
break
case data[pos] === '<':
state.pos++
return TAG
default:
expr(state, null, '<', pos)
}
case data[pos] === '<':
state.pos++
return TAG
default:
expr(state, null, '<', pos)
}

@@ -71,2 +71,2 @@ return TEXT

}
}
}

@@ -37,3 +37,3 @@ /**

style: /<\/style\s*>/gi,
textarea: /<\/textarea\s*>/gi
textarea: /<\/textarea\s*>/gi,
}

@@ -40,0 +40,0 @@

@@ -21,3 +21,3 @@ /*---------------------------------------------------------------------

*/
import {COMMENT, TAG, TEXT} from './node-types'
import { COMMENT, TAG, TEXT } from './node-types'
import {

@@ -31,6 +31,6 @@ CSS_OUTPUT_NAME,

STYLE_TAG,
TEMPLATE_OUTPUT_NAME
TEMPLATE_OUTPUT_NAME,
} from './constants'
import {RAW_TAGS} from './regex'
import {duplicatedNamedTag} from './messages'
import { RAW_TAGS } from './regex'
import { duplicatedNamedTag } from './messages'
import panic from './utils/panic'

@@ -44,9 +44,8 @@

function escapeReturn(string) {
return string
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
return string.replace(/\r/g, '\\r').replace(/\n/g, '\\n')
}
// check whether a tag has the 'src' attribute set like for example `<script src="">`
const hasSrcAttribute = node => (node.attributes || []).some(attr => attr.name === 'src')
const hasSrcAttribute = (node) =>
(node.attributes || []).some((attr) => attr.name === 'src')

@@ -78,3 +77,3 @@ /**

[CSS_OUTPUT_NAME]: store[STYLE_TAG],
[JAVASCRIPT_OUTPUT_NAME]: store[JAVASCRIPT_TAG]
[JAVASCRIPT_OUTPUT_NAME]: store[JAVASCRIPT_TAG],
}

@@ -84,6 +83,6 @@ },

/**
* Process the current tag or text.
* @param {Object} node - Raw pseudo-node from the parser
* @returns {undefined} void function
*/
* Process the current tag or text.
* @param {Object} node - Raw pseudo-node from the parser
* @returns {undefined} void function
*/
push(node) {

@@ -93,21 +92,21 @@ const store = this.store

switch (node.type) {
case COMMENT:
this.pushComment(store, node)
break
case TEXT:
this.pushText(store, node)
break
case TAG: {
const name = node.name
const closingTagChar = '/'
const [firstChar] = name
case COMMENT:
this.pushComment(store, node)
break
case TEXT:
this.pushText(store, node)
break
case TAG: {
const name = node.name
const closingTagChar = '/'
const [firstChar] = name
if (firstChar === closingTagChar && !node.isVoid) {
this.closeTag(store, node, name)
} else if (firstChar !== closingTagChar) {
this.openTag(store, node)
if (firstChar === closingTagChar && !node.isVoid) {
this.closeTag(store, node, name)
} else if (firstChar !== closingTagChar) {
this.openTag(store, node)
}
break
}
break
}
}
},

@@ -137,3 +136,4 @@ pushComment(store, node) {

const attrs = node.attributes
const isCoreTag = (JAVASCRIPT_TAG === name && !hasSrcAttribute(node) || name === STYLE_TAG)
const isCoreTag =
(JAVASCRIPT_TAG === name && !hasSrcAttribute(node)) || name === STYLE_TAG

@@ -143,3 +143,7 @@ if (isCoreTag) {

if (store[name]) {
panic(this.store.data, duplicatedNamedTag.replace('%1', name), node.start)
panic(
this.store.data,
duplicatedNamedTag.replace('%1', name),
node.start,
)
}

@@ -174,3 +178,3 @@

attrs(attributes) {
attributes.forEach(attr => {
attributes.forEach((attr) => {
if (attr.value) {

@@ -206,6 +210,9 @@ this.split(attr, attr.value, attr.valueStart, true)

expressions.forEach(expr => {
expressions.forEach((expr) => {
const text = source.slice(pos, expr.start - start)
const code = expr.text
parts.push(this.sanitise(node, text, pack), escapeReturn(escapeSlashes(code).trim()))
parts.push(
this.sanitise(node, text, pack),
escapeReturn(escapeSlashes(code).trim()),
)
pos = expr.end - start

@@ -221,3 +228,3 @@ })

node.parts = parts.filter(p => p) // remove the empty strings
node.parts = parts.filter((p) => p) // remove the empty strings
},

@@ -239,3 +246,3 @@ // unescape escaped brackets and split prefixes of expressions

return pack ? cleanSpaces(text) : escapeReturn(text)
}
},
})

@@ -249,3 +256,3 @@

end: 0,
nodes: []
nodes: [],
}

@@ -262,5 +269,5 @@

script: null,
data
}
data,
},
})
}

@@ -11,2 +11,2 @@ /**

return collection
}
}

@@ -11,2 +11,2 @@ /**

return re.exec(string)
}
}

@@ -7,4 +7,4 @@ /*

*/
import skipES6TL, {$_ES6_BQ} from './skip-es6-tl'
import {unclosedExpression, unexpectedCharInExpression} from '../messages'
import skipES6TL, { $_ES6_BQ } from './skip-es6-tl'
import { unclosedExpression, unexpectedCharInExpression } from '../messages'
import escapeStr from './escape-str'

@@ -69,22 +69,22 @@ import panic from './panic'

switch (char) {
case '[':
case '(':
case '{':
stack.push(char === '[' ? ']' : char === '(' ? ')' : '}')
break
case ')':
case ']':
case '}':
if (char !== stack.pop()) {
panic(code, unexpectedCharInExpression.replace('%1', char), index)
}
case '[':
case '(':
case '{':
stack.push(char === '[' ? ']' : char === '(' ? ')' : '}')
break
case ')':
case ']':
case '}':
if (char !== stack.pop()) {
panic(code, unexpectedCharInExpression.replace('%1', char), index)
}
if (char === '}' && stack[stack.length - 1] === $_ES6_BQ) {
char = stack.pop()
}
if (char === '}' && stack[stack.length - 1] === $_ES6_BQ) {
char = stack.pop()
}
index = idx + 1
break
case '/':
index = skipRegex(code, idx)
index = idx + 1
break
case '/':
index = skipRegex(code, idx)
}

@@ -96,12 +96,12 @@

/**
* Parses the code string searching the end of the expression.
* It skips braces, quoted strings, regexes, and ES6 template literals.
*
* @function exprExtr
* @param {string} code - Buffer to parse
* @param {number} start - Position of the opening brace
* @param {[string,string]} bp - Brackets pair
* @returns {Object} Expression's end (after the closing brace) or -1
* if it is not an expr.
*/
* Parses the code string searching the end of the expression.
* It skips braces, quoted strings, regexes, and ES6 template literals.
*
* @function exprExtr
* @param {string} code - Buffer to parse
* @param {number} start - Position of the opening brace
* @param {[string,string]} bp - Brackets pair
* @returns {Object} Expression's end (after the closing brace) or -1
* if it is not an expr.
*/
export default function exprExtr(code, start, bp) {

@@ -118,3 +118,4 @@ const [openingBraces, closingBraces] = bp

while (match = re.exec(code)) { // eslint-disable-line
while ((match = re.exec(code))) {
// eslint-disable-line
const idx = match.index

@@ -129,3 +130,3 @@ const str = match[0]

start,
end
end,
}

@@ -144,2 +145,2 @@ }

}
}
}

@@ -11,2 +11,2 @@ /**

return source.slice(start, end)
}
}

@@ -18,2 +18,2 @@ /**

}
}
}

@@ -15,2 +15,2 @@ import formatError from './format-error'

throw new Error(message)
}
}

@@ -1,7 +0,4 @@

import {
IS_CUSTOM,
IS_VOID
} from '../constants'
import {isCustom, isVoid} from 'dom-nodes'
import {TAG} from '../node-types'
import { IS_CUSTOM, IS_VOID } from '../constants'
import { isCustom, isVoid } from 'dom-nodes'
import { TAG } from '../node-types'
import flush from './flush-parser-state'

@@ -48,2 +45,2 @@

state.last = last
}
}

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

import {TEXT} from '../node-types'
import { TEXT } from '../node-types'
import flush from './flush-parser-state'

@@ -42,2 +42,2 @@ import getChunk from './get-chunk'

return TEXT
}
}
import formatError from './format-error'
import {unclosedTemplateLiteral} from '../messages'
import { unclosedTemplateLiteral } from '../messages'
export const $_ES6_BQ = '`'

@@ -20,3 +20,3 @@

let c
while (re.lastIndex = pos, re.exec(code)) {
while (((re.lastIndex = pos), re.exec(code))) {
pos = re.lastIndex

@@ -23,0 +23,0 @@ c = code[pos - 1]

@@ -19,3 +19,3 @@ // forked from https://github.com/aMarCruz/skip-regex

'void',
'yield'
'yield',
]

@@ -28,3 +28,4 @@

// The buffer to search must not include line-endings.
const RE_LIT_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/
const RE_LIT_REGEX =
/^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/

@@ -51,4 +52,2 @@ // Valid characters for JavaScript variable names and literal numbers.

/**

@@ -67,5 +66,5 @@ * Check if the character in the `start` position within `code` can be a regex

*/
/* istanbul ignore next */
/* c8 ignore next */
export default function skipRegex(code, start) {
let pos = RE_DOT_CHAR.lastIndex = start++
let pos = (RE_DOT_CHAR.lastIndex = start++)

@@ -77,3 +76,3 @@ // `exec()` will extract from the slash to the end of the line

if (match) {
const next = pos + match[0].length // result comes from `re.match`
const next = pos + match[0].length // result comes from `re.match`

@@ -94,15 +93,16 @@ pos = _prev(code, pos)

}
} else {
if (c === '+' || c === '-') {
// tricky case
if (code[--pos] !== c || // if have a single operator or
(pos = _prev(code, pos)) < 0 || // ...have `++` and no previous token
beforeReSign.includes(c = code[pos])) {
return next // ...this is a regex
if (
code[--pos] !== c || // if have a single operator or
(pos = _prev(code, pos)) < 0 || // ...have `++` and no previous token
beforeReSign.includes((c = code[pos]))
) {
return next // ...this is a regex
}
}
if (wordsEndChar.includes(c)) { // looks like a keyword?
if (wordsEndChar.includes(c)) {
// looks like a keyword?
const end = pos + 1

@@ -109,0 +109,0 @@

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