riot-compiler
Advanced tools
Comparing version 2.3.11 to 2.3.12
@@ -1,2 +0,2 @@ | ||
/* riot-compiler v2.3.11, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
/* riot-compiler v2.3.12, @license MIT, (c) 2015 Muut Inc. + contributors */ | ||
;(function (root, factory) { | ||
@@ -183,4 +183,5 @@ | ||
function q(s) { | ||
return "'" + (s ? s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") : '') + "'" | ||
return "'" + (s ? s | ||
.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') : | ||
'') + "'" | ||
} | ||
@@ -195,3 +196,3 @@ | ||
return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
return 'riot.tag2(\'' + name + "'" + c + q(html) + c + q(css) + c + q(attrs) + | ||
', function(opts) {\n' + js + s | ||
@@ -290,3 +291,3 @@ } | ||
_bp = brackets.array(opts.brackets) | ||
html = html.replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
} | ||
@@ -307,5 +308,12 @@ if (!pcex) pcex = [] | ||
html = opts.whitespace ? | ||
html.replace(/\r\n?|\n/g, '\\n') : html.trim().replace(/\s+/g, ' ') | ||
if (!opts.whitespace) { | ||
var p = [], | ||
pre = /<pre(?:\s+[^'">]+(?:(?:"[^"]*"|'[^']*')[^'">]*)*|\s*)>[\s\S]*<\/pre\s*>/gi | ||
html = html.replace(pre, function (q) { | ||
return '\u0002' + (p.push(q) - 1) + '~' }).trim().replace(/\s+/g, ' ') | ||
if (p.length) | ||
html = html.replace(/\u0002(\d+)~/g, function (q, n) { return p[n] }) | ||
} | ||
if (opts.compact) html = html.replace(/> <([-\w\/])/g, '><$1') | ||
@@ -375,3 +383,3 @@ | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
@@ -402,2 +410,3 @@ function scopedCSS(tag, style) { | ||
function compileCSS(style, tag, type, scoped, opts) { | ||
if (!type) type = opts.style | ||
@@ -518,3 +527,3 @@ if (type) { | ||
var | ||
CUST_TAG = /^<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^<\/\1\s*>|>(.*)<\/\1\s*>)/gim, | ||
CUST_TAG = /^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/gim, | ||
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi, | ||
@@ -540,3 +549,3 @@ SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi') | ||
.replace(/\r\n?/g, '\n') | ||
.replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
.replace(CUST_TAG, function (_, indent, tagName, attribs, body, body2) { | ||
@@ -551,4 +560,3 @@ var | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -562,2 +570,3 @@ if (body2) body = body2 | ||
else { | ||
body = body.replace(_regEx('^' + indent, 'gm'), '') | ||
@@ -564,0 +573,0 @@ body = body.replace(STYLE, function (_, _attrs, _style) { |
/** | ||
* Compiler for riot custom tags | ||
* @version v2.3.11 | ||
* @version v2.3.12 | ||
*/ | ||
@@ -114,4 +114,5 @@ | ||
function q(s) { | ||
return "'" + (s ? s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") : '') + "'" | ||
return "'" + (s ? s | ||
.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') : | ||
'') + "'" | ||
} | ||
@@ -126,3 +127,3 @@ | ||
return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
return 'riot.tag2(\'' + name + "'" + c + q(html) + c + q(css) + c + q(attrs) + | ||
', function(opts) {\n' + js + s | ||
@@ -221,3 +222,3 @@ } | ||
_bp = brackets.array(opts.brackets) | ||
html = html.replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
} | ||
@@ -238,5 +239,12 @@ if (!pcex) pcex = [] | ||
html = opts.whitespace ? | ||
html.replace(/\r\n?|\n/g, '\\n') : html.trim().replace(/\s+/g, ' ') | ||
if (!opts.whitespace) { | ||
var p = [], | ||
pre = /<pre(?:\s+[^'">]+(?:(?:"[^"]*"|'[^']*')[^'">]*)*|\s*)>[\s\S]*<\/pre\s*>/gi | ||
html = html.replace(pre, function (q) { | ||
return '\u0002' + (p.push(q) - 1) + '~' }).trim().replace(/\s+/g, ' ') | ||
if (p.length) | ||
html = html.replace(/\u0002(\d+)~/g, function (q, n) { return p[n] }) | ||
} | ||
if (opts.compact) html = html.replace(/> <([-\w\/])/g, '><$1') | ||
@@ -306,3 +314,3 @@ | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
@@ -333,2 +341,3 @@ function scopedCSS(tag, style) { | ||
function compileCSS(style, tag, type, scoped, opts) { | ||
if (!type) type = opts.style | ||
@@ -449,3 +458,3 @@ if (type) { | ||
var | ||
CUST_TAG = /^<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^<\/\1\s*>|>(.*)<\/\1\s*>)/gim, | ||
CUST_TAG = /^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/gim, | ||
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi, | ||
@@ -468,3 +477,3 @@ SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi') | ||
.replace(/\r\n?/g, '\n') | ||
.replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
.replace(CUST_TAG, function (_, indent, tagName, attribs, body, body2) { | ||
@@ -479,4 +488,3 @@ var | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -490,2 +498,3 @@ if (body2) body = body2 | ||
else { | ||
body = body.replace(_regEx('^' + indent, 'gm'), '') | ||
@@ -492,0 +501,0 @@ body = body.replace(STYLE, function (_, _attrs, _style) { |
@@ -64,4 +64,5 @@ /** | ||
function q(s) { | ||
//return "'" + (s ? s.replace(/\\/g, '\\\\').replace(/(^|[^\\])'/g, "$1\\'") : '') + "'" | ||
return "'" + (s ? s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") : '') + "'" | ||
return "'" + (s ? s | ||
.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, '\\r') : | ||
'') + "'" | ||
} | ||
@@ -78,3 +79,3 @@ | ||
return 'riot.tag2(' + q(name) + c + q(html) + c + q(css) + c + q(attrs) + | ||
return 'riot.tag2(\'' + name + "'" + c + q(html) + c + q(css) + c + q(attrs) + | ||
', function(opts) {\n' + js + s | ||
@@ -209,3 +210,3 @@ } | ||
_bp = brackets.array(opts.brackets) | ||
html = html.replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
html = html.replace(/\r\n?/g, '\n').replace(HTML_COMMENT, '').replace(TRIM_TRAIL, '') | ||
} | ||
@@ -227,6 +228,13 @@ if (!pcex) pcex = [] | ||
// tags parsed, now compact whitespace, or preserve if `opts.whitespace` is set | ||
html = opts.whitespace ? | ||
html.replace(/\r\n?|\n/g, '\\n') : html.trim().replace(/\s+/g, ' ') | ||
// tags parsed, now compact whitespace if `opts.whitespace` is not set | ||
if (!opts.whitespace) { | ||
var p = [], | ||
pre = /<pre(?:\s+[^'">]+(?:(?:"[^"]*"|'[^']*')[^'">]*)*|\s*)>[\s\S]*<\/pre\s*>/gi | ||
html = html.replace(pre, function (q) { | ||
return '\u0002' + (p.push(q) - 1) + '~' }).trim().replace(/\s+/g, ' ') | ||
if (p.length) | ||
html = html.replace(/\u0002(\d+)~/g, function (q, n) { return p[n] }) | ||
} | ||
// for `opts.compact`, remove whitespace between tags | ||
@@ -238,3 +246,2 @@ if (opts.compact) html = html.replace(/> <([-\w\/])/g, '><$1') | ||
// JavaScript Compilation | ||
@@ -325,3 +332,3 @@ // ---------------------- | ||
// Prepare regex to match CSS selectors, excluding those beginning with '@'. | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
var CSS_SELECTOR = _regEx('(}|{|^)[ ;]*([^@ ;{}][^{}]*)(?={)|' + brackets.R_STRINGS.source, 'g') | ||
@@ -368,2 +375,3 @@ // Parses styles enclosed in a "scoped" tag (`scoped` is deprecated in HTML5). | ||
function compileCSS(style, tag, type, scoped, opts) { | ||
if (!type) type = opts.style | ||
@@ -408,3 +416,2 @@ if (type) { | ||
// Returns the value of any attribute, or the empty string for missing attribute. | ||
@@ -495,6 +502,18 @@ function getAttr(str, name) { | ||
var | ||
CUST_TAG = /^<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^<\/\1\s*>|>(.*)<\/\1\s*>)/gim, | ||
CUST_TAG = /^([ \t]*)<([-\w]+)(?:\s+([^'"\/>]+(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\s\S]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/gim, | ||
STYLE = /<style(\s+[^>]*)?>\n?([^<]*(?:<(?!\/style\s*>)[^<]*)*)<\/style\s*>/gi, | ||
SCRIPT = _regEx(STYLE.source.replace(/tyle/g, 'cript'), 'gi') | ||
/* | ||
An alternate routine for finding custom tags, not depending in indentation. | ||
Find openning tag, must be the first token in a line, after any whitespace. | ||
if it is a self-close tag, i.e. ends with />. we are done. | ||
Set counter to 1. | ||
Find the next '<tag' or '</tag', if '<tag' found increment counter, else decrement. | ||
When counter reach 0 we are done. | ||
var re1 = _regEx('<' + tagName + '[\\s/>]', 'ig'), re2 = _regEx('</' + tagName + '[\\s>]', 'ig') | ||
re1.lastIndex = TAG_START.lastIndex | ||
while (match1 = re1.) | ||
*/ | ||
/** | ||
@@ -538,3 +557,3 @@ * The main compiler processes all custom tags, one by one. | ||
.replace(/\r\n?/g, '\n') | ||
.replace(CUST_TAG, function (_, tagName, attribs, body, body2) { | ||
.replace(CUST_TAG, function (_, indent, tagName, attribs, body, body2) { | ||
@@ -552,4 +571,3 @@ // content can have attributes first, then html markup with zero or more script or | ||
// process the attributes, including their expressions | ||
attribs = !attribs ? '' : | ||
restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
attribs = !attribs ? '' : restoreExpr(parseAttrs(splitHtml(attribs, opts, pcex)), pcex) | ||
@@ -564,2 +582,4 @@ if (body2) body = body2 | ||
else { | ||
body = body.replace(_regEx('^' + indent, 'gm'), '') | ||
// get and process the style blocks | ||
@@ -566,0 +586,0 @@ body = body.replace(STYLE, function (_, _attrs, _style) { |
@@ -25,11 +25,4 @@ | ||
// Removes additional indentation of the source | ||
function unindent(src, dbg) { | ||
var indent = src.match(/^([ \t]*)</m) // only before first tag | ||
if (indent && indent[1]) src = src.replace(new RegExp('^' + indent[1], 'gm'), '') | ||
return src | ||
} | ||
// Runs the call to `riot.tag2` generated by the compiler | ||
function globalEval(js, opts, comp) { | ||
// Run the code generated by the compiler to call `riot.tag2` | ||
function globalEval(js) { | ||
var | ||
@@ -48,3 +41,3 @@ node = doc.createElement('script'), | ||
// After all scripts are compiled the given callback method is called. | ||
function compileScripts(fn) { | ||
function compileScripts(fn, exopt) { | ||
var | ||
@@ -73,3 +66,4 @@ scripts = doc.querySelectorAll('script[type="riot/tag"]'), | ||
url ? GET(url, compileTag, opts) : compileTag(unindent(script.innerHTML), opts) | ||
if (exopt) opts = extend(opts, exopt) | ||
url ? GET(url, compileTag, opts) : compileTag(script.innerHTML, opts) | ||
} | ||
@@ -81,3 +75,3 @@ } | ||
return function (arg, fn) { | ||
return function (arg, fn, opts) { | ||
@@ -87,6 +81,11 @@ if (typeof arg === 'string') { | ||
if (typeof fn === 'object') { | ||
opts = fn | ||
fn = false | ||
} | ||
if (/^\s*</.test(arg)) { // this is a bit faster than trim() | ||
// `riot.compile(tag [, true])` | ||
// returns the tag as a string, if `true` is given, do not execute. | ||
var js = compile(unindent(arg)) // fix: pass unindented src to compile, don't fake test | ||
// `riot.compile(tag [, true][, options])` | ||
var js = compile(arg, opts) | ||
if (!fn) globalEval(js) | ||
@@ -96,6 +95,6 @@ return js | ||
// `riot.compile(url [, callback])` | ||
// Loads the url and compiles all tags after which the callback is called. | ||
// `riot.compile(url [, callback][, options])` | ||
GET(arg, function (str) { | ||
var js = compile(str, {}, arg) // .tag do not need unindent | ||
var js = compile(str, opts, arg) | ||
globalEval(js) | ||
@@ -108,7 +107,14 @@ if (fn) fn(js, str) | ||
// `riot.compile([callback])` | ||
// Compile all tags defined with `<script type="riot/tag">`` to JavaScript. | ||
// Compile all tags defined with `<script type="riot/tag">` to JavaScript. | ||
// `riot.compile([callback][, options])` | ||
// must be a function | ||
fn = typeof arg !== 'function' ? undefined : arg | ||
// arg is the callback or the extra options object | ||
if (typeof arg === 'function') { | ||
opts = fn | ||
fn = arg | ||
} | ||
else { | ||
opts = arg | ||
fn = undefined | ||
} | ||
@@ -126,3 +132,3 @@ // all compiled | ||
promise = riot.observable() | ||
compileScripts(fn) | ||
compileScripts(fn, opts) | ||
} | ||
@@ -134,3 +140,3 @@ } | ||
// reassign mount methods | ||
// reassign mount methods ----- | ||
var mount = riot.mount | ||
@@ -143,4 +149,1 @@ | ||
} | ||
// @deprecated | ||
riot.mountTo = riot.mount |
{ | ||
"name": "riot-compiler", | ||
"version": "2.3.11", | ||
"version": "2.3.12", | ||
"description": "Compiler for riot .tag files", | ||
@@ -17,3 +17,4 @@ "main": "dist/compiler.js", | ||
"scripts": { | ||
"test": "make test" | ||
"test": "make test", | ||
"prepublish": "make build bump" | ||
}, | ||
@@ -31,3 +32,3 @@ "repository": { | ||
"dependencies": { | ||
"riot-tmpl": "^2.3.0" | ||
"riot-tmpl": "^2.3.12" | ||
}, | ||
@@ -34,0 +35,0 @@ "devDependencies": { |
@@ -49,3 +49,3 @@ | ||
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 }) | ||
testStr('<p>a\r</p>\r\r\n<p>\n</p>', '<p>a\n</p>\n\n<p>\n</p>', { whitespace: 1 }) | ||
}) | ||
@@ -52,0 +52,0 @@ |
@@ -67,2 +67,6 @@ describe('Scoped CSS', function() { | ||
}) | ||
it('compile empty style', function() { | ||
expect(render('h1 {} h2 { font-size: 130% }')) | ||
.to.equal('my-tag h1,[riot-tag="my-tag"] h1 {} my-tag h2,[riot-tag="my-tag"] h2 { font-size: 130% }') | ||
}) | ||
@@ -69,0 +73,0 @@ it('use a custom css parser to render the css', function() { |
@@ -102,5 +102,18 @@ var fs = require('fs'), | ||
it('The `whitespace` option preserves newlines and tabs', function () { | ||
testFile('empty') | ||
var src = [ | ||
'<whitespace>', | ||
'\t<p>xyz', | ||
'\t cc', | ||
'\t ss</p>', | ||
'</whitespace>' | ||
].join('\n'), | ||
str = compiler.compile(src, {whitespace: true}) | ||
expect(str).to.be('riot.tag2(\'whitespace\', \'\t<p>xyz\\n\t cc\\n\t ss</p>\\n\', \'\', \'\', function(opts) {\n});') | ||
}) | ||
it('Whitespace within <pre> tags is always preserved', function () { | ||
testFile('pre') | ||
}) | ||
it('Empty tag', function () { | ||
@@ -119,2 +132,6 @@ testFile('empty') | ||
it('Multiline tags must be open/closed with the same indentation, which is removed', function () { | ||
testFile('indentation') | ||
}) | ||
it('the `entities` option give access to the compiled parts', function () { | ||
@@ -121,0 +138,0 @@ var parts = compiler.compile(cat(fixtures, 'treeview.tag'), {entities: true}) |
133327
116
3004
Updatedriot-tmpl@^2.3.12