riot-compiler
Advanced tools
Comparing version 2.3.22 to 2.3.23
# Compiler Changes | ||
### v2.3.23 | ||
- The parsers are moved to its own directory in the node version. The load is on first use. | ||
- Fix [riot#1325](https://github.com/riot/riot/issues/1325) : Gulp + Browserify + Babelify + type="es6" error. | ||
- Fix [riot#1342](https://github.com/riot/riot/issues/1342), [riot#1636](https://github.com/riot/riot/issues/1636) and request from [dwyl/learn-riot#8](https://github.com/dwyl/learn-riot/issues/8) : Server-Side Rendered Page Fails W3C Check. The new `data-is` attribute is used for scoped styles in addition to `riot-tag` (the later will be removed in compiler v3.x) | ||
- The keyword `defer` in `<script src=file>` avoids that the compiler loads the file, preserving the tag - Requested by [riot#1492](https://github.com/riot/riot/issues/1492) : Stop script tags from being evaluated with serverside `riot.render`. It is removed in client-side compilation because browsers will not load scripts through innerHTML. | ||
- It has changed the character used to hide expressions during the compilation, maybe this fix [riot#1588](https://github.com/riot/riot/issues/1588) : Syntax Error: Invalid character `\0129` (riot+compiler.min). | ||
- The option `debug` inserts newlines between the `riot.tag2` parameters and the call is prefixed with the source filename - Requested by [riot#1646](https://github.com/riot/riot/issues/1646) : Split portions of generated html with newline instead of space | ||
- Removed the unused parameter with the compiled-time brackets from the call to `riot.tag2`. | ||
- Removed support for raw expressions. It is unlikely this feature will be implemented in v2.3.x | ||
- Updated the regex that is used to match tag names, more closer to the HTML5 specs. | ||
- Update devDependencies. | ||
### v2.3.22 | ||
@@ -4,0 +16,0 @@ - Fix [riot#1511](https://github.com/riot/riot/issues/1511) : Escape Quotes - They may be some issues to fix. |
/** | ||
* Compiler for riot custom tags | ||
* @version v2.3.22 | ||
* @version v2.3.23 | ||
*/ | ||
@@ -109,4 +109,6 @@ | ||
var HTML_TAGS = /<([-\w]+)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g | ||
var BOOL_ATTRS = RegExp( | ||
@@ -129,2 +131,6 @@ '^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|' + | ||
var | ||
RE_HASEXPR = /\x01#\d/, | ||
RE_REPEXPR = /\x01#(\d+)/g, | ||
CH_IDEXPR = '\x01#', | ||
CH_DQCODE = '\u2057', | ||
DQ = '"', | ||
@@ -143,3 +149,3 @@ SQ = "'" | ||
re.lastIndex = 0 | ||
while (mm = re.exec(src)) { | ||
while ((mm = re.exec(src))) { | ||
if (mm[0][0] === '<') { | ||
@@ -163,3 +169,3 @@ src = RegExp.leftContext + RegExp.rightContext | ||
while (match = HTML_ATTRS.exec(str)) { | ||
while ((match = HTML_ATTRS.exec(str))) { | ||
var | ||
@@ -180,3 +186,3 @@ k = match[1].toLowerCase(), | ||
} else { | ||
if (/\u0001\d/.test(v)) { | ||
if (RE_HASEXPR.test(v)) { | ||
@@ -207,3 +213,3 @@ if (k === 'value') vexp = 1 | ||
list = brackets.split(html, 0, _bp), | ||
expr, israw | ||
expr | ||
@@ -215,8 +221,6 @@ for (var i = 1; i < list.length; i += 2) { | ||
} else if (jsfn) { | ||
israw = expr[0] === '=' | ||
expr = jsfn(israw ? expr.slice(1) : expr, opts).trim() | ||
expr = jsfn(expr, opts).trim() | ||
if (expr.slice(-1) === ';') expr = expr.slice(0, -1) | ||
if (israw) expr = '=' + expr | ||
} | ||
list[i] = '\u0001' + (pcex.push(expr) - 1) + _bp[1] | ||
list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1] | ||
} | ||
@@ -230,16 +234,6 @@ html = list.join('') | ||
if (pcex.length) { | ||
html = html | ||
.replace(/\u0001(\d+)/g, function (_, d) { | ||
var expr = pcex[d] | ||
html = html.replace(RE_REPEXPR, function (_, d) { | ||
if (expr[0] === '=') { | ||
expr = expr.replace(brackets.R_STRINGS, function (qs) { | ||
return qs | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
}) | ||
} | ||
return pcex._bp[0] + expr.trim().replace(/[\r\n]+/g, ' ').replace(/"/g, '\u2057') | ||
}) | ||
return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) | ||
}) | ||
} | ||
@@ -278,3 +272,3 @@ return html | ||
if (opts.compact) html = html.replace(/>[ \t]+<([-\w\/])/g, '><$1') | ||
if (opts.compact) html = html.replace(HTML_PACK, '><$1') | ||
@@ -316,3 +310,3 @@ return restoreExpr(html, pcex).replace(TRIM_TRAIL, '') | ||
while (match = js.match(JS_ES6SIGN)) { | ||
while ((match = js.match(JS_ES6SIGN))) { | ||
@@ -336,3 +330,3 @@ parts.push(RE.leftContext) | ||
r.lastIndex = 0 | ||
while (m = r.exec(s)) { | ||
while ((m = r.exec(s))) { | ||
if (m[0][0] === '/' && !m[1] && !m[2]) { | ||
@@ -402,8 +396,10 @@ s = RE.leftContext + ' ' + RE.rightContext | ||
if (s.indexOf(scope) < 0) { | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s + | ||
',[data-is="' + tag + '"] ' + s | ||
} else { | ||
s = s.replace(scope, tag) + ',' + | ||
s.replace(scope, '[riot-tag="' + tag + '"]') | ||
s.replace(scope, '[riot-tag="' + tag + '"]') + ',' + | ||
s.replace(scope, '[data-is="' + tag + '"]') | ||
} | ||
return sel.slice(-1) === ' ' ? s + ' ' : s | ||
return s | ||
}) | ||
@@ -452,3 +448,3 @@ | ||
var END_TAGS = /\/>\n|^<(?:\/?[-\w]+\s*|[-\w]+\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
@@ -461,6 +457,6 @@ function _q (s, r) { | ||
function mktag (name, html, css, attribs, js, pcex) { | ||
function mktag (name, html, css, attr, js, opts) { | ||
var | ||
c = ', ', | ||
s = '}' + (pcex.length ? ', ' + _q(pcex._bp[8]) : '') + ');' | ||
c = opts.debug ? ',\n ' : ', ', | ||
s = '});' | ||
@@ -472,3 +468,3 @@ if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
c + _q(css) + | ||
c + _q(attribs) + ', function(opts) {\n' + js + s | ||
c + _q(attr) + ', function(opts) {\n' + js + s | ||
} | ||
@@ -527,4 +523,7 @@ | ||
function getCode (code, opts, attribs, base) { | ||
var type = getType(attribs) | ||
var | ||
type = getType(attribs), | ||
src = getAttrib(attribs, 'src') | ||
if (src) return false | ||
return _compileJS(code, opts, type, getParserOptions(attribs), base) | ||
@@ -554,3 +553,3 @@ } | ||
CUST_TAG = RegExp(/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
.source.replace('@', S_STRINGS), 'gim'), | ||
@@ -650,3 +649,3 @@ | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
return mktag(tagName, html, styles, attribs, jscode, opts) | ||
}) | ||
@@ -659,3 +658,3 @@ | ||
var version = 'v2.3.22' | ||
var version = 'v2.3.23' | ||
@@ -662,0 +661,0 @@ export default { |
@@ -95,3 +95,3 @@ | ||
* Compiler for riot custom tags | ||
* @version v2.3.22 | ||
* @version v2.3.23 | ||
*/ | ||
@@ -108,4 +108,6 @@ var compile = (function () { | ||
var HTML_TAGS = /<([-\w]+)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g | ||
var BOOL_ATTRS = RegExp( | ||
@@ -128,2 +130,6 @@ '^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|' + | ||
var | ||
RE_HASEXPR = /\x01#\d/, | ||
RE_REPEXPR = /\x01#(\d+)/g, | ||
CH_IDEXPR = '\x01#', | ||
CH_DQCODE = '\u2057', | ||
DQ = '"', | ||
@@ -142,3 +148,3 @@ SQ = "'" | ||
re.lastIndex = 0 | ||
while (mm = re.exec(src)) { | ||
while ((mm = re.exec(src))) { | ||
if (mm[0][0] === '<') { | ||
@@ -162,3 +168,3 @@ src = RegExp.leftContext + RegExp.rightContext | ||
while (match = HTML_ATTRS.exec(str)) { | ||
while ((match = HTML_ATTRS.exec(str))) { | ||
var | ||
@@ -179,3 +185,3 @@ k = match[1].toLowerCase(), | ||
} else { | ||
if (/\u0001\d/.test(v)) { | ||
if (RE_HASEXPR.test(v)) { | ||
@@ -206,3 +212,3 @@ if (k === 'value') vexp = 1 | ||
list = brackets.split(html, 0, _bp), | ||
expr, israw | ||
expr | ||
@@ -214,8 +220,6 @@ for (var i = 1; i < list.length; i += 2) { | ||
} else if (jsfn) { | ||
israw = expr[0] === '=' | ||
expr = jsfn(israw ? expr.slice(1) : expr, opts).trim() | ||
expr = jsfn(expr, opts).trim() | ||
if (expr.slice(-1) === ';') expr = expr.slice(0, -1) | ||
if (israw) expr = '=' + expr | ||
} | ||
list[i] = '\u0001' + (pcex.push(expr) - 1) + _bp[1] | ||
list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1] | ||
} | ||
@@ -229,16 +233,6 @@ html = list.join('') | ||
if (pcex.length) { | ||
html = html | ||
.replace(/\u0001(\d+)/g, function (_, d) { | ||
var expr = pcex[d] | ||
html = html.replace(RE_REPEXPR, function (_, d) { | ||
if (expr[0] === '=') { | ||
expr = expr.replace(brackets.R_STRINGS, function (qs) { | ||
return qs | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
}) | ||
} | ||
return pcex._bp[0] + expr.trim().replace(/[\r\n]+/g, ' ').replace(/"/g, '\u2057') | ||
}) | ||
return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) | ||
}) | ||
} | ||
@@ -277,3 +271,3 @@ return html | ||
if (opts.compact) html = html.replace(/>[ \t]+<([-\w\/])/g, '><$1') | ||
if (opts.compact) html = html.replace(HTML_PACK, '><$1') | ||
@@ -315,3 +309,3 @@ return restoreExpr(html, pcex).replace(TRIM_TRAIL, '') | ||
while (match = js.match(JS_ES6SIGN)) { | ||
while ((match = js.match(JS_ES6SIGN))) { | ||
@@ -335,3 +329,3 @@ parts.push(RE.leftContext) | ||
r.lastIndex = 0 | ||
while (m = r.exec(s)) { | ||
while ((m = r.exec(s))) { | ||
if (m[0][0] === '/' && !m[1] && !m[2]) { | ||
@@ -401,8 +395,10 @@ s = RE.leftContext + ' ' + RE.rightContext | ||
if (s.indexOf(scope) < 0) { | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s + | ||
',[data-is="' + tag + '"] ' + s | ||
} else { | ||
s = s.replace(scope, tag) + ',' + | ||
s.replace(scope, '[riot-tag="' + tag + '"]') | ||
s.replace(scope, '[riot-tag="' + tag + '"]') + ',' + | ||
s.replace(scope, '[data-is="' + tag + '"]') | ||
} | ||
return sel.slice(-1) === ' ' ? s + ' ' : s | ||
return s | ||
}) | ||
@@ -451,3 +447,3 @@ | ||
var END_TAGS = /\/>\n|^<(?:\/?[-\w]+\s*|[-\w]+\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
@@ -460,6 +456,6 @@ function _q (s, r) { | ||
function mktag (name, html, css, attribs, js, pcex) { | ||
function mktag (name, html, css, attr, js, opts) { | ||
var | ||
c = ', ', | ||
s = '}' + (pcex.length ? ', ' + _q(pcex._bp[8]) : '') + ');' | ||
c = opts.debug ? ',\n ' : ', ', | ||
s = '});' | ||
@@ -471,3 +467,3 @@ if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
c + _q(css) + | ||
c + _q(attribs) + ', function(opts) {\n' + js + s | ||
c + _q(attr) + ', function(opts) {\n' + js + s | ||
} | ||
@@ -526,4 +522,7 @@ | ||
function getCode (code, opts, attribs, base) { | ||
var type = getType(attribs) | ||
var | ||
type = getType(attribs), | ||
src = getAttrib(attribs, 'src') | ||
if (src) return false | ||
return _compileJS(code, opts, type, getParserOptions(attribs), base) | ||
@@ -553,3 +552,3 @@ } | ||
CUST_TAG = RegExp(/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
.source.replace('@', S_STRINGS), 'gim'), | ||
@@ -649,3 +648,3 @@ | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
return mktag(tagName, html, styles, attribs, jscode, opts) | ||
}) | ||
@@ -663,3 +662,3 @@ | ||
js: compileJS, | ||
version: 'v2.3.22' | ||
version: 'v2.3.23' | ||
} | ||
@@ -666,0 +665,0 @@ return compile |
@@ -65,3 +65,3 @@ # Compiler Guide (complement, WIP) | ||
This may seem counterintuitive, but complies with the riot specification for [untagged JavaScript blocks](the-untagged-javascript-block). | ||
This may seem counterintuitive, but complies with the riot specification for [untagged JavaScript blocks](#the-untagged-javascript-block). | ||
@@ -265,8 +265,22 @@ | ||
The `src` attribute of the `script` tags inside a riot tag, allows load source files from the file system. | ||
The `src` attribute of the `script` tags inside a riot tag allows load source files from the file system. | ||
The filename in `src` can be absolute or relative. If you pass a third parameter to the `compile` function with the full name of the file being compiled, relative paths will be resolved from this name, if not, these will be relative to the current working directory (as returned by `proccess.cwd()`). | ||
JavaScript type defaults to the `type` specified in the options passed to the compiler. If you don't want the code to be parsed, use `type="none"`. | ||
Without a `type=` directive, the JavaScript parser defaults to the `type` specified in the options passed to the compiler. If you don't want the code to be parsed, use `type="none"`. | ||
If you just want to get the `script` tag rendered, keeping the `type` | ||
attribute and the tag contents untouched, you should then use the `defer` | ||
attribute. | ||
The `defer` attribute is used to avoid the processing of the `script` tag | ||
during the Riot compile time, which would threat them as 'code to be | ||
evaluated'. This will be deferred to happen just on the final renderer context | ||
(e.g. Web Browsers). | ||
This can be useful for example on Server Side Rendering (SSR) of plain | ||
old HTML files. Riot Tags in this context would include some logic inside | ||
`script` tags designed to be run on just on the Client (e.g. To provide | ||
animations). The original `defer` attribute is also removed during the | ||
rendering of the final emitted `script` tag. | ||
The encoding is specified by the `charset` attribute. It defaults to `utf8`. | ||
@@ -278,4 +292,11 @@ | ||
fs = require('fs') | ||
var source = fs.readFileSync(full_filename, 'utf8') | ||
var result = compiler.compile(source, options, full_filename) | ||
var tagfile = 'src/mytag.tag', | ||
outfile = 'js/mytag.js', | ||
options = {} | ||
fs.readFile(tagfile, function (err, source) { | ||
if (err) throw err | ||
var js = compiler.compile(source, options, tagfile) | ||
fs.writeFile(outfile, js) | ||
}) | ||
``` | ||
@@ -309,2 +330,8 @@ | ||
To avoid the compiler load the code from the file, include the keyword `defer` in the tag: | ||
```html | ||
<script src="js/data.js" defer></script> | ||
``` | ||
with this, the `<script>` is retained in the html, with the keyword `defer` removed. | ||
**Note:** You cannot nest `<script>` elements. | ||
@@ -311,0 +338,0 @@ |
@@ -131,3 +131,3 @@ /** | ||
while (match = re.exec(str)) { | ||
while ((match = re.exec(str))) { | ||
@@ -206,3 +206,3 @@ pos = match.index | ||
ix = 1 | ||
while (mm = rr.exec(s)) { | ||
while ((mm = rr.exec(s))) { | ||
if (mm[1] && | ||
@@ -209,0 +209,0 @@ !(mm[1] === ch ? ++ix : --ix)) break |
/** | ||
* The riot-compiler WIP | ||
* The riot-compiler v2.3.23 | ||
* | ||
* @module compiler | ||
* @version WIP | ||
* @version v2.3.23 | ||
* @license MIT | ||
@@ -57,5 +57,12 @@ * @copyright 2015 Muut Inc. + contributors | ||
*/ | ||
var HTML_TAGS = /<([-\w]+)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
/** | ||
* Matches spaces and tabs between HTML tags | ||
* Used by the `compact` option. | ||
* @const RegExp | ||
*/ | ||
var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g | ||
/** | ||
* Matches boolean HTML attributes, prefixed with `"__"` in the riot tag definition. | ||
@@ -114,2 +121,6 @@ * Used by {@link module:compiler~parseAttribs|parseAttribs} with lowercase names. | ||
var | ||
RE_HASEXPR = /\x01#\d/, | ||
RE_REPEXPR = /\x01#(\d+)/g, | ||
CH_IDEXPR = '\x01#', | ||
CH_DQCODE = '\u2057', | ||
DQ = '"', | ||
@@ -137,3 +148,3 @@ SQ = "'" | ||
re.lastIndex = 0 | ||
while (mm = re.exec(src)) { | ||
while ((mm = re.exec(src))) { | ||
if (mm[0][0] === '<') { | ||
@@ -166,3 +177,3 @@ src = RegExp.leftContext + RegExp.rightContext | ||
while (match = HTML_ATTRS.exec(str)) { | ||
while ((match = HTML_ATTRS.exec(str))) { | ||
var | ||
@@ -183,3 +194,3 @@ k = match[1].toLowerCase(), | ||
} else { | ||
if (/\u0001\d/.test(v)) { | ||
if (RE_HASEXPR.test(v)) { | ||
@@ -221,3 +232,3 @@ if (k === 'value') vexp = 1 | ||
list = brackets.split(html, 0, _bp), | ||
expr, israw | ||
expr | ||
@@ -229,8 +240,6 @@ for (var i = 1; i < list.length; i += 2) { | ||
} else if (jsfn) { | ||
israw = expr[0] === '=' | ||
expr = jsfn(israw ? expr.slice(1) : expr, opts).trim() | ||
expr = jsfn(expr, opts).trim() | ||
if (expr.slice(-1) === ';') expr = expr.slice(0, -1) | ||
if (israw) expr = '=' + expr | ||
} | ||
list[i] = '\u0001' + (pcex.push(expr) - 1) + _bp[1] | ||
list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1] | ||
} | ||
@@ -252,16 +261,6 @@ html = list.join('') | ||
if (pcex.length) { | ||
html = html | ||
.replace(/\u0001(\d+)/g, function (_, d) { | ||
var expr = pcex[d] | ||
html = html.replace(RE_REPEXPR, function (_, d) { | ||
if (expr[0] === '=') { | ||
expr = expr.replace(brackets.R_STRINGS, function (qs) { | ||
return qs | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
}) | ||
} | ||
return pcex._bp[0] + expr.trim().replace(/[\r\n]+/g, ' ').replace(/"/g, '\u2057') | ||
}) | ||
return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) | ||
}) | ||
} | ||
@@ -310,3 +309,3 @@ return html | ||
if (opts.compact) html = html.replace(/>[ \t]+<([-\w\/])/g, '><$1') | ||
if (opts.compact) html = html.replace(HTML_PACK, '><$1') | ||
@@ -389,3 +388,3 @@ return restoreExpr(html, pcex).replace(TRIM_TRAIL, '') | ||
while (match = js.match(JS_ES6SIGN)) { | ||
while ((match = js.match(JS_ES6SIGN))) { | ||
@@ -409,3 +408,3 @@ parts.push(RE.leftContext) | ||
r.lastIndex = 0 | ||
while (m = r.exec(s)) { | ||
while ((m = r.exec(s))) { | ||
if (m[0][0] === '/' && !m[1] && !m[2]) { | ||
@@ -517,8 +516,10 @@ s = RE.leftContext + ' ' + RE.rightContext | ||
if (s.indexOf(scope) < 0) { | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s + | ||
',[data-is="' + tag + '"] ' + s | ||
} else { | ||
s = s.replace(scope, tag) + ',' + | ||
s.replace(scope, '[riot-tag="' + tag + '"]') | ||
s.replace(scope, '[riot-tag="' + tag + '"]') + ',' + | ||
s.replace(scope, '[data-is="' + tag + '"]') | ||
} | ||
return sel.slice(-1) === ' ' ? s + ' ' : s | ||
return s | ||
}) | ||
@@ -639,3 +640,3 @@ | ||
*/ | ||
var END_TAGS = /\/>\n|^<(?:\/?[-\w]+\s*|[-\w]+\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
@@ -662,14 +663,14 @@ /** | ||
* | ||
* @param {string} name - The tag name | ||
* @param {string} html - HTML (can contain embeded eols) | ||
* @param {string} css - Styles | ||
* @param {string} attribs - Root attributes | ||
* @param {string} js - JavaScript "constructor" | ||
* @param {Array} pcex - Expressions | ||
* @param {string} name - The tag name | ||
* @param {string} html - HTML (can contain embeded eols) | ||
* @param {string} css - Styles | ||
* @param {string} attr - Root attributes | ||
* @param {string} js - JavaScript "constructor" | ||
* @param {object} opts - Compiler options | ||
* @returns {string} Code to call `riot.tag2` | ||
*/ | ||
function mktag (name, html, css, attribs, js, pcex) { | ||
function mktag (name, html, css, attr, js, opts) { | ||
var | ||
c = ', ', | ||
s = '}' + (pcex.length ? ', ' + _q(pcex._bp[8]) : '') + ');' | ||
c = opts.debug ? ',\n ' : ', ', | ||
s = '});' | ||
@@ -681,3 +682,3 @@ if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
c + _q(css) + | ||
c + _q(attribs) + ', function(opts) {\n' + js + s | ||
c + _q(attr) + ', function(opts) {\n' + js + s | ||
} | ||
@@ -774,6 +775,6 @@ | ||
function getCode (code, opts, attribs, base) { | ||
var type = getType(attribs) | ||
var | ||
type = getType(attribs), | ||
src = getAttrib(attribs, 'src') | ||
var src = getAttrib(attribs, 'src') | ||
if (src) { | ||
@@ -839,3 +840,3 @@ if (DEFER_ATTR.test(attribs)) return false | ||
*/ | ||
CUST_TAG = RegExp(/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
.source.replace('@', S_STRINGS), 'gim'), | ||
@@ -971,3 +972,3 @@ /** | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
return mktag(tagName, html, styles, attribs, jscode, opts) | ||
}) | ||
@@ -991,3 +992,3 @@ | ||
parsers: parsers, | ||
version: 'WIP' | ||
version: 'v2.3.23' | ||
} |
@@ -5,203 +5,73 @@ /** | ||
*/ | ||
var REQPATH = './parsers/' | ||
var path = require('path') // for sass | ||
// dummy function for the none and javascript parsers | ||
function _none (src) { return src } | ||
/** Cache of required modules */ | ||
var _mods = { | ||
none: _none, | ||
javascript: _none | ||
// Passtrough for the internal `none` and `javascript` parsers | ||
function _none (src) { | ||
return src | ||
} | ||
/** | ||
* Returns the module name for the given parser's name. | ||
* | ||
* @param {string} name - one of the `html`, `css`, or `js` parsers. | ||
* @returns {string} The module name for using with `require()` | ||
* @static | ||
*/ | ||
function _modname (name) { | ||
switch (name) { | ||
case 'es6': | ||
return 'babel' | ||
case 'babel': | ||
return 'babel-core' | ||
case 'javascript': | ||
return 'none' | ||
case 'coffee': | ||
case 'coffeescript': | ||
return 'coffee-script' | ||
case 'scss': | ||
case 'sass': | ||
return 'node-sass' | ||
case 'typescript': | ||
return 'typescript-simple' | ||
default: | ||
return name | ||
} | ||
} | ||
// Initialize the cache with parsers that cannot be required | ||
var _mods = { none: _none, javascript: _none } | ||
/** | ||
* Loads a parser instance via `require`, without generating error. | ||
* Returns a parser instance by its name, requiring the module without generating error. | ||
* | ||
* @param {string} name - one of the `html`, `css`, or `js` parsers. | ||
* @param {string} [req=name] - name for `require()` | ||
* @returns {function} parser function, or null if error | ||
*/ | ||
function _try (name, req) { | ||
function fn (r) { | ||
try { return require(r) } catch (_) {/**/} | ||
return null | ||
} | ||
var p = _mods[name] = fn(req || _modname(name)) | ||
// istanbul ignore next: babel-core v5.8.x is not loaded by CI | ||
if (!p && name === 'es6') { | ||
p = _mods[name] = fn('babel-core') | ||
} | ||
return p | ||
} | ||
/** | ||
* Returns a parser instance by its name, require the module if necessary. | ||
* Public through the `parsers._req` function. | ||
* | ||
* @param {string} name - The parser's name, as registered in the parsers object | ||
* @param {string} [req] - To be used by `_try` with `require` | ||
* @returns {function} The parser instance, null if the parser is not found | ||
* @static | ||
* @param {string} [req] - To be used by require(). Defaults to parser's name | ||
* @returns {Function} The parser instance, null if the parser is not found. | ||
*/ | ||
function _req (name, req) { | ||
return name in _mods ? _mods[name] : _try(name, req) | ||
var mod | ||
if (name in _mods) { | ||
mod = _mods[name] | ||
} else { | ||
if (!req) req = REQPATH + (name === 'coffeescript' ? 'coffee' : name) | ||
try { mod = require(req) } catch (_) {/**/} | ||
_mods[name] = mod || null | ||
} | ||
return mod | ||
} | ||
/** | ||
* Merge the properties of the first object with the properties of the second. | ||
* Fill the parsers object with loaders for each parser. | ||
* | ||
* @param {object} target - Target object | ||
* @param {object} source - Source of the extra properties | ||
* @returns {object} Target object containing the new properties | ||
* @param {Object} _p - The `parsers` object | ||
* @returns {Object} The received object. | ||
* @private | ||
*/ | ||
function extend (target, source) { | ||
if (source) { | ||
for (var prop in source) { | ||
/* istanbul ignore next */ | ||
if (source.hasOwnProperty(prop)) { | ||
target[prop] = source[prop] | ||
} | ||
} | ||
function _makelist (_p) { | ||
var names = { | ||
html: ['jade'], | ||
css: ['sass', 'scss', 'less', 'stylus'], | ||
js: ['es6', 'babel', 'coffee', 'livescript', 'typescript'] | ||
} | ||
return target | ||
} | ||
module.exports = { | ||
/** | ||
* The HTML parsers. | ||
* @prop {function} jade - http://jade-lang.com | ||
*/ | ||
html: { | ||
jade: function (html, opts, url) { | ||
opts = extend({ | ||
pretty: true, | ||
filename: url, | ||
doctype: 'html' | ||
}, opts) | ||
return _req('jade').render(html, opts) | ||
// loads the module at first use and returns the parsed result | ||
function mkloader (dest, name) { | ||
return function _loadParser (p1, p2, p3, p4) { | ||
return (dest[name] = _req(name))(p1, p2, p3, p4) | ||
} | ||
}, | ||
/** | ||
* Style parsers. In browsers, only less is supported. | ||
* @prop {function} sass - http://sass-lang.com | ||
* @prop {function} scss - http://sass-lang.com | ||
* @prop {function} less - http://lesscss.org | ||
* @prop {function} stylus - http://stylus-lang.com | ||
*/ | ||
css: { | ||
sass: function (tag, css, opts, url) { | ||
opts = extend({ | ||
data: css, | ||
includePaths: [path.dirname(url)], | ||
indentedSyntax: true, | ||
omitSourceMapUrl: true, | ||
outputStyle: 'compact' | ||
}, opts) | ||
return _req('sass').renderSync(opts).css + '' | ||
}, | ||
scss: function (tag, css, opts, url) { | ||
opts = extend({ | ||
data: css, | ||
includePaths: [path.dirname(url)], | ||
indentedSyntax: false, | ||
omitSourceMapUrl: true, | ||
outputStyle: 'compact' | ||
}, opts) | ||
return _req('scss').renderSync(opts).css + '' | ||
}, | ||
less: function (tag, css, opts, url) { | ||
var ret | ||
} | ||
opts = extend({ | ||
sync: true, | ||
syncImport: true, | ||
filename: url | ||
}, opts) | ||
_req('less').render(css, opts, function (err, result) { | ||
/* istanbul ignore next */ | ||
if (err) throw err | ||
ret = result.css | ||
}) | ||
return ret | ||
}, | ||
stylus: function (tag, css, opts, url) { | ||
var | ||
stylus = _req('stylus'), | ||
nib = _req('nib') // optional nib support | ||
for (var type in names) { // eslint-disable-line guard-for-in | ||
var dest = _p[type] | ||
opts = extend({ filename: url }, opts) | ||
/* istanbul ignore next: can't run both */ | ||
return nib | ||
? stylus(css, opts).use(nib()).import('nib').render() : stylus.render(css, opts) | ||
} | ||
}, | ||
/** | ||
* The JavaScript parsers. | ||
* @prop {function} es6 - https://babeljs.io - babel or babel-core up to v5.8 | ||
* @prop {function} babel - https://babeljs.io - for v6.x or later | ||
* @prop {function} coffee - http://coffeescript.org | ||
* @prop {function} livescript - http://livescript.net | ||
* @prop {function} typescript - http://www.typescriptlang.org | ||
*/ | ||
js: { | ||
es6: function (js, opts) { | ||
opts = extend({ | ||
blacklist: ['useStrict', 'strict', 'react'], | ||
sourceMaps: false, | ||
comments: false | ||
}, opts) | ||
return _req('es6').transform(js, opts).code | ||
}, | ||
babel: function (js, opts, url) { | ||
return _req('babel').transform(js, extend({ filename: url }, opts)).code | ||
}, | ||
coffee: function (js, opts) { | ||
return _req('coffee').compile(js, extend({ bare: true }, opts)) | ||
}, | ||
livescript: function (js, opts) { | ||
return _req('livescript').compile(js, extend({ bare: true, header: false }, opts)) | ||
}, | ||
typescript: function (js, opts) { | ||
return _req('typescript')(js, opts) | ||
}, | ||
none: _none, javascript: _none | ||
}, | ||
_modname: _modname, | ||
_req: _req | ||
names[type].forEach(function (name) { // eslint-disable-line no-loop-func | ||
dest[name] = mkloader(dest, name) | ||
}) | ||
} | ||
return _p | ||
} | ||
exports = module.exports | ||
exports.js.coffeescript = exports.js.coffee // 4 the nostalgics | ||
// Exports the initialized parsers | ||
module.exports = _makelist({ | ||
_req: _req, | ||
html: {}, | ||
css: {}, | ||
js: { none: _none, javascript: _none } | ||
}) | ||
module.exports.js.coffeescript = module.exports.js.coffee // 4 the nostalgics |
{ | ||
"name": "riot-compiler", | ||
"version": "2.3.22", | ||
"version": "2.3.23", | ||
"description": "Compiler for riot .tag files", | ||
@@ -20,3 +20,3 @@ "main": "lib/compiler.js", | ||
"test": "make test", | ||
"prepublish": "make build && ./node_modules/.bin/riot-bump" | ||
"prepublish": "make build && ./node_modules/.bin/riot-bump && ./node_modules/.bin/riot-bump lib" | ||
}, | ||
@@ -34,8 +34,8 @@ "repository": { | ||
"devDependencies": { | ||
"coveralls": "^2.11.4", | ||
"eslint": "^1.10.3", | ||
"coveralls": "^2.11.8", | ||
"eslint": "^2.2.0", | ||
"expect.js": "^0.3.1", | ||
"istanbul": "^0.4.1", | ||
"istanbul": "^0.4.2", | ||
"jspreproc": "^0.2.7", | ||
"mocha": "^2.3.4", | ||
"mocha": "^2.4.5", | ||
"riot-bump": "^1.0.0" | ||
@@ -42,0 +42,0 @@ }, |
[![Build Status][travis-image]][travis-url] | ||
[![Code Quality][codeclimate-image]][codeclimate-url] | ||
[![Issue Count][codeclimate-image]][codeclimate-url] | ||
[![Coverage Status][coverage-image]][coverage-url] | ||
@@ -41,10 +41,10 @@ [![NPM version][npm-version-image]][npm-url] | ||
[travis-url]: https://travis-ci.org/riot/compiler | ||
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square | ||
[license-image]: https://img.shields.io/badge/license-MIT-000000.svg?style=flat-square | ||
[license-url]: LICENSE.txt | ||
[npm-version-image]: http://img.shields.io/npm/v/riot-compiler.svg?style=flat-square | ||
[npm-downloads-image]: http://img.shields.io/npm/dm/riot-compiler.svg?style=flat-square | ||
[npm-version-image]: https://img.shields.io/npm/v/riot-compiler.svg?style=flat-square | ||
[npm-downloads-image]: https://img.shields.io/npm/dm/riot-compiler.svg?style=flat-square | ||
[npm-url]: https://npmjs.org/package/riot-compiler | ||
[coverage-image]: https://img.shields.io/coveralls/riot/compiler/master.svg?style=flat-square | ||
[coverage-url]: https://coveralls.io/r/riot/compiler/?branch=master | ||
[codeclimate-image]: https://codeclimate.com/github/riot/compiler/badges/gpa.svg | ||
[coverage-image]: https://codeclimate.com/github/riot/compiler/badges/coverage.svg | ||
[coverage-url]: https://codeclimate.com/github/riot/compiler/coverage | ||
[codeclimate-image]: https://codeclimate.com/github/riot/compiler/badges/issue_count.svg | ||
[codeclimate-url]: https://codeclimate.com/github/riot/compiler |
100
src/core.js
@@ -18,7 +18,4 @@ //#if NODE | ||
//#set $_RIX_TEST = 4 | ||
//#set $_RIX_PAIR = 8 | ||
//#ifndef $_RIX_TEST | ||
var | ||
$_RIX_TEST = 4, | ||
$_RIX_PAIR = 8 | ||
var $_RIX_TEST = 4 | ||
//#endif | ||
@@ -68,5 +65,12 @@ | ||
*/ | ||
var HTML_TAGS = /<([-\w]+)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g | ||
/** | ||
* Matches spaces and tabs between HTML tags | ||
* Used by the `compact` option. | ||
* @const RegExp | ||
*/ | ||
var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g | ||
/** | ||
* Matches boolean HTML attributes, prefixed with `"__"` in the riot tag definition. | ||
@@ -126,2 +130,6 @@ * Used by {@link module:compiler~parseAttribs|parseAttribs} with lowercase names. | ||
var | ||
RE_HASEXPR = /\x01#\d/, // for searching a hidden expression in a string | ||
RE_REPEXPR = /\x01#(\d+)/g, // used to restore a hidden expression | ||
CH_IDEXPR = '\x01#', // sequence for marking a hidden expression | ||
CH_DQCODE = '\u2057', // escape double quotes with this char | ||
DQ = '"', | ||
@@ -149,3 +157,3 @@ SQ = "'" | ||
re.lastIndex = 0 | ||
while (mm = re.exec(src)) { | ||
while ((mm = re.exec(src))) { | ||
if (mm[0][0] === '<') { | ||
@@ -178,3 +186,3 @@ src = RegExp.leftContext + RegExp.rightContext | ||
while (match = HTML_ATTRS.exec(str)) { | ||
while ((match = HTML_ATTRS.exec(str))) { | ||
var | ||
@@ -195,3 +203,3 @@ k = match[1].toLowerCase(), // attribute names are forced to lower case | ||
} else { | ||
if (/\u0001\d/.test(v)) { | ||
if (RE_HASEXPR.test(v)) { | ||
// renames special attributes with expressiones in their value. | ||
@@ -234,3 +242,3 @@ if (k === 'value') vexp = 1 | ||
list = brackets.split(html, 0, _bp), | ||
expr, israw | ||
expr | ||
@@ -242,8 +250,6 @@ for (var i = 1; i < list.length; i += 2) { | ||
} else if (jsfn) { | ||
israw = expr[0] === '=' | ||
expr = jsfn(israw ? expr.slice(1) : expr, opts).trim() | ||
expr = jsfn(expr, opts).trim() | ||
if (expr.slice(-1) === ';') expr = expr.slice(0, -1) | ||
if (israw) expr = '=' + expr | ||
} | ||
list[i] = '\u0001' + (pcex.push(expr) - 1) + _bp[1] | ||
list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1] | ||
} | ||
@@ -265,16 +271,6 @@ html = list.join('') | ||
if (pcex.length) { | ||
html = html | ||
.replace(/\u0001(\d+)/g, function (_, d) { | ||
var expr = pcex[d] | ||
if (expr[0] === '=') { | ||
expr = expr.replace(brackets.R_STRINGS, function (qs) { | ||
return qs | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
}) | ||
} | ||
// 2016-01-18: chaining replaces seems most efficient | ||
return pcex._bp[0] + expr.trim().replace(/[\r\n]+/g, ' ').replace(/"/g, '\u2057') | ||
}) | ||
html = html.replace(RE_REPEXPR, function (_, d) { | ||
// 2016-01-18: chaining replaces seems most efficient | ||
return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) | ||
}) | ||
} | ||
@@ -333,3 +329,3 @@ return html | ||
// for `opts.compact`, remove tabs and spaces between tags | ||
if (opts.compact) html = html.replace(/>[ \t]+<([-\w\/])/g, '><$1') | ||
if (opts.compact) html = html.replace(HTML_PACK, '><$1') | ||
@@ -420,3 +416,3 @@ // 2016-01-16: new logic in compile makes necessary another TRIM_TRAIL | ||
// 2016-01-18: Faster, only replaces the method name, captured in $1 | ||
while (match = js.match(JS_ES6SIGN)) { | ||
while ((match = js.match(JS_ES6SIGN))) { | ||
// save the processed part | ||
@@ -443,3 +439,3 @@ parts.push(RE.leftContext) | ||
r.lastIndex = 0 | ||
while (m = r.exec(s)) { | ||
while ((m = r.exec(s))) { | ||
if (m[0][0] === '/' && !m[1] && !m[2]) { // $1:div, $2:regex | ||
@@ -563,10 +559,12 @@ s = RE.leftContext + ' ' + RE.rightContext | ||
// if `:scope` was not included, add the tag name as prefix, and mirror all | ||
// to `[riot-tag]` | ||
// `[data-is]` | ||
if (s.indexOf(scope) < 0) { | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s | ||
s = tag + ' ' + s + ',[riot-tag="' + tag + '"] ' + s + | ||
',[data-is="' + tag + '"] ' + s | ||
} else { | ||
s = s.replace(scope, tag) + ',' + | ||
s.replace(scope, '[riot-tag="' + tag + '"]') | ||
s.replace(scope, '[riot-tag="' + tag + '"]') + ',' + | ||
s.replace(scope, '[data-is="' + tag + '"]') | ||
} | ||
return sel.slice(-1) === ' ' ? s + ' ' : s // respect (a little) the user style | ||
return s | ||
}) | ||
@@ -696,3 +694,3 @@ // add the danling bracket char and return the processed selector list | ||
*/ | ||
var END_TAGS = /\/>\n|^<(?:\/?[-\w]+\s*|[-\w]+\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/ | ||
@@ -719,14 +717,14 @@ /** | ||
* | ||
* @param {string} name - The tag name | ||
* @param {string} html - HTML (can contain embeded eols) | ||
* @param {string} css - Styles | ||
* @param {string} attribs - Root attributes | ||
* @param {string} js - JavaScript "constructor" | ||
* @param {Array} pcex - Expressions | ||
* @param {string} name - The tag name | ||
* @param {string} html - HTML (can contain embeded eols) | ||
* @param {string} css - Styles | ||
* @param {string} attr - Root attributes | ||
* @param {string} js - JavaScript "constructor" | ||
* @param {object} opts - Compiler options | ||
* @returns {string} Code to call `riot.tag2` | ||
*/ | ||
function mktag (name, html, css, attribs, js, pcex) { | ||
function mktag (name, html, css, attr, js, opts) { | ||
var | ||
c = ', ', | ||
s = '}' + (pcex.length ? ', ' + _q(pcex._bp[$_RIX_PAIR]) : '') + ');' | ||
c = opts.debug ? ',\n ' : ', ', | ||
s = '});' | ||
@@ -740,3 +738,3 @@ // give more consistency to the output | ||
c + _q(css) + | ||
c + _q(attribs) + ', function(opts) {\n' + js + s | ||
c + _q(attr) + ', function(opts) {\n' + js + s | ||
} | ||
@@ -834,7 +832,7 @@ | ||
function getCode (code, opts, attribs, base) { | ||
var type = getType(attribs) | ||
var | ||
type = getType(attribs), | ||
src = getAttrib(attribs, 'src') | ||
//#if NODE | ||
var src = getAttrib(attribs, 'src') | ||
if (src) { | ||
@@ -848,2 +846,4 @@ if (DEFER_ATTR.test(attribs)) return false | ||
} | ||
//#else | ||
if (src) return false | ||
//#endif | ||
@@ -907,3 +907,3 @@ return _compileJS(code, opts, type, getParserOptions(attribs), base) | ||
*/ | ||
CUST_TAG = RegExp(/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ | ||
.source.replace('@', S_STRINGS), 'gim'), | ||
@@ -1064,3 +1064,3 @@ /** | ||
// replace the tag with a call to the riot.tag2 function and we are done | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
return mktag(tagName, html, styles, attribs, jscode, opts) | ||
}) | ||
@@ -1067,0 +1067,0 @@ |
@@ -11,3 +11,3 @@ /* global describe, expect:true, compiler:true */ | ||
require('./specs/tag') | ||
require('./specs/parsers/suite') | ||
require('./specs/parsers/_suite') | ||
}) |
@@ -67,43 +67,43 @@ /* eslint-env mocha */ | ||
expect(render('h1 { font-size: 150% }')) | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1 { font-size: 150% }') | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1,[data-is="my-tag"] h1{ font-size: 150% }') | ||
}) | ||
it('add my-tag to the multi selector in a line', function () { | ||
expect(render('h1 { font-size: 150% } #id { color: #f00 }')) | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1 { font-size: 150% } my-tag #id,[riot-tag="my-tag"] #id { color: #f00 }') | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1,[data-is="my-tag"] h1{ font-size: 150% } my-tag #id,[riot-tag="my-tag"] #id,[data-is="my-tag"] #id{ color: #f00 }') | ||
}) | ||
it('add my-tag to the complex selector', function () { | ||
expect(render('header a.button:hover { text-decoration: none }')) | ||
.to.equal('my-tag header a.button:hover,[riot-tag="my-tag"] header a.button:hover { text-decoration: none }') | ||
.to.equal('my-tag header a.button:hover,[riot-tag="my-tag"] header a.button:hover,[data-is="my-tag"] header a.button:hover{ text-decoration: none }') | ||
}) | ||
it('add my-tag to the comma-separated selector', function () { | ||
expect(render('h2, h3 { border-bottom: 1px solid #000 }')) | ||
.to.equal('my-tag h2,[riot-tag="my-tag"] h2,my-tag h3,[riot-tag="my-tag"] h3 { border-bottom: 1px solid #000 }') | ||
.to.equal('my-tag h2,[riot-tag="my-tag"] h2,[data-is="my-tag"] h2,my-tag h3,[riot-tag="my-tag"] h3,[data-is="my-tag"] h3{ border-bottom: 1px solid #000 }') | ||
}) | ||
it('add my-tag to the attribute selector', function () { | ||
expect(render('i[class=twitter] { background: #55ACEE }')) | ||
.to.equal('my-tag i[class=twitter],[riot-tag="my-tag"] i[class=twitter] { background: #55ACEE }') | ||
.to.equal('my-tag i[class=twitter],[riot-tag="my-tag"] i[class=twitter],[data-is="my-tag"] i[class=twitter]{ background: #55ACEE }') | ||
}) | ||
it('add my-tag to the selector with a pseudo-class', function () { | ||
expect(render('a:after { content: "*" }')) | ||
.to.equal('my-tag a:after,[riot-tag="my-tag"] a:after { content: "*" }') | ||
.to.equal('my-tag a:after,[riot-tag="my-tag"] a:after,[data-is="my-tag"] a:after{ content: "*" }') | ||
}) | ||
it('add my-tag to the selector with multi-line definitions', function () { | ||
expect(render('header {\n text-align: center;\n background: rgba(0,0,0,.2);\n}')) | ||
.to.equal('my-tag header,[riot-tag="my-tag"] header { text-align: center; background: rgba(0,0,0,.2); }') | ||
.to.equal('my-tag header,[riot-tag="my-tag"] header,[data-is="my-tag"] header{ text-align: center; background: rgba(0,0,0,.2); }') | ||
}) | ||
it('add my-tag to the root selector', function () { | ||
expect(render(':scope { display: block }')) | ||
.to.equal('my-tag,[riot-tag="my-tag"] { display: block }') | ||
.to.equal('my-tag,[riot-tag="my-tag"],[data-is="my-tag"]{ display: block }') | ||
}) | ||
it('add my-tag to the nested root selector', function () { | ||
expect(render(':scope > ul { padding: 0 }')) | ||
.to.equal('my-tag > ul,[riot-tag="my-tag"] > ul { padding: 0 }') | ||
.to.equal('my-tag > ul,[riot-tag="my-tag"] > ul,[data-is="my-tag"] > ul{ padding: 0 }') | ||
}) | ||
it('add my-tag to the root selector with attribute', function () { | ||
expect(render(':scope[disabled] { color: gray }')) | ||
.to.equal('my-tag[disabled],[riot-tag="my-tag"][disabled] { color: gray }') | ||
.to.equal('my-tag[disabled],[riot-tag="my-tag"][disabled],[data-is="my-tag"][disabled]{ color: gray }') | ||
}) | ||
it('add my-tag to the root selector with class', function () { | ||
expect(render(':scope.great { color: gray }')) | ||
.to.equal('my-tag.great,[riot-tag="my-tag"].great { color: gray }') | ||
.to.equal('my-tag.great,[riot-tag="my-tag"].great,[data-is="my-tag"].great{ color: gray }') | ||
}) | ||
@@ -116,3 +116,3 @@ it('not add my-tag to @font-face', function () { | ||
expect(render('@media (min-width: 500px) {\n header {\n text-align: left;\n }\n}')) | ||
.to.equal('@media (min-width: 500px) { my-tag header,[riot-tag="my-tag"] header { text-align: left; } }') | ||
.to.equal('@media (min-width: 500px) { my-tag header,[riot-tag="my-tag"] header,[data-is="my-tag"] header{ text-align: left; } }') | ||
}) | ||
@@ -130,5 +130,5 @@ it('not add my-tag to "from" and "to" in @keyframes', function () { | ||
expect(render('h1 {} h2 { font-size: 130% }')) | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1 {} my-tag h2,[riot-tag="my-tag"] h2 { font-size: 130% }') | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1,[data-is="my-tag"] h1{} my-tag h2,[riot-tag="my-tag"] h2,[data-is="my-tag"] h2{ font-size: 130% }') | ||
}) | ||
}) |
@@ -9,2 +9,2 @@ //src: test/specs/fixtures/box.tag | ||
} | ||
}, '{ }'); | ||
}); |
@@ -17,4 +17,4 @@ // free indent | ||
.bind (this) | ||
}, '{ }'); | ||
}); | ||
// done |
@@ -5,2 +5,2 @@ riot.tag2('includes-defer', '<p onclick="{click}"></p> <script src="riotjs.object.js"></script> <script src="../expect/riotjs.method.js"></script>', '', '', function(opts) { | ||
{foo ({})}.bind(this) | ||
}, '{ }'); | ||
}); |
@@ -21,2 +21,2 @@ //src: test/specs/fixtures/includes.tag | ||
.bind (this) | ||
}, '{ }'); | ||
}); |
@@ -9,3 +9,3 @@ //src: test/specs/fixtures/one-quote.tag | ||
var a = 'test'; | ||
}, '{ }'); | ||
}); | ||
@@ -12,0 +12,0 @@ riot.tag2('one-dquote', '<h1>Double quote"</h1>', '', '', function(opts) { |
//src: test/specs/fixtures/pre.tag | ||
riot.tag2('pre-tag', '<pre>xyz\n cc\n ss</pre> <pre-fake>xyz cc ss</pre-fake> <pre x="{1>2}" y="{3}">xyz\n cc\n ss</pre>', '', '', function(opts) { | ||
}, '{ }'); | ||
}); | ||
@@ -5,0 +5,0 @@ riot.tag2('pre-tag2', '<pre>xyz\n cc\n ss</pre> <pre-x> cc ss</pre-x>', '', '', function(opts) { |
@@ -11,2 +11,2 @@ //src: test/specs/fixtures/raw-html.tag | ||
}.bind(this) | ||
}, '{ }'); | ||
}); |
//src: test/specs/fixtures/root-attribs.tag | ||
riot.tag2('root-attribs', '', '', '__disabled="{x<y}" style="display:none" data-x="{x>0 ? 1 : 0}" data-y="{y<0 ? -1 : 0}" data-s="{\'John\\\'s\'}" id="{_id}"', function(opts) { | ||
}, '{ }'); | ||
}); |
//src: test/specs/fixtures/scoped.tag | ||
riot.tag2('scoped-tag', '<p>should have a border</p>', 'scoped-tag,[riot-tag="scoped-tag"] { background: red; } scoped-tag p,[riot-tag="scoped-tag"] p { border: solid 1px black }', '', function(opts) { | ||
riot.tag2('scoped-tag', '<p>should have a border</p>', 'scoped-tag,[riot-tag="scoped-tag"],[data-is="scoped-tag"]{ background: red; } scoped-tag p,[riot-tag="scoped-tag"] p,[data-is="scoped-tag"] p{ border: solid 1px black }', '', function(opts) { | ||
}); |
//src: test/specs/fixtures/so-input.tag | ||
riot.tag2('so-input', '<label if="{opts.label}" for="theInput">{opts.label}</label> <input id="theInput" class="{\'is-invalid\': note.type === 1, \'is-valid\': ofMinLength && note.type !== 1}">', '', '', function(opts) { | ||
require('./so-input.js').call(this); | ||
}, '{ }'); | ||
}); |
@@ -31,3 +31,3 @@ //src: test/specs/fixtures/treeview.tag | ||
} | ||
}, '{ }'); | ||
}); | ||
@@ -60,2 +60,2 @@ riot.tag2('treeitem', '<div class="{bold: isFolder()}" onclick="{toggle}" ondblclick="{changeType}"> {name} <span if="{isFolder()}">[{open ? \'-\' : \'+\'}]</span> </div> <ul if="{isFolder()}" show="{isFolder() && open}"> <li each="{child, i in nodes}"> <treeitem data="{child}"></treeitem> </li> <li onclick="{addChild}">+</li> </ul>', '', '', function(opts) { | ||
}.bind(this) | ||
}, '{ }'); | ||
}); |
@@ -5,2 +5,2 @@ //src: test/specs/fixtures/whitespace.tag | ||
{}.bind(this) | ||
}, '{ }'); | ||
}); |
@@ -9,3 +9,29 @@ module.exports = { | ||
.trim() | ||
}, | ||
/** | ||
* Returns the module name for the given parser's name. | ||
* | ||
* @param {string} name - one of the `html`, `css`, or `js` parsers. | ||
* @returns {string} The module name for using with `require()` | ||
*/ | ||
requireName: function (name) { | ||
switch (name) { | ||
case 'es6': | ||
return 'babel' | ||
case 'babel': | ||
return 'babel-core' | ||
case 'javascript': | ||
return 'none' | ||
case 'coffee': | ||
case 'coffeescript': | ||
return 'coffee-script' | ||
case 'scss': | ||
case 'sass': | ||
return 'node-sass' | ||
case 'typescript': | ||
return 'typescript-simple' | ||
default: | ||
return name | ||
} | ||
} | ||
} |
@@ -135,2 +135,3 @@ /* eslint-env mocha */ | ||
/* | ||
it('raw html detection through the `=` flag', function () { | ||
@@ -143,3 +144,3 @@ testStr( | ||
'<ul><li>{= [\u2057foo\u2057, \u2057bar\u2057].join(\'<br/>\')}</li></ul>') | ||
}) | ||
})*/ | ||
@@ -146,0 +147,0 @@ it('new compiler.html API allows omit the options (v2.3.20)', function () { |
riot.tag2('tag', '<p attr="${thing}">\\${ thing \\}</p>', '', '', function(opts) { | ||
this.x = 'ok' | ||
}, '${ }'); | ||
}); |
@@ -9,6 +9,5 @@ | ||
riot.tag2('2nd', '<p></p>', '', '', function(opts) { | ||
riot.tag2('-t2', '<p></p>', '', '', function(opts) { | ||
this.foo = function() { | ||
this.update() | ||
@@ -18,2 +17,2 @@ }.bind(this) | ||
var after = 'js2 <html>' | ||
var after = 'js2 <html>' |
@@ -1,3 +0,3 @@ | ||
riot.tag2('less-import', '<button></button>', 'less-import,[riot-tag="less-import"] { display: inline-block; } less-import button,[riot-tag="less-import"] button { background: #3f51b5; color: rgba(0, 0, 0, 0.87); cursor: pointer; } less-import button,[riot-tag="less-import"] button { color: #ffffff; } less-import button:active,[riot-tag="less-import"] button:active { background: #8591d5; }', '', function(opts) { | ||
riot.tag2('less-import', '<button></button>', 'less-import,[riot-tag="less-import"],[data-is="less-import"]{display:inline-block} less-import button,[riot-tag="less-import"] button,[data-is="less-import"] button{background:#3f51b5;color:rgba(0,0,0,0.87);cursor:pointer} less-import button,[riot-tag="less-import"] button,[data-is="less-import"] button{color:#fff} less-import button:active,[riot-tag="less-import"] button:active,[data-is="less-import"] button:active{background:#8591d5}', '', function(opts) { | ||
this.foo = function () {}.bind(this) | ||
}); |
@@ -1,3 +0,3 @@ | ||
riot.tag2('less-test', '<h3>less</h3>', '.box { color: #fe33ac; border-color: #fdcdea; } .box div { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }', '', function(opts) { | ||
riot.tag2('less-test', '<h3>less</h3>', '.box{color:#fe33ac;border-color:#fdcdea}.box div{-webkit-box-shadow:0 0 5px rgba(0,0,0,0.3);box-shadow:0 0 5px rgba(0,0,0,0.3)}', '', function(opts) { | ||
this.foo = function () {}.bind(this) | ||
}); |
@@ -1,2 +0,2 @@ | ||
riot.tag2('mixed-css', '<h3>Mixing CSS Types</h3>', 'mixed-css h3,[riot-tag="mixed-css"] h3 {top:0} a {color:gray} p {color:blue}', '', function(opts) { | ||
riot.tag2('mixed-css', '<h3>Mixing CSS Types</h3>', 'mixed-css h3,[riot-tag="mixed-css"] h3,[data-is="mixed-css"] h3{top:0} a {color:gray} p {color:blue}', '', function(opts) { | ||
}); |
@@ -1,3 +0,3 @@ | ||
riot.tag2('postcss', '<h3>postcss</h3>', 'postcss,[riot-tag="postcss"] { -webkit-transition: all 0.3s; transition: all 0.3s; }', '', function(opts) { | ||
riot.tag2('postcss', '<h3>postcss</h3>', 'postcss,[riot-tag="postcss"],[data-is="postcss"]{ -webkit-transition: all 0.3s; transition: all 0.3s; }', '', function(opts) { | ||
this.foo = function() {}.bind(this) | ||
}); |
@@ -10,2 +10,2 @@ riot.tag2('raw-html', '<p>{=[address1,address2].join(\'<br>\')}</p> <p onclick="{swap}"> {=\'<\' + myElem + \' style="color: \' + myColor + \';">\\n Click\\n</\' + myElem + \'><br>\\n<b>me</b>\'} </p>', '', '', function(opts) { | ||
} | ||
}, '{ }'); | ||
}); |
@@ -1,3 +0,3 @@ | ||
riot.tag2('scss-import', '<button></button>', 'scss-import,[riot-tag="scss-import"] { display: inline-block; } scss-import button,[riot-tag="scss-import"] button { background: #3f51b5; color: #000; cursor: pointer; } scss-import button:active,[riot-tag="scss-import"] button:active { background: #8591d5; }', '', function(opts) { | ||
riot.tag2('scss-import', '<button></button>', 'scss-import,[riot-tag="scss-import"],[data-is="scss-import"]{ display: inline-block; } scss-import button,[riot-tag="scss-import"] button,[data-is="scss-import"] button{ background: #3f51b5; color: #000; cursor: pointer; } scss-import button:active,[riot-tag="scss-import"] button:active,[data-is="scss-import"] button:active{ background: #8591d5; }', '', function(opts) { | ||
this.foo = function() {}.bind(this) | ||
}); |
riot.tag2('slide', '<div each="{url,index in imgList}" class="image-slide"><img riot-src="{url}" class="slider-item"></div>', '', '', function(opts) { | ||
this.imgList = ['abc', 'bdc']; | ||
}, '{ }'); | ||
}); |
@@ -5,2 +5,2 @@ riot.tag2('style-test', '<h3>{opts.title}</h3>', 'style-test { display: block; border: 2px }', '', function(opts) { | ||
}.bind(this) | ||
}, '{ }'); | ||
}); |
@@ -1,5 +0,5 @@ | ||
riot.tag2('style-test', '<header> <h1>{title1}</h1> <h2>{title2}</h2> <a class="button"><i class="twitter"></i> Twitter</a> </header> <h3 id="id">{title3}</h3> <ul> <li>Apple</li> <li>Orange</li> </ul>', 'style-test h1,[riot-tag="style-test"] h1 { font-size: 150% } style-test #id,[riot-tag="style-test"] #id { color: #f00 } style-test header a.button:hover,[riot-tag="style-test"] header a.button:hover { text-decoration: none } style-test h2,[riot-tag="style-test"] h2,style-test h3,[riot-tag="style-test"] h3 { border-bottom: 1px solid #000 } style-test i[class=twitter],[riot-tag="style-test"] i[class=twitter] { background: #55ACEE } style-test a:after,[riot-tag="style-test"] a:after { content: \'\\25BA\' } style-test header,[riot-tag="style-test"] header { text-align: center; background: rgba(0,0,0,.2); } style-test,[riot-tag="style-test"] { display: block } style-test > ul,[riot-tag="style-test"] > ul { padding: 0 } @font-face { font-family: \'FontAwesome\' } @media (min-width: 500px) { style-test header,[riot-tag="style-test"] header { text-align: left; } }', '', function(opts) { | ||
riot.tag2('style-test', '<header> <h1>{title1}</h1> <h2>{title2}</h2> <a class="button"><i class="twitter"></i> Twitter</a> </header> <h3 id="id">{title3}</h3> <ul> <li>Apple</li> <li>Orange</li> </ul>', 'style-test h1,[riot-tag="style-test"] h1,[data-is="style-test"] h1{ font-size: 150% } style-test #id,[riot-tag="style-test"] #id,[data-is="style-test"] #id{ color: #f00 } style-test header a.button:hover,[riot-tag="style-test"] header a.button:hover,[data-is="style-test"] header a.button:hover{ text-decoration: none } style-test h2,[riot-tag="style-test"] h2,[data-is="style-test"] h2,style-test h3,[riot-tag="style-test"] h3,[data-is="style-test"] h3{ border-bottom: 1px solid #000 } style-test i[class=twitter],[riot-tag="style-test"] i[class=twitter],[data-is="style-test"] i[class=twitter]{ background: #55ACEE } style-test a:after,[riot-tag="style-test"] a:after,[data-is="style-test"] a:after{ content: \'\\25BA\' } style-test header,[riot-tag="style-test"] header,[data-is="style-test"] header{ text-align: center; background: rgba(0,0,0,.2); } style-test,[riot-tag="style-test"],[data-is="style-test"]{ display: block } style-test > ul,[riot-tag="style-test"] > ul,[data-is="style-test"] > ul{ padding: 0 } @font-face { font-family: \'FontAwesome\' } @media (min-width: 500px) { style-test header,[riot-tag="style-test"] header,[data-is="style-test"] header{ text-align: left; } }', '', function(opts) { | ||
this.title1 = 'This is an example with Scoped-CSS.' | ||
this.title2 = 'KORE-WA-Scoped-CSS-NO-SAMPLE=DESU' | ||
this.title3 = 'List of fruits' | ||
}, '{ }'); | ||
}); |
riot.tag2('stylus-import', '<h3>{opts.title}</h3>', 'stylus-test { display: block; border: 2px; }', '', function(opts) { | ||
this.foo = function() {}.bind(this) | ||
}, '{ }'); | ||
}); |
riot.tag2('stylus-test', '<h3>{opts.title}</h3>', 'stylus-test { display: block; border: 2px; }', '', function(opts) { | ||
this.foo = function() {}.bind(this) | ||
}, '{ }'); | ||
}); |
@@ -7,2 +7,2 @@ // alternative to nested custom tags using the comment hack. | ||
var self = this | ||
}, '{ }'); | ||
}); |
riot.tag2('coffee', '<div class="{className: true}" str="{({ className: true })}">Hello</div>', '', '', function(opts) { | ||
}, '{ }'); | ||
}); |
@@ -8,2 +8,2 @@ riot.tag2('babel', '<h3>{test}</h3>', '', '', function(opts) { | ||
this.test = 'This is ' + type; | ||
}, '{ }'); | ||
}); |
@@ -11,2 +11,2 @@ riot.tag2('kids', '<h3 each="{kids.slice(1, 3)}">{name}</h3>', '', '', function(opts) { | ||
]; | ||
}, '{ }'); | ||
}); |
riot.tag2('babelcore', '<h3>{test}</h3>', '', '', function(opts) { | ||
var foo | ||
}, '{ }'); | ||
}); |
@@ -5,2 +5,2 @@ riot.tag2('es6', '<h3>{test}</h3>', '', '', function(opts) { | ||
this.test = 'This is ' + type; | ||
}, '{ }'); | ||
}); |
riot.tag2('sample', '<p>test {value}</p>', '', '', function(opts) { | ||
this.value = 'sample'; | ||
}, '{ }'); | ||
}); |
riot.tag2('treeitems', '<treeitem> <div class="{bold: isFolder()}" onclick="{toggle}" ondblclick="{changeType}"> {name} <span if="{isFolder()}">[{open ? \'-\' : \'+\'}]</span> </div> <ul if="{isFolder()}" show="{isFolder() && open}"> <li each="{child, i in nodes}"> <treeitem data="{child}"></treeitem> </li> <li onclick="{addChild}">+</li> </ul> </treeitem>', '', '', function(opts) { | ||
var self = this | ||
}, '{ }'); | ||
}); |
@@ -15,2 +15,2 @@ riot.tag2('kids', '<h3 each="{name in kids}">{name}</h3>', '', '', function(opts) { | ||
]; | ||
}, '{ }'); | ||
}); |
@@ -216,9 +216,9 @@ /*eslint-env mocha */ | ||
expect(compileStr(dummyTag, '', { exclude: ['html'] })).to.be(norm( | ||
"riot.tag2('my-tag', '', 'my-tag,[riot-tag=\"my-tag\"] { color: red; }', '', function(opts) {\nthis.hi = \"hi\"\n});")) | ||
"riot.tag2('my-tag', '', 'my-tag,[riot-tag=\"my-tag\"],[data-is=\"my-tag\"]{ color: red; }', '', function(opts) {\nthis.hi = \"hi\"\n});")) | ||
expect(compileStr(dummyTag, '', { exclude: ['html', 'js'] })).to.be(norm( | ||
"riot.tag2('my-tag', '', 'my-tag,[riot-tag=\"my-tag\"] { color: red; }', '', function(opts) {\n});")) | ||
"riot.tag2('my-tag', '', 'my-tag,[riot-tag=\"my-tag\"],[data-is=\"my-tag\"]{ color: red; }', '', function(opts) {\n});")) | ||
expect(compileStr(dummyTag, '', { exclude: ['css'] })).to.be(norm( | ||
"riot.tag2('my-tag', '<p>{hi}</p>', '', '', function(opts) {\nthis.hi = \"hi\"\n}, '{ }');")) | ||
"riot.tag2('my-tag', '<p>{hi}</p>', '', '', function(opts) {\nthis.hi = \"hi\"\n});")) | ||
@@ -251,6 +251,2 @@ expect(parts[0].html + parts[1].html).to.be('') | ||
it('Escaping raw html in expressions through the `=` flag', function () { | ||
testFile('raw-html') | ||
}) | ||
it('Script and Style blocks inside strings must be skipped riot#1448', function () { | ||
@@ -257,0 +253,0 @@ testFile('quoted-tags') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
235302
171
5153
0
8