riot-compiler
Advanced tools
Comparing version 2.3.1 to 2.3.11
@@ -1,2 +0,2 @@ | ||
/* riot-compiler 2.3.1, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
/* riot-compiler v2.3.11, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
;(function (root, factory) { | ||
@@ -40,3 +40,2 @@ | ||
return fn('babel') || fn('babel-core') | ||
/* istanbul ignore next */ | ||
case 'babel': | ||
@@ -131,3 +130,3 @@ req = 'babel-core' | ||
}, | ||
es6: /* istanbul ignore next */ function (js, opts) { | ||
es6: function (js, opts) { | ||
return _req('es6').transform(js, extend({ | ||
@@ -195,7 +194,3 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false | ||
if (/\S/.test(js)) { | ||
js = js.replace(/\n{3,}/g, '\n\n') | ||
if (js.slice(-1) !== '\n') s = '\n' + s | ||
} | ||
else js = '' | ||
if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
@@ -208,3 +203,2 @@ return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
for (var prop in props) { | ||
/* istanbul ignore next */ | ||
if (props.hasOwnProperty(prop)) { | ||
@@ -371,2 +365,3 @@ obj[prop] = props[prop] | ||
function compileJS(js, opts, type, parserOpts) { | ||
if (!js) return '' | ||
if (!type) type = opts.type | ||
@@ -425,3 +420,5 @@ | ||
var TYPE_ATTR = /\stype\s*=\s*(?:['"]([^'"]+)['"]|(\S+))/i | ||
var | ||
TYPE_ATTR = /\stype\s*=\s*(?:(['"])(.+?)\1|(\S+))/i, | ||
MISC_ATTR = /\s*=\s*("(?:\\[\S\s]|[^"\\]*)*"|'(?:\\[\S\s]|[^'\\]*)*'|\{[^}]+}|\S+)/.source | ||
@@ -432,3 +429,3 @@ function getType(str) { | ||
var match = str.match(TYPE_ATTR) | ||
str = match && (match[1] || match[2]) | ||
str = match && (match[2] || match[3]) | ||
} | ||
@@ -442,25 +439,42 @@ return str ? str.replace('text/', '') : '' | ||
var | ||
re = _regEx(TYPE_ATTR.source.replace('type', name), 'i'), | ||
match = str && str.match(re) | ||
/* istanbul ignore next */ | ||
str = match && (match[1] || match[2]) | ||
re = _regEx('\\s' + name + MISC_ATTR, 'i'), | ||
match = str.match(re) | ||
str = match && match[1] | ||
if (str) | ||
return /^['"]/.test(str) ? str.slice(1, -1) : str | ||
} | ||
return str || '' | ||
return '' | ||
} | ||
// get the parser options from the options attribute | ||
function getParserOptions(attrs) { | ||
var opts = getAttr(attrs, 'options') | ||
/* istanbul ignore next */ | ||
if (opts) opts = JSON.parse(parserOpts) | ||
// convert the string into a valid js object | ||
if (opts) opts = JSON.parse(opts) | ||
return opts | ||
} | ||
function getCode(code, opts, attrs) { | ||
// Runs the custom or default parser on the received JavaScript code. | ||
// The CLI version can read code from the file system (experimental) | ||
function getCode(code, opts, attrs, url) { | ||
var type = getType(attrs), | ||
parserOpts = getParserOptions(attrs) | ||
//#if READ_JS_SRC | ||
var src = getAttr(attrs, 'src') | ||
if (src && url) { | ||
var | ||
charset = getAttr(attrs, 'charset'), | ||
file = path.resolve(path.dirname(url), src) | ||
code = require('fs').readFileSync(file, {encoding: charset || 'utf8'}) | ||
} | ||
//#endif | ||
return compileJS(code, opts, type, parserOpts) | ||
} | ||
// Matches HTML tag ending a line. This regex still can be fooled by code as: | ||
// ```js | ||
// x <y && y > | ||
// z | ||
// ``` | ||
var END_TAGS = /\/>\n|^<(?:\/[\w\-]+\s*|[\w\-]+(?:\s+(?:[-\w:\xA0-\xFF][\S\s]*?)?)?)>\n/ | ||
@@ -475,3 +489,3 @@ | ||
k = str.lastIndexOf('<') | ||
k = str.lastIndexOf('<') // first probable open tag | ||
while (~k) { | ||
@@ -488,2 +502,3 @@ if (m = str.slice(k).match(END_TAGS)) { | ||
// Runs the external HTML parser for the entire tag file | ||
function compileTemplate(lang, html, opts) { | ||
@@ -498,2 +513,10 @@ var parser = parsers.html[lang] | ||
/* | ||
CUST_TAG regex don't allow unquoted expressions containing the `>` operator. | ||
STYLE and SCRIPT disallows the operator `>` at all. | ||
The beta.4 CUST_TAG regex is fast, with RegexBuddy I get 76 steps and 14 backtracks on | ||
the test/specs/fixtures/treeview.tag :) but fails with nested tags of the same name :( | ||
With a greedy * operator, we have ~500 and 200bt, it is acceptable. So let's fix this. | ||
*/ | ||
var | ||
@@ -505,3 +528,3 @@ CUST_TAG = /^<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^<\/\1\s*>|>(.*)<\/\1\s*>)/gim, | ||
function compile(src, opts, url) { | ||
var label | ||
var label, parts = [] | ||
@@ -515,5 +538,8 @@ if (!opts) opts = {} | ||
label = url ? '//src: ' + path.relative('.', url) + '\n' : '' | ||
/* istanbul ignore next */ | ||
label = !url ? '' : path.isAbsolute(url) ? path.relative('.', url) : url | ||
if (label) | ||
label = '//src: ' + label.replace(/\\/g, '/') + '\n' | ||
return label + src | ||
src = label + src | ||
.replace(/\r\n?/g, '\n') | ||
@@ -530,4 +556,4 @@ .replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
if (attribs) | ||
attribs = restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -550,3 +576,3 @@ if (body2) body = body2 | ||
body = body.replace(SCRIPT, function (_, _attrs, _script) { | ||
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs) | ||
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url) | ||
return '' | ||
@@ -567,4 +593,19 @@ }) | ||
jscode = /\S/.test(jscode) ? jscode.replace(/\n{3,}/g, '\n\n') : '' | ||
if (opts.entities) { | ||
parts.push({ | ||
tagName: tagName, | ||
html: html, | ||
css: styles, | ||
attribs: attribs, | ||
js: jscode | ||
}) | ||
return '' | ||
} | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
}) | ||
return opts.entities ? parts : src | ||
} | ||
@@ -571,0 +612,0 @@ |
/** | ||
* Compiler for riot custom tags | ||
* @version 2.3.0 | ||
* @version v2.3.11 | ||
*/ | ||
@@ -59,3 +59,3 @@ | ||
}, | ||
es6: /* istanbul ignore next */ function (js, opts) { | ||
es6: function (js, opts) { | ||
return _req('es6').transform(js, extend({ | ||
@@ -124,7 +124,3 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false | ||
if (/\S/.test(js)) { | ||
js = js.replace(/\n{3,}/g, '\n\n') | ||
if (js.slice(-1) !== '\n') s = '\n' + s | ||
} | ||
else js = '' | ||
if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
@@ -137,3 +133,2 @@ return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
for (var prop in props) { | ||
/* istanbul ignore next */ | ||
if (props.hasOwnProperty(prop)) { | ||
@@ -300,2 +295,3 @@ obj[prop] = props[prop] | ||
function compileJS(js, opts, type, parserOpts) { | ||
if (!js) return '' | ||
if (!type) type = opts.type | ||
@@ -354,3 +350,5 @@ | ||
var TYPE_ATTR = /\stype\s*=\s*(?:['"]([^'"]+)['"]|(\S+))/i | ||
var | ||
TYPE_ATTR = /\stype\s*=\s*(?:(['"])(.+?)\1|(\S+))/i, | ||
MISC_ATTR = /\s*=\s*("(?:\\[\S\s]|[^"\\]*)*"|'(?:\\[\S\s]|[^'\\]*)*'|\{[^}]+}|\S+)/.source | ||
@@ -361,3 +359,3 @@ function getType(str) { | ||
var match = str.match(TYPE_ATTR) | ||
str = match && (match[1] || match[2]) | ||
str = match && (match[2] || match[3]) | ||
} | ||
@@ -371,25 +369,42 @@ return str ? str.replace('text/', '') : '' | ||
var | ||
re = _regEx(TYPE_ATTR.source.replace('type', name), 'i'), | ||
match = str && str.match(re) | ||
/* istanbul ignore next */ | ||
str = match && (match[1] || match[2]) | ||
re = _regEx('\\s' + name + MISC_ATTR, 'i'), | ||
match = str.match(re) | ||
str = match && match[1] | ||
if (str) | ||
return /^['"]/.test(str) ? str.slice(1, -1) : str | ||
} | ||
return str || '' | ||
return '' | ||
} | ||
// get the parser options from the options attribute | ||
function getParserOptions(attrs) { | ||
var opts = getAttr(attrs, 'options') | ||
/* istanbul ignore next */ | ||
if (opts) opts = JSON.parse(parserOpts) | ||
// convert the string into a valid js object | ||
if (opts) opts = JSON.parse(opts) | ||
return opts | ||
} | ||
function getCode(code, opts, attrs) { | ||
// Runs the custom or default parser on the received JavaScript code. | ||
// The CLI version can read code from the file system (experimental) | ||
function getCode(code, opts, attrs, url) { | ||
var type = getType(attrs), | ||
parserOpts = getParserOptions(attrs) | ||
//#if READ_JS_SRC | ||
var src = getAttr(attrs, 'src') | ||
if (src && url) { | ||
var | ||
charset = getAttr(attrs, 'charset'), | ||
file = path.resolve(path.dirname(url), src) | ||
code = require('fs').readFileSync(file, {encoding: charset || 'utf8'}) | ||
} | ||
//#endif | ||
return compileJS(code, opts, type, parserOpts) | ||
} | ||
// Matches HTML tag ending a line. This regex still can be fooled by code as: | ||
// ```js | ||
// x <y && y > | ||
// z | ||
// ``` | ||
var END_TAGS = /\/>\n|^<(?:\/[\w\-]+\s*|[\w\-]+(?:\s+(?:[-\w:\xA0-\xFF][\S\s]*?)?)?)>\n/ | ||
@@ -404,3 +419,3 @@ | ||
k = str.lastIndexOf('<') | ||
k = str.lastIndexOf('<') // first probable open tag | ||
while (~k) { | ||
@@ -417,2 +432,3 @@ if (m = str.slice(k).match(END_TAGS)) { | ||
// Runs the external HTML parser for the entire tag file | ||
function compileTemplate(lang, html, opts) { | ||
@@ -427,2 +443,10 @@ var parser = parsers.html[lang] | ||
/* | ||
CUST_TAG regex don't allow unquoted expressions containing the `>` operator. | ||
STYLE and SCRIPT disallows the operator `>` at all. | ||
The beta.4 CUST_TAG regex is fast, with RegexBuddy I get 76 steps and 14 backtracks on | ||
the test/specs/fixtures/treeview.tag :) but fails with nested tags of the same name :( | ||
With a greedy * operator, we have ~500 and 200bt, it is acceptable. So let's fix this. | ||
*/ | ||
var | ||
@@ -434,3 +458,3 @@ CUST_TAG = /^<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^<\/\1\s*>|>(.*)<\/\1\s*>)/gim, | ||
function compile(src, opts, url) { | ||
var label | ||
var label, parts = [] | ||
@@ -446,3 +470,3 @@ if (!opts) opts = {} | ||
return label + src | ||
src = label + src | ||
.replace(/\r\n?/g, '\n') | ||
@@ -459,4 +483,4 @@ .replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
if (attribs) | ||
attribs = restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -495,4 +519,19 @@ if (body2) body = body2 | ||
jscode = /\S/.test(jscode) ? jscode.replace(/\n{3,}/g, '\n\n') : '' | ||
if (opts.entities) { | ||
parts.push({ | ||
tagName: tagName, | ||
html: html, | ||
css: styles, | ||
attribs: attribs, | ||
js: jscode | ||
}) | ||
return '' | ||
} | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
}) | ||
return opts.entities ? parts : src | ||
} | ||
@@ -499,0 +538,0 @@ |
@@ -5,8 +5,8 @@ Attributes | ||
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. | ||
`d` describes the SVG `<path>`, Chrome gives error if the value has invalid format. | ||
See: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d | ||
`style` | ||
`src` | ||
`d` | ||
- `style` | ||
- `src` | ||
- `d` | ||
@@ -18,7 +18,7 @@ Boolean Attributes | ||
http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes | ||
http://w3c.github.io/html-reference/global-attributes.html | ||
http://javascript.info/tutorial/attributes-and-custom-properties | ||
http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html | ||
http://www.w3.org/wiki/HTML/Elements/audio | ||
http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes | ||
http://w3c.github.io/html-reference/global-attributes.html | ||
http://javascript.info/tutorial/attributes-and-custom-properties | ||
http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html | ||
http://www.w3.org/wiki/HTML/Elements/audio | ||
@@ -29,55 +29,55 @@ Tested with [the w3c Validator](https://validator.w3.org/nu) | ||
disabled | ||
checked | ||
readonly | ||
ismap | ||
reversed - `<ol>` | ||
selected | ||
- disabled | ||
- checked | ||
- readonly | ||
- ismap | ||
- reversed - `<ol>` | ||
- selected | ||
### New html5 attributes | ||
autofocus | ||
formnovalidate | ||
hidden | ||
inert | ||
itemscope - html5 Microdata | ||
multiple | ||
novalidate | ||
required | ||
typemustmatch | ||
default - `<menuitem>` (not yet supported by browsers) | ||
open - `<details>`/`<dialog>` | ||
sortable - html 5.1 | ||
- autofocus | ||
- formnovalidate | ||
- hidden | ||
- inert | ||
- itemscope - html5 Microdata | ||
- multiple | ||
- novalidate | ||
- required | ||
- typemustmatch | ||
- default - `<menuitem>` (not yet supported by browsers) | ||
- open - `<details>`/`<dialog>` | ||
- sortable - html 5.1 | ||
### Not supported in html5 | ||
allowfullscreen - `<iframe>` | ||
seamless - `<iframe>` | ||
noresize - `<frame>` | ||
noshade - `<hr>` (obsolete) | ||
nohref - `<area>` | ||
nowrap - `<td>` | ||
compact - `<ol>`/`<ul>`/`<dir>` | ||
truespeed - `<marquee>` attribute not supported by Chrome/Opera | ||
- allowfullscreen - `<iframe>` | ||
- seamless - `<iframe>` | ||
- noresize - `<frame>` | ||
- noshade - `<hr>` (obsolete) | ||
- nohref - `<area>` | ||
- nowrap - `<td>` | ||
- compact - `<ol>`/`<ul>`/`<dir>` | ||
- truespeed - `<marquee>` attribute not supported by Chrome/Opera | ||
### For the `<video>` element | ||
autoplay | ||
controls | ||
loop | ||
default - `<track>` | ||
muted | ||
- autoplay | ||
- controls | ||
- loop | ||
- default - `<track>` | ||
- muted | ||
### Removed from BOOL_ATTR | ||
## Removed from BOOL_ATTR | ||
async -- `<script>` riot does not handle this | ||
defer -- `<script>` riot does not handle this, only IE8+ honors this attribute | ||
defaultChecked, Muted, Selected -- they are properties, not attributes | ||
draggable -- not boolean, this is an enumerated attribute: true, false, auto | ||
spellcheck -- not boolean, this is an enumerated attribute: true, false | ||
translate -- not boolean, this is an enumerated attribute: yes, no | ||
declare - `<object>` unuseful in main browsers | ||
indeterminate - boolean attr, but can't be set with markup | ||
pauseonexit - `<track>` not for markup, or it is too complex | ||
enabled - not in the HTML specs | ||
visible - not in the HTML specs | ||
- async -- `<script>` riot does not handle this | ||
- defer -- `<script>` riot does not handle this, only IE8+ honors this attribute | ||
- defaultChecked, Muted, Selected -- they are properties, not attributes | ||
- draggable -- not boolean, this is an enumerated attribute: true, false, auto | ||
- spellcheck -- not boolean, this is an enumerated attribute: true, false | ||
- translate -- not boolean, this is an enumerated attribute: yes, no | ||
- declare - `<object>` unuseful in main browsers | ||
- indeterminate - boolean attr, but can't be set with markup | ||
- pauseonexit - `<track>` not for markup, or it is too complex | ||
- enabled - not in the HTML specs | ||
- visible - not in the HTML specs |
# Backslashes and Whitespace | ||
From the perspective of the riot compiler and `tmpl`, backslashes in the template are characters without special meaning, the compiler preserves this in the HTML, and remove inside the expressions. | ||
From the perspective of the riot compiler and `tmpl`, backslashes in the template are characters with no special meaning. The compiler preserves them in the HTML and expressions, with one exception: backslashes used to escape riot brackets are temporarily removed when the expression is passed to a parser, and finally removed at runtime, before evaluating the expression. | ||
EOLs are converted to spaces and compacted. This happens in the quoted HTML text and the element values. | ||
In the html, including quoted text, newlines are converted to spaces and compacted, except if you pass the `whitespace` option to the compiler. With this options, newlines are normalized to `\n` and preserved. | ||
In strings and regexes inside expressions, whitespace are preserved. | ||
In quoted strings and regexes inside expressions, all whitespace are preserved. |
@@ -23,3 +23,3 @@ # Compiler | ||
but you don't get to know when external resources are loaded and compiled and the return value is an empty array if you have external scripts. If all scripts are defined on the page then compiler.compile step can be left out. | ||
but you don't get to know when external resources are loaded and compiled and the return value is an empty array if you have external scripts. If all scripts are defined on the page then `compiler.compile` step can be left out. | ||
@@ -82,3 +82,3 @@ For more details, read the compiler [general introduction](/guide/compiler/). | ||
Custom parsers that could be used to compile your tags css. For example: | ||
Custom parsers that could be used to compile your tags CSS. For example: | ||
@@ -113,3 +113,3 @@ ```js | ||
Custom parsers that could be used to compile your tags javascript. For example | ||
Custom parsers that could be used to compile your tags JavaScript. For example | ||
@@ -144,5 +144,6 @@ ```js | ||
Custom parsers that could be used to compile your tags html. | ||
Custom parsers that could be used to compile your tags HTML. | ||
The predefined parsers are: | ||
#### html | ||
@@ -152,2 +153,4 @@ - `jade` | ||
#### css | ||
- `less` | ||
- `sass` | ||
- `stylus` | ||
@@ -160,6 +163,7 @@ | ||
- `es6` - (using `babel-core` or `babel`) | ||
- `babel` - (using `babel-core` v6.x and the `es2015` preset) | ||
- `coffee` or `coffeescript` | ||
## Changes | ||
## Changes in v2.3.0 | ||
In previous versions, escaped brackets were preserved, generating incorrect HTML or invalid JavaScript code. This version removes them at an early stage, after passing the tag to the html parser, but before that the JavaScript code and expressions are sent to the js parser. | ||
In previous versions, escaped brackets were preserved, generating incorrect HTML or invalid JavaScript code. This version removes them at an early stage, after passing the tag to the html parser and before the JavaScript code and expressions are sent to the js parser. |
@@ -9,2 +9,3 @@ /** | ||
//#else | ||
//#define READ_JS_SRC | ||
@@ -75,7 +76,3 @@ var brackets = _tmpl.brackets //eslint-disable-line no-redeclare | ||
// give more consistency to the output | ||
if (/\S/.test(js)) { | ||
js = js.replace(/\n{3,}/g, '\n\n') | ||
if (js.slice(-1) !== '\n') s = '\n' + s | ||
} | ||
else js = '' | ||
if (js && js.slice(-1) !== '\n') s = '\n' + s | ||
@@ -95,3 +92,2 @@ return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
for (var prop in props) { | ||
/* istanbul ignore next */ | ||
if (props.hasOwnProperty(prop)) { | ||
@@ -311,2 +307,3 @@ obj[prop] = props[prop] | ||
function compileJS(js, opts, type, parserOpts) { | ||
if (!js) return '' | ||
if (!type) type = opts.type | ||
@@ -394,3 +391,5 @@ | ||
// Matches the 'type' attribute, for script and style tags | ||
var TYPE_ATTR = /\stype\s*=\s*(?:['"]([^'"]+)['"]|(\S+))/i | ||
var | ||
TYPE_ATTR = /\stype\s*=\s*(?:(['"])(.+?)\1|(\S+))/i, // don't handle escaped quotes :( | ||
MISC_ATTR = /\s*=\s*("(?:\\[\S\s]|[^"\\]*)*"|'(?:\\[\S\s]|[^'\\]*)*'|\{[^}]+}|\S+)/.source | ||
@@ -402,3 +401,3 @@ // Returns the value of the 'type' attribute, with the prefix "text/" removed. | ||
var match = str.match(TYPE_ATTR) | ||
str = match && (match[1] || match[2]) | ||
str = match && (match[2] || match[3]) | ||
} | ||
@@ -414,8 +413,9 @@ return str ? str.replace('text/', '') : '' | ||
var | ||
re = _regEx(TYPE_ATTR.source.replace('type', name), 'i'), | ||
match = str && str.match(re) | ||
/* istanbul ignore next */ | ||
str = match && (match[1] || match[2]) | ||
re = _regEx('\\s' + name + MISC_ATTR, 'i'), | ||
match = str.match(re) | ||
str = match && match[1] | ||
if (str) | ||
return /^['"]/.test(str) ? str.slice(1, -1) : str | ||
} | ||
return str || '' | ||
return '' | ||
} | ||
@@ -427,11 +427,9 @@ | ||
// convert the string into a valid js object | ||
/* istanbul ignore next */ | ||
if (opts) opts = JSON.parse(parserOpts) | ||
if (opts) opts = JSON.parse(opts) | ||
return opts | ||
} | ||
// Runs the custom or default parser on the received JavaScript code. | ||
// The CLI version can read code from the file system (experimental) | ||
function getCode(code, opts, attrs) { | ||
function getCode(code, opts, attrs, url) { | ||
var type = getType(attrs), | ||
@@ -442,7 +440,6 @@ parserOpts = getParserOptions(attrs) | ||
var src = getAttr(attrs, 'src') | ||
if (src) { | ||
if (src && url) { | ||
var | ||
charset = getAttr(attrs, 'charset'), | ||
file = path.resolve(opts.basedir, src) | ||
file = path.resolve(path.dirname(url), src) | ||
code = require('fs').readFileSync(file, {encoding: charset || 'utf8'}) | ||
@@ -517,3 +514,3 @@ } | ||
function compile(src, opts, url) { | ||
var label | ||
var label, parts = [] | ||
@@ -529,4 +526,8 @@ if (!opts) opts = {} | ||
// riot #1070 -- isAbsolute does not exists in node 10.x | ||
//#if NODE | ||
label = url ? '//src: ' + path.relative('.', url) + '\n' : '' | ||
/* istanbul ignore next */ | ||
label = !url ? '' : path.isAbsolute(url) ? path.relative('.', url) : url | ||
if (label) | ||
label = '//src: ' + label.replace(/\\/g, '/') + '\n' | ||
//#else | ||
@@ -537,3 +538,3 @@ label = url ? '//src: ' + url + '\n' : '' | ||
// normalize eols and start processing the tags | ||
return label + src | ||
src = label + src | ||
.replace(/\r\n?/g, '\n') | ||
@@ -553,4 +554,4 @@ .replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
// process the attributes, including their expressions | ||
if (attribs) | ||
attribs = restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -575,3 +576,7 @@ if (body2) body = body2 | ||
body = body.replace(SCRIPT, function (_, _attrs, _script) { | ||
//#if READ_JS_SRC | ||
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs, url) | ||
//#else | ||
jscode += (jscode ? '\n' : '') + getCode(_script, opts, _attrs) | ||
//#endif | ||
return '' | ||
@@ -593,5 +598,21 @@ }) | ||
// give more consistency to the output | ||
jscode = /\S/.test(jscode) ? jscode.replace(/\n{3,}/g, '\n\n') : '' | ||
// replace the tag with a call to the riot.tag2 function and we are done | ||
if (opts.entities) { | ||
parts.push({ | ||
tagName: tagName, | ||
html: html, | ||
css: styles, | ||
attribs: attribs, | ||
js: jscode | ||
}) | ||
return '' | ||
} | ||
// replace the tag with a call to the riot.tag2 function and we are done | ||
return mktag(tagName, html, styles, attribs, jscode, pcex) | ||
}) | ||
return opts.entities ? parts : src | ||
} | ||
@@ -598,0 +619,0 @@ |
//#if NODE | ||
//#undef RIOT | ||
/* riot-compiler 2.3.1, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
/* riot-compiler WIP, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
;(function (root, factory) { | ||
@@ -25,3 +25,3 @@ | ||
* Compiler for riot custom tags | ||
* @version 2.3.0 | ||
* @version WIP | ||
*/ | ||
@@ -28,0 +28,0 @@ //#endif |
@@ -7,6 +7,8 @@ /** | ||
/* | ||
Search a instance for a parser. | ||
If found, saves the function in _mods before return it to caller. | ||
Returns null if not found. | ||
/** | ||
* Loads a parser instance. | ||
* On success, saves the function in _mods before return it to caller. | ||
* @param {string} name - the _mods element, one of parsers.html/jss/css | ||
* @param {string} [req] - name for require(), defaults to 'name' | ||
* @returns {Function} parser function, or null if error | ||
*/ | ||
@@ -30,3 +32,2 @@ //#if NODE | ||
return fn('babel') || fn('babel-core') // versions 5.8x | ||
/* istanbul ignore next */ | ||
case 'babel': | ||
@@ -144,3 +145,3 @@ req = 'babel-core' | ||
}, | ||
es6: /* istanbul ignore next */ function (js, opts) { | ||
es6: function (js, opts) { | ||
return _req('es6').transform(js, extend({ | ||
@@ -147,0 +148,0 @@ blacklist: ['useStrict', 'strict', 'react'], sourceMaps: false, comments: false |
{ | ||
"name": "riot-compiler", | ||
"version": "2.3.1", | ||
"version": "2.3.11", | ||
"description": "Compiler for riot .tag files", | ||
@@ -17,4 +17,3 @@ "main": "dist/compiler.js", | ||
"scripts": { | ||
"test": "make test", | ||
"prepublish": "make build" | ||
"test": "make test" | ||
}, | ||
@@ -21,0 +20,0 @@ "repository": { |
@@ -6,3 +6,2 @@ var isNode = typeof window === 'undefined' | ||
compiler = require('../dist/compiler.js') | ||
//require('shelljs/global') | ||
require('./specs/html') | ||
@@ -9,0 +8,0 @@ require('./specs/scoped-css') |
@@ -1,2 +0,2 @@ | ||
//src: box.tag | ||
//src: test/specs/fixtures/box.tag | ||
riot.tag2('content', '<div class="box"> <h1>{box.title}</h1> <img riot-src="{box.image}" width="480"> <div class="body">{box.body}</div> </div>', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
//src: empty.tag | ||
//src: test/specs/fixtures/empty.tag | ||
riot.tag2('empty1', '', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
//src: free-style.tag | ||
//src: test/specs/fixtures/free-style.tag | ||
// free indent | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
//src: html-blocks.tag | ||
//src: test/specs/fixtures/html-blocks.tag | ||
// <y && y> can be confused with a closing html tag | ||
@@ -3,0 +3,0 @@ |
@@ -1,4 +0,4 @@ | ||
//src: includes.tag | ||
//src: test/specs/fixtures/includes.tag | ||
// free indent | ||
riot.tag2('includes', '<p onclick="{click}"></p><p foo="{myObj.foo < \'bar\'}"></p>', '', '', function(opts) { | ||
riot.tag2('includes', '<p onclick="{click}"></p>', '', '', function(opts) { | ||
this.myObj = { | ||
@@ -8,2 +8,3 @@ foo: 'bar', | ||
} | ||
this.click = function(e) { | ||
@@ -13,10 +14,10 @@ alert('Hello!') | ||
this.click = function(e) | ||
{foo ({})}.bind(this) | ||
this.click = function(e) | ||
{foo ({})}.bind(this) | ||
this.handle = function( e ) | ||
{ | ||
bar( {} ) | ||
} | ||
.bind (this) | ||
this.handle = function( e ) | ||
{ | ||
bar( {} ) | ||
} | ||
.bind (this) | ||
}, '{ }'); |
@@ -1,2 +0,2 @@ | ||
//src: input-last.tag | ||
//src: test/specs/fixtures/input-last.tag | ||
riot.tag2('test', '<input type="text">', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
//src: mixed-js.tag | ||
//src: test/specs/fixtures/mixed-js.tag | ||
function foo() { | ||
@@ -3,0 +3,0 @@ alert('1 < 2') |
@@ -1,3 +0,3 @@ | ||
//src: oneline.tag | ||
//src: test/specs/fixtures/oneline.tag | ||
riot.tag2('oneline', '<p>one line</p>', '', '', function(opts) { | ||
}); |
@@ -1,2 +0,2 @@ | ||
//src: same.tag | ||
//src: test/specs/fixtures/same.tag | ||
riot.tag2('same', '', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ var foo |
@@ -1,3 +0,3 @@ | ||
//src: scoped.tag | ||
//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) { | ||
}); |
@@ -1,4 +0,4 @@ | ||
//src: so-input.tag | ||
//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); | ||
}, '{ }'); |
@@ -1,3 +0,3 @@ | ||
//src: timetable.tag | ||
//src: test/specs/fixtures/timetable.tag | ||
riot.tag2('timetable', '<timer start="10"></timer> <timer start="20"></timer> <timer start="30"></timer>', '', '', function(opts) { | ||
}); |
@@ -1,2 +0,2 @@ | ||
//src: treeview.tag | ||
//src: test/specs/fixtures/treeview.tag | ||
riot.tag2('treeview', '<ul id="treeview"> <li> <treeitem data="{treedata}"></treeitem> </li> </ul>', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ this.treedata = { |
@@ -1,2 +0,2 @@ | ||
//src: unclosed-es6.tag | ||
//src: test/specs/fixtures/unclosed-es6.tag | ||
riot.tag2('unclosed-es6', '<h2>Methods</h2>', '', '', function(opts) { | ||
@@ -3,0 +3,0 @@ this.click = function() { |
@@ -109,3 +109,3 @@ // | ||
// testParser.tag | ||
// test.tag | ||
it('javascript (root container)', function () { | ||
@@ -115,3 +115,3 @@ testParser('test', { expr: true }) | ||
// testParser-alt.tag | ||
// test-alt.tag | ||
it('javascript (comment hack)', function () { | ||
@@ -128,3 +128,3 @@ testParser('test-alt', { expr: true }) | ||
// testParser.coffee.tag | ||
// test.coffee.tag | ||
it('coffeescript', function () { | ||
@@ -136,3 +136,3 @@ if (have('coffee')) { | ||
// testParser.livescript.tag | ||
// test.livescript.tag | ||
it('livescript', function () { | ||
@@ -144,3 +144,3 @@ if (have('livescript')) { | ||
// testParser.livescript.tag | ||
// test.livescript.tag | ||
it('typescript', function () { | ||
@@ -152,5 +152,12 @@ if (have('typescript')) { | ||
// testParser.babel.tag | ||
// test.es6.tag | ||
it('es6', function () { | ||
if (have('es6')) { | ||
testParser('test', { type: 'es6' }) | ||
} | ||
}) | ||
// test.babel.tag | ||
it('babel', function () { | ||
if (have('es6')) { | ||
if (have('babel')) { | ||
testParser('test', { type: 'babel' }) | ||
@@ -160,6 +167,6 @@ } | ||
// testParser-attr.babel.tag | ||
it('babel with shorthands (fix #1090)', function () { | ||
if (have('es6')) { | ||
testParser('test-attr', { type: 'babel', expr: true }) | ||
// test-attr.babel.tag | ||
it('coffee with shorthands (fix #1090)', function () { | ||
if (have('coffee')) { | ||
testParser('test-attr', { type: 'coffee', expr: true }) | ||
} | ||
@@ -219,2 +226,9 @@ }) | ||
// testing the options attribute on the style tag | ||
it('custom style options', function () { | ||
if (have('sass', 'node-sass')) { | ||
testParser('sass.options', {}) | ||
} | ||
}) | ||
// scss.tag | ||
@@ -221,0 +235,0 @@ it('custom parser using postcss + autoprefixer', function () { |
@@ -5,2 +5,7 @@ var fs = require('fs'), | ||
describe('Compile tags', function() { | ||
// in Windows __dirname is the real path, path.relative uses symlink | ||
var | ||
basepath = path.resolve(__dirname, '../..'), | ||
fixtures = path.relative(basepath, path.join(__dirname, 'fixtures')), | ||
expected = path.relative(basepath, path.join(__dirname, 'expect')) | ||
@@ -18,14 +23,14 @@ // adding some custom riot parsers | ||
function render(str, name) { | ||
return compiler.compile(str, {}, name) | ||
return compiler.compile(str, {}, path.join(fixtures, name)) | ||
} | ||
function cat(dir, filename) { | ||
return fs.readFileSync(path.join(__dirname, dir, filename)).toString() | ||
return fs.readFileSync(path.join(dir, filename)).toString() | ||
} | ||
function testFile(name) { | ||
var src = cat('fixtures', name + '.tag'), | ||
var src = cat(fixtures, name + '.tag'), | ||
js = render(src, name + '.tag') | ||
expect(js).to.equal(cat('expect', name + '.js')) | ||
expect(js).to.equal(cat(expected, name + '.js')) | ||
} | ||
@@ -69,7 +74,5 @@ | ||
/* | ||
it('Include files (v2.3)', function() { | ||
it('Included files (v2.3.1)', function() { | ||
testFile('includes') | ||
}) | ||
*/ | ||
@@ -86,7 +89,21 @@ it('Dealing with unclosed es6 methods', function () { | ||
var | ||
src = cat('fixtures', 'root-attribs.tag'), | ||
src = cat(fixtures, 'root-attribs.tag'), | ||
js = compiler.compile(src) // no name, no options | ||
expect(js).to.equal(cat('expect', 'root-attribs.js')) | ||
expect(js).to.equal(cat(expected, 'root-attribs.js')) | ||
}) | ||
it('Parsing the options attribute in script tags', function () { | ||
var | ||
src = cat(fixtures, 'script-options.tag'), | ||
js = compiler.compile(src, { parser: testOpts }) | ||
function testOpts(src, opts) { | ||
expect(opts).to.eql({ val: true }) | ||
} | ||
}) | ||
it('The `whitespace` option preserves newlines and tabs', function () { | ||
testFile('empty') | ||
}) | ||
it('Empty tag', function () { | ||
@@ -105,2 +122,28 @@ testFile('empty') | ||
}) | ||
it('the `entities` option give access to the compiled parts', function () { | ||
var parts = compiler.compile(cat(fixtures, 'treeview.tag'), {entities: true}) | ||
resarr = [ | ||
[ 'treeview', | ||
/^<ul id="treeview"> <li> <treeitem data="\{treedata}">/, | ||
'', '', | ||
/\s+this.treedata = {/ | ||
], | ||
[ 'treeitem', | ||
/^<div class="\{bold: isFolder\(\)}" onclick="\{toggle}"/, | ||
'', '', | ||
/\s+var self = this\s+self.name = opts.data.name/ | ||
] | ||
] | ||
expect(parts.length).to.be(2) | ||
for (var i = 0; i < 2; ++i) { | ||
var a = resarr[i] | ||
expect(parts[i]).to.be.an('object') | ||
expect(parts[i].tagName).to.be(a[0]) | ||
expect(parts[i].html).to.match(a[1]) | ||
expect(parts[i].css).to.be(a[2]) | ||
expect(parts[i].attribs).to.be(a[3]) | ||
expect(parts[i].js).to.match(a[4]) | ||
} | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
123052
113
2940
9