Socket
Socket
Sign inDemoInstall

riot-compiler

Package Overview
Dependencies
Maintainers
4
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

riot-compiler - npm Package Compare versions

Comparing version 2.3.19 to 2.3.20

test/specs/expect/html-comments_out.js

8

CHANGELOG.md
# Compiler Changes
### v2.3.20
- Fix [riot#1495](https://github.com/riot/riot/issues/1495) : Warning of input tag value - Avoids warnings for date/datetime/time/month/email/color types with expression in its value.
- Fix [riot#1488](https://github.com/riot/riot/issues/1488) : Cannot read property 'replace' of undefined when compiling in Node a tag with an import in its less stylesheet -- Thanks to @jrx-jsj
- Fix [riot#1448](https://github.com/riot/riot/issues/1448) : Riot compiler parses and removes content from string declaration. This is partial fix, you need to write `<\/script>` for closing script tags within quoted strings.
- Revised regex that matches `<pre>` tags.
- `@import` directives of `stylus`, `sass`, `scss`, and `less` can be relative to the file being processed.
- Fixed lint issues with new .eslintrc.yml, almost compatible with [JavaScript Standard Style](http://standardjs.com/)
### v2.3.19

@@ -4,0 +12,0 @@ - Fixing issues with double quotes.

241

dist/compiler.js

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

/* riot-compiler v2.3.19, @license MIT, (c) 2015 Muut Inc. + contributors */
'use strict' // eslint-disable-line
/* riot-compiler v2.3.20, @license MIT, (c) 2015 Muut Inc. + contributors */
'use strict'

@@ -15,2 +15,4 @@ /**

var path = require('path')
var _modnames = {

@@ -27,10 +29,10 @@ es6: 'babel',

function _modname(name) {
function _modname (name) {
return _modnames[name] || name
}
function _try(name, req) { //eslint-disable-line complexity
function _try (name, req) { //eslint-disable-line complexity
var parser
function fn(r) {
function fn (r) {
try {

@@ -54,6 +56,18 @@ _mods[name] = require(r)

function _req(name, req) {
function _req (name, req) {
return name in _mods ? _mods[name] : _try(name, req)
}
function extend (obj, props) {
if (props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
}
return obj
}
var _html = {

@@ -70,3 +84,3 @@ jade: function (html, opts, url) {

var _css = {
sass: function(tag, css, opts, url) {
sass: function (tag, css, opts, url) {
var sass = _req('sass')

@@ -76,2 +90,3 @@

data: css,
includePaths: [path.dirname(url)],
indentedSyntax: true,

@@ -82,3 +97,3 @@ omitSourceMapUrl: true,

},
scss: function(tag, css, opts, url) {
scss: function (tag, css, opts, url) {
var scss = _req('scss')

@@ -88,2 +103,3 @@

data: css,
includePaths: [path.dirname(url)],
indentedSyntax: false,

@@ -94,3 +110,3 @@ omitSourceMapUrl: true,

},
less: function(tag, css, opts, url) {
less: function (tag, css, opts, url) {
var less = _req('less'),

@@ -101,2 +117,4 @@ ret

sync: true,
syncImport: true,
filename: url,
compress: true

@@ -112,6 +130,9 @@ }, opts), function (err, result) {

var
stylus = _req('stylus'), nib = _req('nib')
xopts = extend({filename: url}, opts),
stylus = _req('stylus'),
nib = _req('nib')
/* istanbul ignore next: can't run both */
return nib ?
stylus(css).use(nib()).import('nib').render() : stylus.render(css)
stylus(css, xopts).use(nib()).import('nib').render() : stylus.render(css, xopts)
}

@@ -121,9 +142,9 @@ }

var _js = {
livescript: function (js, opts, url) {
livescript: function (js, opts) {
return _req('livescript').compile(js, extend({bare: true, header: false}, opts))
},
typescript: function (js, opts, url) {
typescript: function (js, opts) {
return _req('typescript')(js, opts).replace(/\r\n?/g, '\n')
},
es6: function (js, opts, url) {
es6: function (js, opts) {
return _req('es6').transform(js, extend({

@@ -134,10 +155,5 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false

babel: function (js, opts, url) {
// istanbul ignore next: url empty if comming from expression
return _req('babel').transform(js,
extend({
filename: url || ''
}, opts)
).code
return _req('babel').transform(js, extend({filename: url}, opts)).code
},
coffee: function (js, opts, url) {
coffee: function (js, opts) {
return _req('coffee').compile(js, extend({bare: true}, opts))

@@ -198,3 +214,3 @@ },

function _rewrite(re, bp) {
function _rewrite (re, bp) {
return RegExp(

@@ -211,3 +227,3 @@ re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''

_brackets.split = function split(str, tmpl, _bp) {
_brackets.split = function split (str, tmpl, _bp) {

@@ -253,10 +269,10 @@ var

function unescapeStr(str) {
function unescapeStr (s) {
if (isexpr)
parts.push(str && str.replace(_bp[5], '$1'))
parts.push(s && s.replace(_bp[5], '$1'))
else
parts.push(str)
parts.push(s)
}
function skipBraces(ch, pos) {
function skipBraces (ch, pos) {
var

@@ -278,3 +294,3 @@ match,

_brackets.array = function array(pair) {
_brackets.array = function array (pair) {

@@ -308,3 +324,3 @@ if (!pair || pair === DEFAULT) return _pairs

function _regEx(str, opt) { return new RegExp(str, opt) }
function _regEx (str, opt) { return new RegExp(str, opt) }

@@ -324,8 +340,9 @@ var

HTML_ATTR = /\s*([-\w:\xA0-\xFF]+)\s*(?:=\s*('[^']+'|"[^"]+"|\S+))?/g,
SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i,
TRIM_TRAIL = /[ \t]+$/gm,
S_STRINGS = brackets.R_STRINGS.source
TRIM_TRAIL = /[ \t]+$/gm
var path = require('path')
function q(s) {
function q (s) {
return "'" + (s ? s

@@ -336,3 +353,3 @@ .replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') :

function mktag(name, html, css, attrs, js, pcex) {
function mktag (name, html, css, attrs, js, pcex) {
var

@@ -348,18 +365,7 @@ c = ', ',

function extend(obj, props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
return obj
}
function parseAttrs(str, pcex) {
function parseAttrs (str, pcex) {
var
list = [],
match,
k, v,
_bp = pcex._bp,
k, v, t, e,
DQ = '"'

@@ -384,22 +390,26 @@

if (k === 'type' && v.toLowerCase() === '"number"') {
v = DQ + _bp[0] + "'number'" + _bp[1] + DQ
if (k === 'type' && SPEC_TYPES.test(v)) {
t = v
}
else if (/\u0001\d/.test(v)) {
else {
if (/\u0001\d/.test(v)) {
if (BOOL_ATTRS.test(k)) {
k = '__' + k
if (k === 'value') e = 1
else if (BOOL_ATTRS.test(k)) k = '__' + k
else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
}
else if (~RIOT_ATTRS.indexOf(k)) {
k = 'riot-' + k
}
list.push(k + '=' + v)
}
list.push(k + '=' + v)
}
}
if (t) {
if (e) t = DQ + pcex._bp[0] + "'" + t.slice(1, -1) + "'" + pcex._bp[1] + DQ
list.push('type=' + t)
}
return list.join(' ')
}
function splitHtml(html, opts, pcex) {
function splitHtml (html, opts, pcex) {
var _bp = pcex._bp

@@ -409,3 +419,3 @@

var
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0,
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, //eslint-disable-line
list = brackets.split(html, 0, _bp),

@@ -431,3 +441,3 @@ expr

function restoreExpr(html, pcex) {
function restoreExpr (html, pcex) {
if (pcex.length) {

@@ -451,9 +461,8 @@ html = html

var
HTML_COMMENT = /<!--(?!>)[\S\s]*?-->/g,
HTML_COMMENT = _regEx(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_STRINGS, 'g'),
HTML_TAGS = /<([-\w]+)\s*([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)(\/?)>/g,
PRE_TAG = _regEx(
/<pre(?:\s+[^'">]+(?:(?:@Q)[^'">]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/
.source.replace('@Q', brackets.R_STRINGS.source), 'gi')
/<pre(?:\s+[^'">]+(?:(?:@Q)|[^>]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/.source.replace('@Q', S_STRINGS), 'gi')
function _compileHTML(html, opts, pcex) {
function _compileHTML (html, opts, pcex) {

@@ -475,7 +484,8 @@ html = splitHtml(html, opts, pcex)

var p = []
html = html.replace(PRE_TAG, function (q)
{ return p.push(q) && '\u0002' }).trim().replace(/\s+/g, ' ')
html = html.replace(PRE_TAG, function (_q) {
return p.push(_q) && '\u0002'
}).trim().replace(/\s+/g, ' ')
// istanbul ignore else
if (p.length)
html = html.replace(/\u0002/g, function (_) { return p.shift() })
html = html.replace(/\u0002/g, function () { return p.shift() })
}

@@ -492,3 +502,3 @@ else

// istanbul ignore next
function compileHTML(html, opts, pcex) {
function compileHTML (html, opts, pcex) {
if (Array.isArray(opts)) {

@@ -503,4 +513,4 @@ pcex = opts

if (!pcex.__intflag)
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '')
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s }).replace(TRIM_TRAIL, '')

@@ -516,3 +526,3 @@ if (!pcex._bp) pcex._bp = brackets.array(opts.brackets)

function riotjs(js) {
function riotjs (js) {
var

@@ -524,3 +534,3 @@ match,

js = js.replace(JS_RMCOMMS, function (m, q) { return q ? m : ' ' })
js = js.replace(JS_RMCOMMS, function (m, _q) { return _q ? m : ' ' })

@@ -544,11 +554,11 @@ while (match = js.match(JS_ES6SIGN)) {

function skipBlock(str) {
function skipBlock (str) {
var
re = _regEx('([{}])|' + brackets.S_QBLOCKS, 'g'),
level = 1,
match
mm
while (level && (match = re.exec(str))) {
if (match[1])
match[1] === '{' ? ++level : --level
while (level && (mm = re.exec(str))) {
if (mm[1])
mm[1] === '{' ? ++level : --level
}

@@ -559,3 +569,3 @@ return level ? str.length : re.lastIndex

function _compileJS(js, opts, type, parserOpts, url) {
function _compileJS (js, opts, type, parserOpts, url) {
if (!js) return ''

@@ -572,3 +582,3 @@ if (!type) type = opts.type

// istanbul ignore next
function compileJS(js, opts, type, extra) {
function compileJS (js, opts, type, extra) {
if (typeof opts === 'string') {

@@ -588,5 +598,5 @@ extra = type

var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g')
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + S_STRINGS, 'g')
function scopedCSS(tag, style) {
function scopedCSS (tag, style) {
var scope = ':scope'

@@ -614,3 +624,3 @@

function _compileCSS(style, tag, type, opts) {
function _compileCSS (style, tag, type, opts) {
var scoped = (opts || (opts = {})).scoped

@@ -623,3 +633,3 @@

else if (parsers.css[type]) {
style = parsers.css[type](tag, style, opts.parserOpts, opts.url)
style = parsers.css[type](tag, style, opts.parserOpts || {}, opts.url)
}

@@ -643,3 +653,3 @@ else if (type !== 'css') {

// istanbul ignore next
function compileCSS(style, parser, opts) {
function compileCSS (style, parser, opts) {
if (typeof parser === 'object') {

@@ -649,3 +659,2 @@ opts = parser

}
else if (!opts) opts = {}
return _compileCSS(style, opts.tagName, parser, opts)

@@ -658,3 +667,3 @@ }

function getType(str) {
function getType (str) {

@@ -668,3 +677,3 @@ if (str) {

function getAttr(str, name) {
function getAttr (str, name) {

@@ -682,3 +691,3 @@ if (str) {

function getParserOptions(attrs) {
function getParserOptions (attrs) {
var opts = getAttr(attrs, 'options')

@@ -690,3 +699,3 @@

function getCode(code, opts, attrs, url) {
function getCode (code, opts, attrs, url) {
var type = getType(attrs),

@@ -708,5 +717,14 @@ parserOpts = getParserOptions(attrs)

function cssCode (code, opts, attrs, url, tag) {
var extraOpts = {
parserOpts: getParserOptions(attrs),
scoped: attrs && /\sscoped(\s|=|$)/i.test(attrs),
url: url
}
return _compileCSS(code, tag, getType(attrs) || opts.style, extraOpts)
}
var END_TAGS = /\/>\n|^<(?:\/[\w\-]+\s*|[\w\-]+(?:\s+(?:[-\w:\xA0-\xFF][\S\s]*?)?)?)>\n/
function splitBlocks(str) {
function splitBlocks (str) {
var k, m

@@ -723,3 +741,3 @@

}
k = str.lastIndexOf('<', k -1)
k = str.lastIndexOf('<', k - 1)
}

@@ -729,3 +747,3 @@ return ['', str]

function compileTemplate(html, url, lang, opts) {
function compileTemplate (html, url, lang, opts) {
var parser = parsers.html[lang]

@@ -742,7 +760,8 @@

/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@Q|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/
.source.replace('@Q', brackets.R_STRINGS.source), 'gim'),
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi,
SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi')
.source.replace('@Q', S_STRINGS), 'gim'),
SRC_TAGS = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/.source + '|' + S_STRINGS,
STYLES = _regEx(SRC_TAGS, 'gi'),
SCRIPT = _regEx(SRC_TAGS.replace(/style/g, 'script'), 'gi')
function compile(src, opts, url) {
function compile (src, opts, url) {
var

@@ -754,6 +773,6 @@ parts = [],

url = url || process.cwd() + '/.'
if (!url) url = process.cwd() + '/.'
exclude = opts.exclude || false
function included(s) { return !(exclude && ~exclude.indexOf(s)) }
function included (s) { return !(exclude && ~exclude.indexOf(s)) }

@@ -776,3 +795,2 @@ var _bp = brackets.array(opts.brackets)

pcex._bp = _bp
pcex.__intflag = 1

@@ -786,3 +804,4 @@ tagName = tagName.toLowerCase()

if (body && (body = body.replace(HTML_COMMENT, '')) && /\S/.test(body)) {
if (body && (body = body.replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s })) && /\S/.test(body)) {

@@ -796,17 +815,15 @@ if (body2) {

body = body.replace(STYLE, included('css') ? function (_, _attrs, _style) {
var extraOpts = {
scoped: _attrs && /\sscoped(\s|=|$)/i.test(_attrs),
url: url,
parserOpts: getParserOptions(_attrs)
}
styles += (styles ? ' ' : '') +
_compileCSS(_style, tagName, getType(_attrs) || opts.style, extraOpts)
body = body.replace(STYLES, function (_m, _attrs, _style) {
if (_m[0] !== '<') return _m
if (included('css'))
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
return ''
} : '')
})
body = body.replace(SCRIPT, included('js') ? function (_, _attrs, _script) {
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
body = body.replace(SCRIPT, function (_m, _attrs, _script) {
if (_m[0] !== '<') return _m
if (included('js'))
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
return ''
} : '')
})

@@ -862,3 +879,3 @@ var blocks = splitBlocks(body.replace(TRIM_TRAIL, ''))

parsers: parsers,
version: 'v2.3.19'
version: 'v2.3.20'
}
/**
* Compiler for riot custom tags
* @version v2.3.19
* @version v2.3.20
*/

@@ -19,19 +19,21 @@

function _try(name, req) { //eslint-disable-line complexity
function _try (name, req) { //eslint-disable-line complexity
var parser
/*global window */
switch (name) {
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
}

@@ -47,6 +49,18 @@ parser = window[req]

function _req(name, req) {
function _req (name, req) {
return name in _mods ? _mods[name] : _try(name, req)
}
function extend (obj, props) {
if (props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
}
return obj
}
var _html = {

@@ -63,3 +77,3 @@ jade: function (html, opts, url) {

var _css = {
less: function(tag, css, opts, url) {
less: function (tag, css, opts, url) {
var less = _req('less'),

@@ -70,2 +84,4 @@ ret

sync: true,
syncImport: true,
filename: url,
compress: true

@@ -81,6 +97,9 @@ }, opts), function (err, result) {

var
stylus = _req('stylus'), nib = _req('nib')
xopts = extend({filename: url}, opts),
stylus = _req('stylus'),
nib = _req('nib')
/* istanbul ignore next: can't run both */
return nib ?
stylus(css).use(nib()).import('nib').render() : stylus.render(css)
stylus(css, xopts).use(nib()).import('nib').render() : stylus.render(css, xopts)
}

@@ -90,9 +109,9 @@ }

var _js = {
livescript: function (js, opts, url) {
livescript: function (js, opts) {
return _req('livescript').compile(js, extend({bare: true, header: false}, opts))
},
typescript: function (js, opts, url) {
typescript: function (js, opts) {
return _req('typescript')(js, opts).replace(/\r\n?/g, '\n')
},
es6: function (js, opts, url) {
es6: function (js, opts) {
return _req('es6').transform(js, extend({

@@ -103,10 +122,5 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false

babel: function (js, opts, url) {
// istanbul ignore next: url empty if comming from expression
return _req('babel').transform(js,
extend({
filename: url || ''
}, opts)
).code
return _req('babel').transform(js, extend({filename: url}, opts)).code
},
coffee: function (js, opts, url) {
coffee: function (js, opts) {
return _req('coffee').compile(js, extend({bare: true}, opts))

@@ -132,3 +146,3 @@ },

function _regEx(str, opt) { return new RegExp(str, opt) }
function _regEx (str, opt) { return new RegExp(str, opt) }

@@ -148,6 +162,7 @@ var

HTML_ATTR = /\s*([-\w:\xA0-\xFF]+)\s*(?:=\s*('[^']+'|"[^"]+"|\S+))?/g,
SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i,
TRIM_TRAIL = /[ \t]+$/gm,
S_STRINGS = brackets.R_STRINGS.source
TRIM_TRAIL = /[ \t]+$/gm
function q(s) {
function q (s) {
return "'" + (s ? s

@@ -158,3 +173,3 @@ .replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') :

function mktag(name, html, css, attrs, js, pcex) {
function mktag (name, html, css, attrs, js, pcex) {
var

@@ -170,18 +185,7 @@ c = ', ',

function extend(obj, props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
return obj
}
function parseAttrs(str, pcex) {
function parseAttrs (str, pcex) {
var
list = [],
match,
k, v,
_bp = pcex._bp,
k, v, t, e,
DQ = '"'

@@ -206,22 +210,26 @@

if (k === 'type' && v.toLowerCase() === '"number"') {
v = DQ + _bp[0] + "'number'" + _bp[1] + DQ
if (k === 'type' && SPEC_TYPES.test(v)) {
t = v
}
else if (/\u0001\d/.test(v)) {
else {
if (/\u0001\d/.test(v)) {
if (BOOL_ATTRS.test(k)) {
k = '__' + k
if (k === 'value') e = 1
else if (BOOL_ATTRS.test(k)) k = '__' + k
else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
}
else if (~RIOT_ATTRS.indexOf(k)) {
k = 'riot-' + k
}
list.push(k + '=' + v)
}
list.push(k + '=' + v)
}
}
if (t) {
if (e) t = DQ + pcex._bp[0] + "'" + t.slice(1, -1) + "'" + pcex._bp[1] + DQ
list.push('type=' + t)
}
return list.join(' ')
}
function splitHtml(html, opts, pcex) {
function splitHtml (html, opts, pcex) {
var _bp = pcex._bp

@@ -231,3 +239,3 @@

var
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0,
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, //eslint-disable-line
list = brackets.split(html, 0, _bp),

@@ -253,3 +261,3 @@ expr

function restoreExpr(html, pcex) {
function restoreExpr (html, pcex) {
if (pcex.length) {

@@ -273,9 +281,8 @@ html = html

var
HTML_COMMENT = /<!--(?!>)[\S\s]*?-->/g,
HTML_COMMENT = _regEx(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_STRINGS, 'g'),
HTML_TAGS = /<([-\w]+)\s*([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)(\/?)>/g,
PRE_TAG = _regEx(
/<pre(?:\s+[^'">]+(?:(?:@Q)[^'">]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/
.source.replace('@Q', brackets.R_STRINGS.source), 'gi')
/<pre(?:\s+[^'">]+(?:(?:@Q)|[^>]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/.source.replace('@Q', S_STRINGS), 'gi')
function _compileHTML(html, opts, pcex) {
function _compileHTML (html, opts, pcex) {

@@ -297,7 +304,8 @@ html = splitHtml(html, opts, pcex)

var p = []
html = html.replace(PRE_TAG, function (q)
{ return p.push(q) && '\u0002' }).trim().replace(/\s+/g, ' ')
html = html.replace(PRE_TAG, function (_q) {
return p.push(_q) && '\u0002'
}).trim().replace(/\s+/g, ' ')
// istanbul ignore else
if (p.length)
html = html.replace(/\u0002/g, function (_) { return p.shift() })
html = html.replace(/\u0002/g, function () { return p.shift() })
}

@@ -314,3 +322,3 @@ else

// istanbul ignore next
function compileHTML(html, opts, pcex) {
function compileHTML (html, opts, pcex) {
if (Array.isArray(opts)) {

@@ -325,4 +333,4 @@ pcex = opts

if (!pcex.__intflag)
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '')
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s }).replace(TRIM_TRAIL, '')

@@ -338,3 +346,3 @@ if (!pcex._bp) pcex._bp = brackets.array(opts.brackets)

function riotjs(js) {
function riotjs (js) {
var

@@ -346,3 +354,3 @@ match,

js = js.replace(JS_RMCOMMS, function (m, q) { return q ? m : ' ' })
js = js.replace(JS_RMCOMMS, function (m, _q) { return _q ? m : ' ' })

@@ -366,11 +374,11 @@ while (match = js.match(JS_ES6SIGN)) {

function skipBlock(str) {
function skipBlock (str) {
var
re = _regEx('([{}])|' + brackets.S_QBLOCKS, 'g'),
level = 1,
match
mm
while (level && (match = re.exec(str))) {
if (match[1])
match[1] === '{' ? ++level : --level
while (level && (mm = re.exec(str))) {
if (mm[1])
mm[1] === '{' ? ++level : --level
}

@@ -381,3 +389,3 @@ return level ? str.length : re.lastIndex

function _compileJS(js, opts, type, parserOpts, url) {
function _compileJS (js, opts, type, parserOpts, url) {
if (!js) return ''

@@ -394,3 +402,3 @@ if (!type) type = opts.type

// istanbul ignore next
function compileJS(js, opts, type, extra) {
function compileJS (js, opts, type, extra) {
if (typeof opts === 'string') {

@@ -410,5 +418,5 @@ extra = type

var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g')
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + S_STRINGS, 'g')
function scopedCSS(tag, style) {
function scopedCSS (tag, style) {
var scope = ':scope'

@@ -436,3 +444,3 @@

function _compileCSS(style, tag, type, opts) {
function _compileCSS (style, tag, type, opts) {
var scoped = (opts || (opts = {})).scoped

@@ -445,3 +453,3 @@

else if (parsers.css[type]) {
style = parsers.css[type](tag, style, opts.parserOpts, opts.url)
style = parsers.css[type](tag, style, opts.parserOpts || {}, opts.url)
}

@@ -465,3 +473,3 @@ else if (type !== 'css') {

// istanbul ignore next
function compileCSS(style, parser, opts) {
function compileCSS (style, parser, opts) {
if (typeof parser === 'object') {

@@ -471,3 +479,2 @@ opts = parser

}
else if (!opts) opts = {}
return _compileCSS(style, opts.tagName, parser, opts)

@@ -480,3 +487,3 @@ }

function getType(str) {
function getType (str) {

@@ -490,3 +497,3 @@ if (str) {

function getAttr(str, name) {
function getAttr (str, name) {

@@ -504,3 +511,3 @@ if (str) {

function getParserOptions(attrs) {
function getParserOptions (attrs) {
var opts = getAttr(attrs, 'options')

@@ -512,3 +519,3 @@

function getCode(code, opts, attrs, url) {
function getCode (code, opts, attrs, url) {
var type = getType(attrs),

@@ -520,5 +527,14 @@ parserOpts = getParserOptions(attrs)

function cssCode (code, opts, attrs, url, tag) {
var extraOpts = {
parserOpts: getParserOptions(attrs),
scoped: attrs && /\sscoped(\s|=|$)/i.test(attrs),
url: url
}
return _compileCSS(code, tag, getType(attrs) || opts.style, extraOpts)
}
var END_TAGS = /\/>\n|^<(?:\/[\w\-]+\s*|[\w\-]+(?:\s+(?:[-\w:\xA0-\xFF][\S\s]*?)?)?)>\n/
function splitBlocks(str) {
function splitBlocks (str) {
var k, m

@@ -535,3 +551,3 @@

}
k = str.lastIndexOf('<', k -1)
k = str.lastIndexOf('<', k - 1)
}

@@ -541,3 +557,3 @@ return ['', str]

function compileTemplate(html, url, lang, opts) {
function compileTemplate (html, url, lang, opts) {
var parser = parsers.html[lang]

@@ -554,7 +570,8 @@

/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@Q|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/
.source.replace('@Q', brackets.R_STRINGS.source), 'gim'),
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi,
SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi')
.source.replace('@Q', S_STRINGS), 'gim'),
SRC_TAGS = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/.source + '|' + S_STRINGS,
STYLES = _regEx(SRC_TAGS, 'gi'),
SCRIPT = _regEx(SRC_TAGS.replace(/style/g, 'script'), 'gi')
function compile(src, opts, url) {
function compile (src, opts, url) {
var

@@ -566,4 +583,6 @@ parts = [],

if (!url) url = ''
exclude = opts.exclude || false
function included(s) { return !(exclude && ~exclude.indexOf(s)) }
function included (s) { return !(exclude && ~exclude.indexOf(s)) }

@@ -586,3 +605,2 @@ var _bp = brackets.array(opts.brackets)

pcex._bp = _bp
pcex.__intflag = 1

@@ -596,3 +614,4 @@ tagName = tagName.toLowerCase()

if (body && (body = body.replace(HTML_COMMENT, '')) && /\S/.test(body)) {
if (body && (body = body.replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s })) && /\S/.test(body)) {

@@ -606,17 +625,15 @@ if (body2) {

body = body.replace(STYLE, included('css') ? function (_, _attrs, _style) {
var extraOpts = {
scoped: _attrs && /\sscoped(\s|=|$)/i.test(_attrs),
url: url,
parserOpts: getParserOptions(_attrs)
}
styles += (styles ? ' ' : '') +
_compileCSS(_style, tagName, getType(_attrs) || opts.style, extraOpts)
body = body.replace(STYLES, function (_m, _attrs, _style) {
if (_m[0] !== '<') return _m
if (included('css'))
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
return ''
} : '')
})
body = body.replace(SCRIPT, included('js') ? function (_, _attrs, _script) {
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
body = body.replace(SCRIPT, function (_m, _attrs, _script) {
if (_m[0] !== '<') return _m
if (included('js'))
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
return ''
} : '')
})

@@ -660,3 +677,3 @@ var blocks = splitBlocks(body.replace(TRIM_TRAIL, ''))

var version = 'v2.3.19'
var version = 'v2.3.20'

@@ -663,0 +680,0 @@ export default {

@@ -13,19 +13,21 @@

function _try(name, req) { //eslint-disable-line complexity
function _try (name, req) { //eslint-disable-line complexity
var parser
/*global window */
switch (name) {
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
}

@@ -41,6 +43,18 @@ parser = window[req]

function _req(name, req) {
function _req (name, req) {
return name in _mods ? _mods[name] : _try(name, req)
}
function extend (obj, props) {
if (props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
}
return obj
}
var _html = {

@@ -57,3 +71,3 @@ jade: function (html, opts, url) {

var _css = {
less: function(tag, css, opts, url) {
less: function (tag, css, opts, url) {
var less = _req('less'),

@@ -64,2 +78,4 @@ ret

sync: true,
syncImport: true,
filename: url,
compress: true

@@ -75,6 +91,9 @@ }, opts), function (err, result) {

var
stylus = _req('stylus'), nib = _req('nib')
xopts = extend({filename: url}, opts),
stylus = _req('stylus'),
nib = _req('nib')
/* istanbul ignore next: can't run both */
return nib ?
stylus(css).use(nib()).import('nib').render() : stylus.render(css)
stylus(css, xopts).use(nib()).import('nib').render() : stylus.render(css, xopts)
}

@@ -84,9 +103,9 @@ }

var _js = {
livescript: function (js, opts, url) {
livescript: function (js, opts) {
return _req('livescript').compile(js, extend({bare: true, header: false}, opts))
},
typescript: function (js, opts, url) {
typescript: function (js, opts) {
return _req('typescript')(js, opts).replace(/\r\n?/g, '\n')
},
es6: function (js, opts, url) {
es6: function (js, opts) {
return _req('es6').transform(js, extend({

@@ -97,10 +116,5 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false

babel: function (js, opts, url) {
// istanbul ignore next: url empty if comming from expression
return _req('babel').transform(js,
extend({
filename: url || ''
}, opts)
).code
return _req('babel').transform(js, extend({filename: url}, opts)).code
},
coffee: function (js, opts, url) {
coffee: function (js, opts) {
return _req('coffee').compile(js, extend({bare: true}, opts))

@@ -126,7 +140,7 @@ },

* Compiler for riot custom tags
* @version v2.3.19
* @version v2.3.20
*/
var compile = (function () {
function _regEx(str, opt) { return new RegExp(str, opt) }
function _regEx (str, opt) { return new RegExp(str, opt) }

@@ -146,6 +160,7 @@ var

HTML_ATTR = /\s*([-\w:\xA0-\xFF]+)\s*(?:=\s*('[^']+'|"[^"]+"|\S+))?/g,
SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i,
TRIM_TRAIL = /[ \t]+$/gm,
S_STRINGS = brackets.R_STRINGS.source
TRIM_TRAIL = /[ \t]+$/gm
function q(s) {
function q (s) {
return "'" + (s ? s

@@ -156,3 +171,3 @@ .replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') :

function mktag(name, html, css, attrs, js, pcex) {
function mktag (name, html, css, attrs, js, pcex) {
var

@@ -168,18 +183,7 @@ c = ', ',

function extend(obj, props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
return obj
}
function parseAttrs(str, pcex) {
function parseAttrs (str, pcex) {
var
list = [],
match,
k, v,
_bp = pcex._bp,
k, v, t, e,
DQ = '"'

@@ -204,22 +208,26 @@

if (k === 'type' && v.toLowerCase() === '"number"') {
v = DQ + _bp[0] + "'number'" + _bp[1] + DQ
if (k === 'type' && SPEC_TYPES.test(v)) {
t = v
}
else if (/\u0001\d/.test(v)) {
else {
if (/\u0001\d/.test(v)) {
if (BOOL_ATTRS.test(k)) {
k = '__' + k
if (k === 'value') e = 1
else if (BOOL_ATTRS.test(k)) k = '__' + k
else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
}
else if (~RIOT_ATTRS.indexOf(k)) {
k = 'riot-' + k
}
list.push(k + '=' + v)
}
list.push(k + '=' + v)
}
}
if (t) {
if (e) t = DQ + pcex._bp[0] + "'" + t.slice(1, -1) + "'" + pcex._bp[1] + DQ
list.push('type=' + t)
}
return list.join(' ')
}
function splitHtml(html, opts, pcex) {
function splitHtml (html, opts, pcex) {
var _bp = pcex._bp

@@ -229,3 +237,3 @@

var
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0,
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, //eslint-disable-line
list = brackets.split(html, 0, _bp),

@@ -251,3 +259,3 @@ expr

function restoreExpr(html, pcex) {
function restoreExpr (html, pcex) {
if (pcex.length) {

@@ -271,9 +279,8 @@ html = html

var
HTML_COMMENT = /<!--(?!>)[\S\s]*?-->/g,
HTML_COMMENT = _regEx(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_STRINGS, 'g'),
HTML_TAGS = /<([-\w]+)\s*([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)(\/?)>/g,
PRE_TAG = _regEx(
/<pre(?:\s+[^'">]+(?:(?:@Q)[^'">]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/
.source.replace('@Q', brackets.R_STRINGS.source), 'gi')
/<pre(?:\s+[^'">]+(?:(?:@Q)|[^>]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/.source.replace('@Q', S_STRINGS), 'gi')
function _compileHTML(html, opts, pcex) {
function _compileHTML (html, opts, pcex) {

@@ -295,7 +302,8 @@ html = splitHtml(html, opts, pcex)

var p = []
html = html.replace(PRE_TAG, function (q)
{ return p.push(q) && '\u0002' }).trim().replace(/\s+/g, ' ')
html = html.replace(PRE_TAG, function (_q) {
return p.push(_q) && '\u0002'
}).trim().replace(/\s+/g, ' ')
// istanbul ignore else
if (p.length)
html = html.replace(/\u0002/g, function (_) { return p.shift() })
html = html.replace(/\u0002/g, function () { return p.shift() })
}

@@ -312,3 +320,3 @@ else

// istanbul ignore next
function compileHTML(html, opts, pcex) {
function compileHTML (html, opts, pcex) {
if (Array.isArray(opts)) {

@@ -323,4 +331,4 @@ pcex = opts

if (!pcex.__intflag)
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '')
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s }).replace(TRIM_TRAIL, '')

@@ -336,3 +344,3 @@ if (!pcex._bp) pcex._bp = brackets.array(opts.brackets)

function riotjs(js) {
function riotjs (js) {
var

@@ -344,3 +352,3 @@ match,

js = js.replace(JS_RMCOMMS, function (m, q) { return q ? m : ' ' })
js = js.replace(JS_RMCOMMS, function (m, _q) { return _q ? m : ' ' })

@@ -364,11 +372,11 @@ while (match = js.match(JS_ES6SIGN)) {

function skipBlock(str) {
function skipBlock (str) {
var
re = _regEx('([{}])|' + brackets.S_QBLOCKS, 'g'),
level = 1,
match
mm
while (level && (match = re.exec(str))) {
if (match[1])
match[1] === '{' ? ++level : --level
while (level && (mm = re.exec(str))) {
if (mm[1])
mm[1] === '{' ? ++level : --level
}

@@ -379,3 +387,3 @@ return level ? str.length : re.lastIndex

function _compileJS(js, opts, type, parserOpts, url) {
function _compileJS (js, opts, type, parserOpts, url) {
if (!js) return ''

@@ -392,3 +400,3 @@ if (!type) type = opts.type

// istanbul ignore next
function compileJS(js, opts, type, extra) {
function compileJS (js, opts, type, extra) {
if (typeof opts === 'string') {

@@ -408,5 +416,5 @@ extra = type

var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g')
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + S_STRINGS, 'g')
function scopedCSS(tag, style) {
function scopedCSS (tag, style) {
var scope = ':scope'

@@ -434,3 +442,3 @@

function _compileCSS(style, tag, type, opts) {
function _compileCSS (style, tag, type, opts) {
var scoped = (opts || (opts = {})).scoped

@@ -443,3 +451,3 @@

else if (parsers.css[type]) {
style = parsers.css[type](tag, style, opts.parserOpts, opts.url)
style = parsers.css[type](tag, style, opts.parserOpts || {}, opts.url)
}

@@ -463,3 +471,3 @@ else if (type !== 'css') {

// istanbul ignore next
function compileCSS(style, parser, opts) {
function compileCSS (style, parser, opts) {
if (typeof parser === 'object') {

@@ -469,3 +477,2 @@ opts = parser

}
else if (!opts) opts = {}
return _compileCSS(style, opts.tagName, parser, opts)

@@ -478,3 +485,3 @@ }

function getType(str) {
function getType (str) {

@@ -488,3 +495,3 @@ if (str) {

function getAttr(str, name) {
function getAttr (str, name) {

@@ -502,3 +509,3 @@ if (str) {

function getParserOptions(attrs) {
function getParserOptions (attrs) {
var opts = getAttr(attrs, 'options')

@@ -510,3 +517,3 @@

function getCode(code, opts, attrs, url) {
function getCode (code, opts, attrs, url) {
var type = getType(attrs),

@@ -518,5 +525,14 @@ parserOpts = getParserOptions(attrs)

function cssCode (code, opts, attrs, url, tag) {
var extraOpts = {
parserOpts: getParserOptions(attrs),
scoped: attrs && /\sscoped(\s|=|$)/i.test(attrs),
url: url
}
return _compileCSS(code, tag, getType(attrs) || opts.style, extraOpts)
}
var END_TAGS = /\/>\n|^<(?:\/[\w\-]+\s*|[\w\-]+(?:\s+(?:[-\w:\xA0-\xFF][\S\s]*?)?)?)>\n/
function splitBlocks(str) {
function splitBlocks (str) {
var k, m

@@ -533,3 +549,3 @@

}
k = str.lastIndexOf('<', k -1)
k = str.lastIndexOf('<', k - 1)
}

@@ -539,3 +555,3 @@ return ['', str]

function compileTemplate(html, url, lang, opts) {
function compileTemplate (html, url, lang, opts) {
var parser = parsers.html[lang]

@@ -552,7 +568,8 @@

/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@Q|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/
.source.replace('@Q', brackets.R_STRINGS.source), 'gim'),
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi,
SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi')
.source.replace('@Q', S_STRINGS), 'gim'),
SRC_TAGS = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/.source + '|' + S_STRINGS,
STYLES = _regEx(SRC_TAGS, 'gi'),
SCRIPT = _regEx(SRC_TAGS.replace(/style/g, 'script'), 'gi')
function compile(src, opts, url) {
function compile (src, opts, url) {
var

@@ -564,4 +581,6 @@ parts = [],

if (!url) url = ''
exclude = opts.exclude || false
function included(s) { return !(exclude && ~exclude.indexOf(s)) }
function included (s) { return !(exclude && ~exclude.indexOf(s)) }

@@ -584,3 +603,2 @@ var _bp = brackets.array(opts.brackets)

pcex._bp = _bp
pcex.__intflag = 1

@@ -594,3 +612,4 @@ tagName = tagName.toLowerCase()

if (body && (body = body.replace(HTML_COMMENT, '')) && /\S/.test(body)) {
if (body && (body = body.replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s })) && /\S/.test(body)) {

@@ -604,17 +623,15 @@ if (body2) {

body = body.replace(STYLE, included('css') ? function (_, _attrs, _style) {
var extraOpts = {
scoped: _attrs && /\sscoped(\s|=|$)/i.test(_attrs),
url: url,
parserOpts: getParserOptions(_attrs)
}
styles += (styles ? ' ' : '') +
_compileCSS(_style, tagName, getType(_attrs) || opts.style, extraOpts)
body = body.replace(STYLES, function (_m, _attrs, _style) {
if (_m[0] !== '<') return _m
if (included('css'))
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
return ''
} : '')
})
body = body.replace(SCRIPT, included('js') ? function (_, _attrs, _script) {
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
body = body.replace(SCRIPT, function (_m, _attrs, _script) {
if (_m[0] !== '<') return _m
if (included('js'))
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
return ''
} : '')
})

@@ -663,3 +680,3 @@ var blocks = splitBlocks(body.replace(TRIM_TRAIL, ''))

js: compileJS,
version: 'v2.3.19'
version: 'v2.3.20'
}

@@ -666,0 +683,0 @@ return compile

Boolean attributes in riot 2.3
==============================
From HTML5 - A vocabulary and associated APIs for HTML and XHTML - W3C Recommendation 28 October 2014:
From _HTML5 - A vocabulary and associated APIs for HTML and XHTML_ - W3C Recommendation, 28 October 2014:

@@ -15,3 +15,3 @@ > 2.4.2 Boolean attributes

When the expression is trueish, riot sets the boolean attribute values to attribute's name:
When the expression is trueish, riot sets the boolean attribute value to the attribute's name:
```html

@@ -38,3 +38,3 @@ <my-tag disabled={ 'yes' }></my-tag>

* disabled - used in almost all form elements
* ismap - `<img>` - for `<img>` elements descendant of an `<a>` element
* ismap - for `<img>` elements descendant of an `<a>` element with href
* noresize - `<frame>` - deprecated in html5

@@ -49,3 +49,3 @@ * noshade - `<hr>` - deprecated in html5

**Recognized html5 attributes**
...and these html5 attributes:
* autofocus

@@ -67,4 +67,4 @@ * autoplay - `<audio>`/`<video>`

**WARNING:** Please don't use expressions in the `loop` attribute within `<img>` tags.
In images, `loop` is not a boolean attribute. This will fix soon.
**Warning:** Please don't use expressions in the `loop` attribute for `<img>` tags.
In images, `loop` is not a boolean attribute. ~~This will fix soon.~~

@@ -76,14 +76,14 @@ Tested with [the w3c Validator](https://validator.w3.org/nu)

This unused or non-boolean attributes, recognized in previous versions, are removed in v2.3.0:
The following unused or non-boolean attributes, recognized in previous versions, are removed in v2.3.0:
* async - `<script>` - riot does not handle this
* async - `<script>` - riot does not support async scripts in custom tags
* declare - `<object>` - unuseful in main browsers
* defaultChecked - it is a property, not attribute
* defer - `<script>` - riot does not handle this, only IE8+ honors this attribute
* defaultChecked - it is a property, not an attribute
* defer - `<script>` - riot does not handle this, only IE8/9 honors this attribute
* draggable - not boolean, this is an enumerated attribute: true, false, auto
* inert - this proposed html5 attribute was [dropped](https://html5.org/r/8536) from the spec
* enabled - not in the HTML spec
* indeterminate - boolean attr, but can't be set with markup
* nohref - `<area>` - deprecated, same effect as NOT including a `href` attribute
* pauseonexit - `<track>` - not for markup, or its too complex
* indeterminate - this attribute can't be set with markup
* nohref - `<area>` - deprecated, same effect as _not_ including a `href` attribute
* pauseonexit - `<track>` - not for markup, it is too complex
* spellcheck - not boolean, this is an enumerated attribute: true, false

@@ -96,4 +96,4 @@ * translate - not boolean, this is an enumerated attribute: yes, no

The following attributes give error when parsed on browser with `{ exrp_value }`.
`d` describes the SVG `<path>`, Chrome gives error if the value has invalid format.
The following attributes give error when parsed on browsers with `{ exrp_value }`.
`d` describes the SVG `<path>`, Chrome gives error if the value has an invalid format.

@@ -100,0 +100,0 @@ See: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d

# Compiler Guide (complement, WIP)
Please note the compiler generates code for call to the internal function `riot.tag2`, which is a simplified version of `riot.tag`. Since the type and order of the parameters of `riot.tag2` can change in any moment, we are using the `riot.tag` here for illustration purposes.
## Indentation

@@ -10,2 +12,4 @@

Inside `<pre>` tags, linefeeds are preserved.
Example:

@@ -26,4 +30,4 @@ ```html

// This JS comment is at column 0, out of the tag
riot.tag2('treeitem', '<pre>one\n two\n</pre> <treeitem> </treeitem>', '', '', function(opts) {
click(e) {}
riot.tag('treeitem', '<pre>one\n two\n</pre> <treeitem> </treeitem>', function(opts) {
this.click = function(e) {}.bind(this)
}); // the closing tag is indented by 2 spaces, this comment must be JS

@@ -63,4 +67,3 @@ ```

This may seem counterintuitive, but maintains backward compatibility with the behavior of previous versions.
See [The untagged JS block](the-untagged-js-block) for details.
This may seem counterintuitive, but complies with the riot specification for [untagged JavaScript blocks](the-untagged-javascript-block).

@@ -87,3 +90,3 @@

* spacing between name and value is removed
* the value is enclosed in double quotes.
* the value is enclosed in double quotes

@@ -113,6 +116,6 @@ Content of `style` blocks and expressions are trimmed and newlines converted to compacted spaces.

```js
riot.tag2('my-tag', '<p></p>', 'p { display: none; }', 'style=" top:0; left:0" expr="{{ foo:"bar" }}"', function(opts) {
riot.tag('my-tag', '<p></p>', 'p { display: none; }', 'style=" top:0; left:0" expr="{{ foo:"bar" }}"', function(opts) {
this.click = function(e)
{}.bind(this)
}, '{ }');
});
```

@@ -138,6 +141,4 @@

```js
// This JS comment is at column 0, out of the tag
riot.tag2('my-tag', '', '', 'non-expr="\\{ empty:\\{} }" expr="{empty:{}}"', function(opts) {
click(e) {}
}); // the closing tag is indented by 2 spaces, this comment must be JS
riot.tag('my-tag', '', '', 'non-expr="\\{ empty:\\{} }" expr="{empty:{}}"', function(opts) {
});
```

@@ -192,3 +193,3 @@ at runtime, the backslashes in `non-expr` will be removed. If you need output a literal backslash in front of brackets, you must use `\\{` to generate `\\\\{`.

Be aware that the `html` and `js` properties can contain raw line endings --i.e. unescaped `\r` and/or `\n`.
Be aware that the `html` and `js` properties can contain raw line endings --i.e. unescaped `\r` and `\n`.

@@ -198,3 +199,3 @@

In addition to the `type` attribute, `script` and `style` tags can include additional configuration at tag level through the `options` attribute.
In addition to the `type` attribute, the `script` and `style` tags can include additional configuration at tag level through the `options` attribute.

@@ -217,3 +218,3 @@ This attribute is a [JSON](http://json.org/) object that specifies options for the JS or CSS parser.

**NOTE:** The `options` attribute must comply with the [JSON specs](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf), i.e. with double-quoted property names and strings, in a format suitable for `JSON.parse`
**Note:** The `options` attribute must comply with the [JSON specs](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf), i.e. with double-quoted property names and strings, in a format suitable for `JSON.parse`

@@ -228,14 +229,11 @@

The first action taken by the compiler is send the received source to any html parser.
After that, it normalizes line endings to `\n` and removes _html_ comments.
Once prepared the source, searches the tags, separate its parts (closing/opening tag, root
attributes, and content). In the content, one by one, removes the `style` blocks and sends its
content to the CSS parser. Next, it does the same for the `script` tags.
This is done in the entire content.
After that, the compiler normalizes line endings to `\n` and removes _html_ comments.
Once prepared the source, searches the tags, separate its parts (closing/opening tag, root attributes, and content). In the content, one by one, removes the `style` blocks and sends its content to the CSS parser. Next, it does the same for the `script` tags.
This is done in the entire tag content.
In the remaining content, looks for the last html tag which ends a line.
In the remaining content, looks for the last html tag which _ends a line_.
If found, this closing tag signals the end of the html markup and the beginning of the JavaScript code.
If not found, all remaining is considered JavaScript.
So, you can put html comments, `style`, and `script` blocks, anywhere inside the tag.
The only restriction is that the untagged JavaScript code must finish the content and you can't use JavaScript comments out of this block.
So, although not a good idea, you can put html comments, `style`, and `script` blocks, anywhere inside the tag; the only restriction is that the untagged JavaScript block must follow the remaining html content and you can't use JavaScript comments out of this block.

@@ -246,2 +244,3 @@ ### Multiple JavaScript Blocks

Once parsed, all blocks will be merged by the compiler.
The resulting block is enclosed in a function, executed at mount time in the tag context, this is why sometimes is referred to as the tag "constructor".

@@ -251,8 +250,9 @@ ### Loading JavaScript from the File System (v2.3.13)

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.
It can be combined with the `charset` attribute. `charset` defaults to `utf8` and the JavaScript type defaults to the `type` option specified in the options passed to the compiler.
**Note**
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()`).
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"`.
The encoding is specified by the `charset` attribute. It defaults to `utf8`.
Example:

@@ -266,12 +266,14 @@ ```js

So, if we have a mytag.tag and a js/data.js file...
So, if you have a js/data.js loaded by a mytag.tag file...
```js
// ./js/data.js file
this.title = "my title"
// js/data.js file
const APP_NAME = 'My App'
```
```html
// ./mytag.tag file
// mytag.tag file
<my-tag>
<p>{ title }</p>
<h1>{ title }</h1>
<script src="js/data.js" type="es6"></script>
this.title = APP_NAME
</my-tag>

@@ -283,6 +285,7 @@ ```

<my-tag>
<p>{ title }</p>
<h1>{ title }</h1>
<script type="es6">
this.title = "my title"
const APP_NAME = 'My App'
</script>
this.title = APP_NAME
</my-tag>

@@ -303,3 +306,3 @@ ```

#### html(source, compilerOptions, compiledExpressions)
#### html(source, compilerOptions, expressions)

@@ -310,6 +313,8 @@ | parameter | type | description

| compilerOptions | object | optional. Used properties: `brackets`, `withespace`, `compact`, `type`, `expr`
| compiledExpressions | Array | optional. See below.
| expressions | Array | optional. See below.
`compiledExpressions` is interesting, on return it holds, in order of appearance, trimmed and without brackets, the expressions found in the html. If you set `type` and `expr` in the `compilerOptions` parameter, the expressions will be compiled.
The `expressions` parameter is interesting, on return it holds, in order of appearance, trimmed and without brackets, the expressions found in the html. If you set `type` and `expr` in the `compilerOptions` parameter, the expressions will be compiled.
**Note:** `expressions` is exposed for debugging purposes, but not dependent on it, its format may be altered in future versions.
#### css(source, parserName, extraOptions)

@@ -320,3 +325,3 @@

| source | string | styles
| parserName | string/function | optional, can be omited. If string, must be one of `parsers.js`
| parserName | string | optional, can be omited. Must be one of `parsers.js`
| extraOptions | Object | optional, can be omited. Used properties: `tagName`, `parserOpts`, `url`, and `scoped`

@@ -357,7 +362,6 @@

```
Since the default JS parser does not make use of the extra options, this is the same:
Since the default JS parser does not make use of the extra options, this is equivalent:
```js
var js = compiler.js(source)
```
`compilerOptions` will be removed in a future version.
The `compilerOptions` parameter will be removed in a future version.
/* riot-compiler WIP, @license MIT, (c) 2015 Muut Inc. + contributors */
'use strict' // eslint-disable-line
'use strict'

@@ -4,0 +4,0 @@ //#include_once parsers

@@ -8,2 +8,5 @@ /**

*/
//#if 0 // only in the unprocessed source
/*eslint no-unused-vars: [2, {args: "after-used", varsIgnorePattern: "^brackets$"}] */
//#endif

@@ -31,4 +34,4 @@ //#set $_RIX_TEST = 4

// `MLCOMMS` - Multiline comments in almost all their forms<br>
// `STRINGS` - Quoted strings. Don't care about inner eols<br>
// `MLCOMMS` - Multiline comments in almost all their forms
// `STRINGS` - Quoted strings. Don't care about inner eols

@@ -82,3 +85,3 @@ MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g,

*/
function _rewrite(re, bp) {
function _rewrite (re, bp) {
return RegExp(

@@ -109,3 +112,3 @@ re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''

*/
_brackets.split = function split(str, tmpl, _bp) {
_brackets.split = function split (str, tmpl, _bp) {

@@ -174,7 +177,7 @@ // Template text is easy: closing brackets are ignored, all we have to do is find

// tmpl, from the HTML part too.
function unescapeStr(str) {
function unescapeStr (s) {
if (isexpr)
parts.push(str && str.replace(_bp[$_RIX_ESC], '$1'))
parts.push(s && s.replace(_bp[$_RIX_ESC], '$1'))
else
parts.push(str)
parts.push(s)
}

@@ -184,3 +187,3 @@

// Skips strings, regexes, and other inner blocks.
function skipBraces(ch, pos) {
function skipBraces (ch, pos) {
var

@@ -208,3 +211,3 @@ match,

*/
_brackets.array = function array(pair) {
_brackets.array = function array (pair) {

@@ -211,0 +214,0 @@ if (!pair || pair === DEFAULT) return _pairs

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

//#if 0 // only in the unprocessed source
/*eslint no-unused-vars: [2, {args: "after-used", varsIgnorePattern: "^compile*"}] */
/*global brackets, parsers */
//#endif
function _regEx(str, opt) { return new RegExp(str, opt) }
function _regEx (str, opt) { return new RegExp(str, opt) }

@@ -27,5 +31,6 @@ // Looks like, in [jsperf tests](http://jsperf.com/riot-regexp-test-vs-array-indexof)

HTML_ATTR = /\s*([-\w:\xA0-\xFF]+)\s*(?:=\s*('[^']+'|"[^"]+"|\S+))?/g,
SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i,
TRIM_TRAIL = /[ \t]+$/gm,
S_STRINGS = brackets.R_STRINGS.source
TRIM_TRAIL = /[ \t]+$/gm
//#if NODE

@@ -36,5 +41,2 @@ var path = require('path')

//#set $_RIX_TEST = 4
//#set $_RIX_ESC = 5
//#set $_RIX_OPEN = 6
//#set $_RIX_CLOSE = 7
//#set $_RIX_PAIR = 8

@@ -44,5 +46,2 @@ //#ifndef $_RIX_TEST

$_RIX_TEST = 4, // DONT'T FORGET SYNC THE #set BLOCK!!!
$_RIX_ESC = 5,
$_RIX_OPEN = 6,
$_RIX_CLOSE = 7,
$_RIX_PAIR = 8

@@ -52,3 +51,3 @@ //#endif

// Escape backslashes and inner single quotes, and enclose s in single quotes
function q(s) {
function q (s) {
return "'" + (s ? s

@@ -60,3 +59,3 @@ .replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') :

// Generates the `riot.tag2` call with the processed parts.
function mktag(name, html, css, attrs, js, pcex) {
function mktag (name, html, css, attrs, js, pcex) {
var

@@ -74,20 +73,2 @@ c = ', ',

/**
* Merge two javascript object extending the properties of the first one with
* the second
*
* @param {object} obj - source object
* @param {object} props - extra properties
* @returns {object} source object containing the new properties
*/
function extend(obj, props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
return obj
}
/**
* Parses and format attributes.

@@ -99,8 +80,7 @@ *

*/
function parseAttrs(str, pcex) {
function parseAttrs (str, pcex) {
var
list = [],
match,
k, v,
_bp = pcex._bp,
k, v, t, e,
DQ = '"'

@@ -122,3 +102,2 @@

else {
// attribute values must be enclosed in double quotes

@@ -128,19 +107,22 @@ if (v[0] !== DQ)

if (k === 'type' && v.toLowerCase() === '"number"') {
v = DQ + _bp[0] + "'number'" + _bp[1] + DQ // fix #827 by @rsbondi
if (k === 'type' && SPEC_TYPES.test(v)) {
t = v
}
else if (/\u0001\d/.test(v)) {
// renames special attributes with expressiones in their value.
if (BOOL_ATTRS.test(k)) {
k = '__' + k
else {
if (/\u0001\d/.test(v)) {
// renames special attributes with expressiones in their value.
if (k === 'value') e = 1
else if (BOOL_ATTRS.test(k)) k = '__' + k
else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
}
else if (~RIOT_ATTRS.indexOf(k)) {
k = 'riot-' + k
}
// join the key-value pair, with no spaces between the parts
list.push(k + '=' + v)
}
// join the key-value pair, with no spaces between the parts
list.push(k + '=' + v)
}
}
// update() will evaluate `type` after the value, avoiding warnings
if (t) {
if (e) t = DQ + pcex._bp[0] + "'" + t.slice(1, -1) + "'" + pcex._bp[1] + DQ
list.push('type=' + t)
}
return list.join(' ') // returns the attribute list

@@ -151,3 +133,3 @@ }

// through the parser, except those beginning with `{^`.
function splitHtml(html, opts, pcex) {
function splitHtml (html, opts, pcex) {
var _bp = pcex._bp

@@ -158,3 +140,3 @@

var
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0,
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, //eslint-disable-line
list = brackets.split(html, 0, _bp),

@@ -181,3 +163,3 @@ expr

// Restores expressions hidden by splitHtml and escape literal internal brackets
function restoreExpr(html, pcex) {
function restoreExpr (html, pcex) {
if (pcex.length) {

@@ -206,9 +188,8 @@ html = html

var
HTML_COMMENT = /<!--(?!>)[\S\s]*?-->/g,
HTML_COMMENT = _regEx(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_STRINGS, 'g'),
HTML_TAGS = /<([-\w]+)\s*([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)(\/?)>/g,
PRE_TAG = _regEx(
/<pre(?:\s+[^'">]+(?:(?:@Q)[^'">]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/
.source.replace('@Q', brackets.R_STRINGS.source), 'gi')
/<pre(?:\s+[^'">]+(?:(?:@Q)|[^>]*)*|\s*)?>([\S\s]*?)<\/pre\s*>/.source.replace('@Q', S_STRINGS), 'gi')
function _compileHTML(html, opts, pcex) {
function _compileHTML (html, opts, pcex) {

@@ -232,7 +213,8 @@ // separate the expressions, then parse the tags and their attributes

var p = []
html = html.replace(PRE_TAG, function (q)
{ return p.push(q) && '\u0002' }).trim().replace(/\s+/g, ' ')
html = html.replace(PRE_TAG, function (_q) {
return p.push(_q) && '\u0002'
}).trim().replace(/\s+/g, ' ')
// istanbul ignore else
if (p.length)
html = html.replace(/\u0002/g, function (_) { return p.shift() })
html = html.replace(/\u0002/g, function () { return p.shift() })
}

@@ -259,3 +241,3 @@ else

// istanbul ignore next
function compileHTML(html, opts, pcex) {
function compileHTML (html, opts, pcex) {
if (Array.isArray(opts)) {

@@ -270,4 +252,4 @@ pcex = opts

if (!pcex.__intflag)
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '')
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s }).replace(TRIM_TRAIL, '')

@@ -291,3 +273,3 @@ // `_bp` is undefined when `compileHTML` is not called by compile

// Default parser for JavaScript code
function riotjs(js) {
function riotjs (js) {
var

@@ -300,3 +282,3 @@ match,

// remove comments
js = js.replace(JS_RMCOMMS, function (m, q) { return q ? m : ' ' })
js = js.replace(JS_RMCOMMS, function (m, _q) { return _q ? m : ' ' })

@@ -326,11 +308,11 @@ // $1: indentation,

// Inner helper - find the position following the closing bracket for the current block
function skipBlock(str) {
function skipBlock (str) {
var
re = _regEx('([{}])|' + brackets.S_QBLOCKS, 'g'),
level = 1,
match
mm
while (level && (match = re.exec(str))) {
if (match[1])
match[1] === '{' ? ++level : --level
while (level && (mm = re.exec(str))) {
if (mm[1])
mm[1] === '{' ? ++level : --level
}

@@ -341,3 +323,3 @@ return level ? str.length : re.lastIndex

function _compileJS(js, opts, type, parserOpts, url) {
function _compileJS (js, opts, type, parserOpts, url) {
if (!js) return ''

@@ -363,3 +345,3 @@ if (!type) type = opts.type

// istanbul ignore next
function compileJS(js, opts, type, extra) {
function compileJS (js, opts, type, extra) {
if (typeof opts === 'string') {

@@ -385,7 +367,7 @@ extra = type

// Prepare regex to match CSS selectors, excluding those beginning with '@'.
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g')
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + S_STRINGS, 'g')
// Parses styles enclosed in a "scoped" tag (`scoped` is deprecated in HTML5).
// The "style" string is received without comments or surrounding spaces.
function scopedCSS(tag, style) {
function scopedCSS (tag, style) {
var scope = ':scope'

@@ -416,3 +398,3 @@

function _compileCSS(style, tag, type, opts) {
function _compileCSS (style, tag, type, opts) {
var scoped = (opts || (opts = {})).scoped

@@ -425,3 +407,3 @@

else if (parsers.css[type]) {
style = parsers.css[type](tag, style, opts.parserOpts, opts.url)
style = parsers.css[type](tag, style, opts.parserOpts || {}, opts.url)
}

@@ -456,3 +438,3 @@ else if (type !== 'css') {

// istanbul ignore next
function compileCSS(style, parser, opts) {
function compileCSS (style, parser, opts) {
if (typeof parser === 'object') {

@@ -462,3 +444,2 @@ opts = parser

}
else if (!opts) opts = {}
return _compileCSS(style, opts.tagName, parser, opts)

@@ -476,3 +457,3 @@ }

// Returns the value of the 'type' attribute, with the prefix "text/" removed.
function getType(str) {
function getType (str) {

@@ -487,3 +468,3 @@ if (str) {

// Returns the value of any attribute, or the empty string for missing attribute.
function getAttr(str, name) {
function getAttr (str, name) {

@@ -502,3 +483,3 @@ if (str) {

// get the parser options from the options attribute
function getParserOptions(attrs) {
function getParserOptions (attrs) {
var opts = getAttr(attrs, 'options')

@@ -512,3 +493,3 @@ // convert the string into a valid js object

// The CLI version can read code from the file system (experimental)
function getCode(code, opts, attrs, url) {
function getCode (code, opts, attrs, url) {
var type = getType(attrs),

@@ -532,2 +513,11 @@ parserOpts = getParserOptions(attrs)

function cssCode (code, opts, attrs, url, tag) {
var extraOpts = {
parserOpts: getParserOptions(attrs),
scoped: attrs && /\sscoped(\s|=|$)/i.test(attrs),
url: url
}
return _compileCSS(code, tag, getType(attrs) || opts.style, extraOpts)
}
// Matches HTML tag ending a line. This regex still can be fooled by code as:

@@ -540,3 +530,3 @@ // ```js

function splitBlocks(str) {
function splitBlocks (str) {
var k, m

@@ -553,3 +543,3 @@

}
k = str.lastIndexOf('<', k -1)
k = str.lastIndexOf('<', k - 1)
}

@@ -568,3 +558,3 @@ return ['', str]

*/
function compileTemplate(html, url, lang, opts) {
function compileTemplate (html, url, lang, opts) {
var parser = parsers.html[lang]

@@ -580,3 +570,3 @@

CUST_TAG regex don't allow unquoted expressions containing the `>` operator.
STYLE and SCRIPT disallows the operator `>` at all.
STYLES and SCRIPT disallows the operator `>` at all.

@@ -592,5 +582,6 @@ The beta.4 CUST_TAG regex is fast, with RegexBuddy I get 76 steps and 14 backtracks on

/^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:@Q|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/
.source.replace('@Q', brackets.R_STRINGS.source), 'gim'),
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi,
SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi')
.source.replace('@Q', S_STRINGS), 'gim'),
SRC_TAGS = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/.source + '|' + S_STRINGS,
STYLES = _regEx(SRC_TAGS, 'gi'),
SCRIPT = _regEx(SRC_TAGS.replace(/style/g, 'script'), 'gi')

@@ -610,3 +601,3 @@ /**

*/
function compile(src, opts, url) {
function compile (src, opts, url) {
var

@@ -622,7 +613,9 @@ parts = [],

// their transpiler setup
url = url || process.cwd() + '/.' // getCode expect a file
if (!url) url = process.cwd() + '/.' // getCode expect a file
//#else
if (!url) url = ''
//#endif
exclude = opts.exclude || false
function included(s) { return !(exclude && ~exclude.indexOf(s)) }
function included (s) { return !(exclude && ~exclude.indexOf(s)) }

@@ -650,3 +643,2 @@ // get a static brackets array for use on the entire source

pcex._bp = _bp // local copy, in preparation for async compilation
pcex.__intflag = 1

@@ -662,3 +654,4 @@ tagName = tagName.toLowerCase()

// remove comments and trim trailing whitespace
if (body && (body = body.replace(HTML_COMMENT, '')) && /\S/.test(body)) {
if (body && (body = body.replace(HTML_COMMENT,
function (s) { return s[0] === '<' ? '' : s })) && /\S/.test(body)) {

@@ -674,19 +667,17 @@ if (body2) {

body = body.replace(STYLE, included('css') ? function (_, _attrs, _style) {
var extraOpts = {
scoped: _attrs && /\sscoped(\s|=|$)/i.test(_attrs),
url: url,
parserOpts: getParserOptions(_attrs)
}
styles += (styles ? ' ' : '') +
_compileCSS(_style, tagName, getType(_attrs) || opts.style, extraOpts)
body = body.replace(STYLES, function (_m, _attrs, _style) {
if (_m[0] !== '<') return _m
if (included('css'))
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
return ''
} : '')
})
// now the script blocks
body = body.replace(SCRIPT, included('js') ? function (_, _attrs, _script) {
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
body = body.replace(SCRIPT, function (_m, _attrs, _script) {
if (_m[0] !== '<') return _m
if (included('js'))
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url)
return ''
} : '')
})

@@ -693,0 +684,0 @@ // separate the untagged javascript block from the html markup

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

//#if 0
/*eslint no-unused-vars: [2, {args: "after-used", varsIgnorePattern: "^parsers*"}] */
//#endif
/**

@@ -13,2 +16,4 @@ * @module parsers

//#if NODE
var path = require('path')
var _modnames = { // for name-module convertion

@@ -31,3 +36,3 @@ es6: 'babel',

*/
function _modname(name) {
function _modname (name) {
return _modnames[name] || name

@@ -45,7 +50,7 @@ }

*/
function _try(name, req) { //eslint-disable-line complexity
function _try (name, req) { //eslint-disable-line complexity
var parser
//#if NODE
function fn(r) {
function fn (r) {
try {

@@ -66,17 +71,18 @@ _mods[name] = require(r)

//#else
/*global window */
switch (name) {
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
case 'coffee':
req = 'CoffeeScript'
break
case 'es6':
case 'babel':
req = 'babel'
break
case 'none':
case 'javascript':
return _mods.none
default:
if (!req) req = name
break
}

@@ -93,8 +99,34 @@ parser = window[req]

// Returns a parser instance, null if the parser is not found.
// Public through the parsers._get function.
function _req(name, req) {
/**
* 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 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)
}
/**
* Merge two javascript object extending the properties of the first one with
* the second.
*
* @param {object} obj - source object
* @param {object} props - extra properties
* @returns {object} source object containing the new properties
*/
function extend (obj, props) {
if (props) {
for (var prop in props) {
/* istanbul ignore next */
if (props.hasOwnProperty(prop)) {
obj[prop] = props[prop]
}
}
}
return obj
}
//// The parsers object --

@@ -114,3 +146,3 @@

//#if NODE
sass: function(tag, css, opts, url) { // there's no standard sass for browsers
sass: function (tag, css, opts, url) { // there's no standard sass for browsers
var sass = _req('sass')

@@ -120,2 +152,3 @@

data: css,
includePaths: [path.dirname(url)],
indentedSyntax: true,

@@ -126,3 +159,3 @@ omitSourceMapUrl: true,

},
scss: function(tag, css, opts, url) { // there's no standard sass for browsers
scss: function (tag, css, opts, url) { // there's no standard sass for browsers
var scss = _req('scss')

@@ -132,2 +165,3 @@

data: css,
includePaths: [path.dirname(url)],
indentedSyntax: false,

@@ -139,3 +173,3 @@ omitSourceMapUrl: true,

//#endif
less: function(tag, css, opts, url) {
less: function (tag, css, opts, url) {
var less = _req('less'),

@@ -146,2 +180,4 @@ ret

sync: true,
syncImport: true,
filename: url,
compress: true

@@ -157,6 +193,9 @@ }, opts), function (err, result) {

var
stylus = _req('stylus'), nib = _req('nib') // optional nib support
xopts = extend({filename: url}, opts),
stylus = _req('stylus'),
nib = _req('nib') // optional nib support
/* istanbul ignore next: can't run both */
return nib ?
stylus(css).use(nib()).import('nib').render() : stylus.render(css)
stylus(css, xopts).use(nib()).import('nib').render() : stylus.render(css, xopts)
}

@@ -166,9 +205,9 @@ }

var _js = {
livescript: function (js, opts, url) {
livescript: function (js, opts) {
return _req('livescript').compile(js, extend({bare: true, header: false}, opts))
},
typescript: function (js, opts, url) {
typescript: function (js, opts) {
return _req('typescript')(js, opts).replace(/\r\n?/g, '\n')
},
es6: function (js, opts, url) {
es6: function (js, opts) {
return _req('es6').transform(js, extend({

@@ -179,10 +218,5 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false

babel: function (js, opts, url) {
// istanbul ignore next: url empty if comming from expression
return _req('babel').transform(js,
extend({
filename: url || ''
}, opts)
).code
return _req('babel').transform(js, extend({filename: url}, opts)).code
},
coffee: function (js, opts, url) {
coffee: function (js, opts) {
return _req('coffee').compile(js, extend({bare: true}, opts))

@@ -189,0 +223,0 @@ },

{
"name": "riot-compiler",
"version": "2.3.19",
"version": "2.3.20",
"description": "Compiler for riot .tag files",

@@ -19,3 +19,3 @@ "main": "dist/compiler.js",

"test": "make test",
"prepublish": "make build && node bump"
"prepublish": "make build && ./node_modules/.bin/riot-bump"
},

@@ -37,4 +37,5 @@ "repository": {

"istanbul": "^0.4.1",
"jspreproc": "^0.2.5",
"mocha": "^2.3.4"
"jspreproc": "^0.2.7",
"mocha": "^2.3.4",
"riot-bump": "^1.0.0"
},

@@ -41,0 +42,0 @@ "author": "Muut, Inc. and other contributors",

@@ -29,6 +29,6 @@ [![Build Status][travis-image]][travis-url]

Due to changes in the babel API, from our v2.3.0-beta.7 we are separating the babel support in the following types:
Due to changes in the babel API, from our v2.3.0 we are separating the babel support in the following types:
* es6 - For `babel` and `babel-core` v5.8.x and below
* babel - For `babel-core` v6.x - You must `npm install babel-preset-es2015` too, for this to work.
* babel - For `babel-core` v6.x - You must `npm install babel-preset-es2015-riot` too, for this to work.

@@ -35,0 +35,0 @@

/*
Performance test for the compiler
*/
'use strict' // eslint-disable-line strict, global-strict
/*eslint no-console: 0 */
'use strict' // eslint-disable-line

@@ -9,5 +10,2 @@ var

compiler22 = require('./v223/compiler223.js').compile,
tmpl23 = require('riot-tmpl').tmpl,
tmpl22 = require('./v223/compiler223.js').tmpl,
assert = require('assert'),
path = require('path'),

@@ -18,4 +16,3 @@ fs = require('fs')

basedir = path.join(__dirname, 'specs', 'fixtures'),
tags = ['box', 'empty', 'input-last', 'mixed-js', 'same', 'scoped', 'timetable', 'treeview', 'oneline'],
data = { num: 1, str: 'string', date: new Date(), bool: true, item: null }
tags = ['box', 'empty', 'input-last', 'mixed-js', 'same', 'scoped', 'timetable', 'treeview', 'oneline']

@@ -40,3 +37,3 @@ var files = tags.map(function (f) {

console.log('Testing each compiler with %d files, %dx%d iterations (%d total)',
tags.length, TMAX-2, LOOP, tags.length * (TMAX-2) * LOOP)
tags.length, TMAX - 2, LOOP, tags.length * (TMAX - 2) * LOOP)

@@ -71,3 +68,3 @@ console.log('Running the compiler v2.2.4 ...')

function test(compiler, times, ogc) {
function test (compiler, times, ogc) {
var gcm

@@ -81,3 +78,3 @@ global.gc()

tt = new Array(TMAX),
s, i, j
i, j

@@ -87,3 +84,3 @@ for (i = 0; i < tt.length; ++i) {

for (j = 0; j < LOOP; ++j) {
s = compiler(text)
compiler(text)
}

@@ -102,18 +99,18 @@ tt[i] = Date.now() - tt[i]

function numsort(a, b) {
function numsort (a, b) {
return a - b
}
function numsum(a, b) {
function numsum (a, b) {
return a + b
}
function replicate(s, n) {
function replicate (s, n) {
return n < 1 ? '' : (new Array(n + 1)).join(s)
}
function padr(s, n) {
function padr (s, n) {
s = '' + s
return s + replicate(' ', n - s.length)
}
function padl(s, n) {
function padl (s, n) {
s = '' + s
return replicate(' ', n - s.length) + s
}
var isNode = typeof window === 'undefined'
describe('Compiler Tests', function() {
describe('Compiler Tests', function () {
expect = require('expect.js')

@@ -5,0 +5,0 @@ compiler = require('../dist/compiler.js')

//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}">xyz\n cc\n ss</pre>', '', '', function(opts) {
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) {
}, '{ }');

@@ -10,1 +10,2 @@

}.bind(this)
var str = '/* str */'

@@ -14,4 +14,5 @@ //THIS IS A LINE COMMENT

}
var str = '/* str */'
/*COMMENT
click (e) {}
*/

@@ -0,13 +1,15 @@

/*eslint-env mocha */
/*global compiler, expect */
describe('Compile HTML', function() {
describe('Compile HTML', function () {
function render(str, opts) {
function render (str, opts) {
return compiler.html(str, opts || {})
}
function testStr(str1, str2, opts) {
function testStr (str1, str2, opts) {
expect(render(str1, opts)).to.be(str2)
}
it('compiles void tag into separated: <x/> -> <x></x>', function() {
it('compiles void tag into separated: <x/> -> <x></x>', function () {
testStr('<p/>', '<p></p>')

@@ -18,3 +20,3 @@ testStr('<a><b/></a>', '<a><b></b></a>')

it('adds the prefix `riot-` to some attributes', function() {
it('adds the prefix `riot-` to some attributes', function () {
testStr('<img src={ a }>', '<img riot-src="{a}">')

@@ -24,3 +26,3 @@ testStr('<p style="left:0; top={ n }">', '<p riot-style="left:0; top={n}">')

it('adds the prefix `__` to boolean attributes with expressions', function() {
it('adds the prefix `__` to boolean attributes with expressions', function () {
testStr('<a disabled={ a } nowrap="{ b }">', '<a __disabled="{a}" __nowrap="{b}">')

@@ -31,3 +33,3 @@ testStr('<a disabled readonly={}>', '<a disabled __readonly="{}">')

it('adds double quotes to the attribute value', function() {
it('adds double quotes to the attribute value', function () {
testStr('<a a={ a }>', '<a a="{a}">')

@@ -40,3 +42,3 @@ testStr("<a a='{ a }'>", '<a a="{a}">')

it('keeps interpolations', function() {
it('keeps interpolations', function () {
testStr('<a href="a?b={ c }">', '<a href="a?b={c}">')

@@ -46,3 +48,3 @@ testStr('<a id="{ a }b">', '<a id="{a}b">')

it('skips HTML comments', function() {
it('skips HTML comments', function () {
testStr('{ a }<!-- c -->', '{a}')

@@ -53,7 +55,7 @@ testStr('<!-- c -->{ a }', '{a}')

it('option `whitespace` normalizes and preserves line endings', function() {
it('option `whitespace` normalizes and preserves line endings', function () {
testStr('<p>a\r</p>\r\r\n<p>\n</p>', '<p>a\n</p>\n\n<p>\n</p>', { whitespace: 1 })
})
it('option `compact` removes line endings between tags', function() {
it('option `compact` removes line endings between tags', function () {
testStr('<p>a\r</p>\r\r\n<p>\n</p>', '<p>a </p><p></p>', { compact: 1 })

@@ -64,6 +66,18 @@ })

it('fix #827 to input type=number', function () {
testStr('<input type=number>', '<input type="{\'number\'}">')
it('fix #827 input type=number and expression in the value', function () {
testStr('<input type=number>', '<input type="number">') // no value
testStr('<input type=number value=1>', '<input value="1" type="number">') // no expression
testStr('<input type=number value={ 1 }>', '<input value="{1}" type="{\'number\'}">')
})
it('fix #1495 Warning of input tag value - for date/time/month/email/color values', function () {
testStr('<input type=date value={d}>', '<input value="{d}" type="{\'date\'}">')
testStr('<input type=time value={t}>', '<input value="{t}" type="{\'time\'}">')
testStr('<input type=date-local value={dl}>', '<input value="{dl}" type="{\'date-local\'}">')
testStr('<input type=datetime value={dt}>', '<input value="{dt}" type="{\'datetime\'}">')
testStr('<input type=month value={m}>', '<input value="{m}" type="{\'month\'}">')
testStr('<input type=email value={e}>', '<input value="{e}" type="{\'email\'}">')
testStr('<input type=color value={c}>', '<input value="{c}" type="{\'color\'}">')
})
it('normalizes attributes, all values in double quotes', function () {

@@ -98,3 +112,3 @@ testStr('<a a={a} b=number c =\'x\'>', '<a a="{a}" b="number" c="x">')

// compile.html must preserve escaped brackets
it('preserves escaped riot brackets', function() {
it('preserves escaped riot brackets', function () {
testStr('\\{ a }', '\\{ a }')

@@ -131,5 +145,5 @@ testStr(' \\{ a \\}', '\\{ a \\}') // trim is ok

'<p>{= \'&lt;\' + myElem + \' style=\u2057color: \' + myColor + \';\u2057&gt;\\n Click me&lt;/\' + myElem + \'&gt;\'}</p>')
testStr(
'<ul><li>{= ["foo", "bar"].join(\'<br/>\') }</li></ul>',
'<ul><li>{= [\u2057foo\u2057, \u2057bar\u2057].join(\'&lt;br/&gt;\')}</li></ul>')
testStr(
'<ul><li>{= ["foo", "bar"].join(\'<br/>\') }</li></ul>',
'<ul><li>{= [\u2057foo\u2057, \u2057bar\u2057].join(\'&lt;br/&gt;\')}</li></ul>')
})

@@ -136,0 +150,0 @@

//
// Parsers Suite
//
/*eslint-env node, mocha */
/*eslint-env mocha */
/*global compiler, expect */
/*eslint no-console: 0 */
var
path = require('path'),
fs = require('fs')
var

@@ -12,3 +16,3 @@ fixtures = __dirname,

function have(mod, req) {
function have (mod, req) {
if (compiler.parsers._req(mod, req))

@@ -20,7 +24,7 @@ return true

function cat(dir, filename) {
function cat (dir, filename) {
return fs.readFileSync(path.join(dir, filename), 'utf8')
}
function normalize(str) {
function normalize (str) {
var

@@ -34,8 +38,9 @@ n = str.search(/[^\n]/)

function testParser(name, opts, save) {
function testParser (name, opts, save) {
opts = opts || {}
var
file = name + (opts.type ? '.' + opts.type : ''),
str1 = cat(fixtures, file + '.tag'),
str2 = cat(expected, file + '.js')
js = compiler.compile(str1, opts || {}, path.join(fixtures, file + '.tag'))
str2 = cat(expected, file + '.js'),
js = compiler.compile(str1, opts, path.join(fixtures, file + '.tag'))

@@ -53,3 +58,3 @@ if (save)

function testStr(str, resStr, opts) {
function testStr (str, resStr, opts) {
expect(compiler.html(str, opts || {})).to.be(resStr)

@@ -104,3 +109,3 @@ }

function _custom(js) {
function _custom () {
return 'var foo'

@@ -114,3 +119,3 @@ }

if (have('none')) { // testing none, for coverage too
testParser('complex', {})
testParser('complex')
}

@@ -132,3 +137,3 @@ else expect().fail('parsers.js must have a "none" property')

if (have('javascript')) { // for js, for coverage too
testParser('mixed-js', {})
testParser('mixed-js')
}

@@ -196,3 +201,3 @@ else expect().fail('parsers.js must have a "javascript" property')

// custom parser
compiler.parsers.css.postcss = function(tag, css, opts) {
compiler.parsers.css.postcss = function (tag, css) {
return require('postcss')([require('autoprefixer')]).process(css).css

@@ -203,3 +208,3 @@ }

it('default style', function () {
testParser('style', {})
testParser('style')
})

@@ -209,3 +214,3 @@

it('scoped styles', function () {
testParser('style.scoped', {})
testParser('style.scoped')
})

@@ -216,3 +221,4 @@

if (have('stylus')) {
testParser('stylus', {})
testParser('stylus')
testParser('stylus-import')
}

@@ -224,3 +230,3 @@ })

if (have('sass')) {
testParser('sass', {})
testParser('sass')
}

@@ -232,3 +238,4 @@ })

if (have('scss')) {
testParser('scss', {})
testParser('scss')
testParser('scss-import')
}

@@ -240,3 +247,3 @@ })

if (have('sass')) {
testParser('sass.options', {})
testParser('sass.options')
}

@@ -248,3 +255,3 @@ })

if (have('postcss', 'postcss')) {
testParser('postcss', {})
testParser('postcss')
}

@@ -256,3 +263,4 @@ })

if (have('less')) {
testParser('less', {})
testParser('less')
testParser('less-import')
}

@@ -262,3 +270,3 @@ })

it('mixing CSS blocks with different type', function () {
testParser('mixed-css', {})
testParser('mixed-css')
})

@@ -314,3 +322,3 @@

// custom parser
compiler.parsers.js.rawhtml = function(js) {
compiler.parsers.js.rawhtml = function (js) {
return js.replace(/"/g, '&quot;')

@@ -317,0 +325,0 @@ }

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

/*eslint-env mocha */
/*global compiler, expect */
var fs = require('fs'),

@@ -6,11 +9,11 @@ path = require('path')

function render(str) {
function render (str) {
return compiler.js(str, {})
}
function cat(dir, filename) {
function cat (dir, filename) {
return fs.readFileSync(path.join(__dirname, dir, filename), 'utf8')
}
function testFile(file, opts) {
function testFile (file/*, opts*/) {
expect(render(cat('fixtures', file))).to.be(cat('expect', file))

@@ -17,0 +20,0 @@ }

@@ -1,68 +0,71 @@

describe('Scoped CSS', function() {
/*eslint-env mocha */
/*global compiler, expect */
function render(str, parser) {
describe('Scoped CSS', function () {
function render (str, parser) {
return compiler.style(str, 'my-tag', parser || 'scoped-css')
}
it('add my-tag to the simple selector', function() {
it('add my-tag to the simple selector', function () {
expect(render('h1 { font-size: 150% }'))
.to.equal('my-tag h1,[riot-tag="my-tag"] h1 { font-size: 150% }')
})
it('add my-tag to the multi selector in a line', function() {
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 }')
})
it('add my-tag to the complex selector', function() {
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 }')
})
it('add my-tag to the comma-separated selector', function() {
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 }')
})
it('add my-tag to the attribute selector', function() {
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 }')
})
it('add my-tag to the selector with a pseudo-class', function() {
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: "*" }')
})
it('add my-tag to the selector with multi-line definitions', function() {
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); }')
})
it('add my-tag to the root selector', function() {
it('add my-tag to the root selector', function () {
expect(render(':scope { display: block }'))
.to.equal('my-tag,[riot-tag="my-tag"] { display: block }')
})
it('add my-tag to the nested root selector', function() {
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 }')
})
it('add my-tag to the root selector with attribute', function() {
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 }')
})
it('add my-tag to the root selector with class', function() {
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 }')
})
it('not add my-tag to @font-face', function() {
it('not add my-tag to @font-face', function () {
expect(render('@font-face { font-family: "FontAwesome" }'))
.to.equal('@font-face { font-family: "FontAwesome" }')
})
it('not add my-tag to @media, and add it to the selector inside', function() {
it('not add my-tag to @media, and add it to the selector inside', 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; } }')
})
it('not add my-tag to "from" and "to" in @keyframes', function() {
it('not add my-tag to "from" and "to" in @keyframes', function () {
expect(render('@keyframes fade { from { opacity: 1; } to { opacity: 0; } }'))
.to.equal('@keyframes fade { from { opacity: 1; } to { opacity: 0; } }')
})
it('not add my-tag to parcentage values in @keyframes', function() {
it('not add my-tag to parcentage values in @keyframes', function () {
expect(render('@keyframes fade { 10% { opacity: 1; } 85% { opacity: 0; } }'))
.to.equal('@keyframes fade { 10% { opacity: 1; } 85% { opacity: 0; } }')
})
it('compile empty style', function() {
it('compile empty style', function () {
expect(render('h1 {} h2 { font-size: 130% }'))

@@ -72,4 +75,4 @@ .to.equal('my-tag h1,[riot-tag="my-tag"] h1 {} my-tag h2,[riot-tag="my-tag"] h2 { font-size: 130% }')

it('use a custom css parser to render the css', function() {
compiler.parsers.css.myParser = function(tag, css) {
it('use a custom css parser to render the css', function () {
compiler.parsers.css.myParser = function (tag, css) {
return css.replace(/@tag/, tag)

@@ -76,0 +79,0 @@ }

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

/*eslint-env mocha */
/*global compiler, expect */
var fs = require('fs'),
path = require('path')
describe('Compile tags', function() {
describe('Compile tags', function () {
// in Windows __dirname is the real path, path.relative uses symlink

@@ -13,19 +16,19 @@ var

// css
compiler.parsers.css.myparser = function(tag, css) {
compiler.parsers.css.myparser = function (tag, css) {
return css.replace(/@tag/, tag)
}
// js
compiler.parsers.js.myparser = function(js) {
compiler.parsers.js.myparser = function (js) {
return js.replace(/@version/, '1.0.0')
}
function render(str, name) {
function render (str, name) {
return compiler.compile(str, { debug: true }, path.join(fixtures, name))
}
function cat(dir, filename) {
function cat (dir, filename) {
return fs.readFileSync(path.join(dir, filename)).toString()
}
function testFile(name, save) {
function testFile (name, save) {
var src = cat(fixtures, name + '.tag'),

@@ -41,27 +44,27 @@ js = render(src, name + '.tag')

it('Timetable tag', function() {
it('Timetable tag', function () {
testFile('timetable')
})
it('Mixing JavaScript and custom tags', function() {
it('Mixing JavaScript and custom tags', function () {
testFile('mixed-js')
})
it('Tag definition and usage on same file', function() {
it('Tag definition and usage on same file', function () {
testFile('same')
})
it('Scoped CSS', function() {
it('Scoped CSS', function () {
testFile('scoped')
})
it('Quotes before ending HTML bracket', function() {
it('Quotes before ending HTML bracket', function () {
testFile('input-last')
})
it('Preserves the object inside the tags', function() {
it('Preserves the object inside the tags', function () {
testFile('box')
})
it('Flexible method style (v2.3)', function() {
it('Flexible method style (v2.3)', function () {
testFile('free-style')

@@ -78,3 +81,3 @@ })

it('Included files (v2.3.1)', function() {
it('Included files (v2.3.1)', function () {
testFile('includes')

@@ -100,6 +103,7 @@ })

var
src = cat(fixtures, 'script-options.tag'),
js = compiler.compile(src, { parser: testOpts })
src = cat(fixtures, 'script-options.tag')
function testOpts(src, opts) {
compiler.compile(src, { parser: testOpts })
function testOpts (src, opts) {
expect(opts).to.eql({ val: true })

@@ -126,3 +130,3 @@ }

it('Whitespace is compacted in other parts', function() {
it('Whitespace is compacted in other parts', function () {
testFile('whitespace')

@@ -151,3 +155,3 @@ })

resarr = [
[ 'treeview',
['treeview',
/^<ul id="treeview"> <li> <treeitem data="\{treedata}">/,

@@ -157,3 +161,3 @@ '', '',

],
[ 'treeitem',
['treeitem',
/^<div class="\{bold: isFolder\(\)}" onclick="\{toggle}"/,

@@ -228,2 +232,10 @@ '', '',

it('Script and Style blocks inside strings must be skipped #1448', function () {
testFile('quoted-tags')
})
it('Html comments are removed anywhere, except inside JS strings', function () {
testFile('html-comments')
})
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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