diff --git a/CHANGELOG.md b/CHANGELOG.md
index fea58d8..9d56354 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,10 @@
# riot-tmpl Changes
### v2.3.21
-- Refactorization of `brackets`, now is ~8% faster.
+- Refactorization, now `tmpl` and `brackets` are ~5% faster.
- Removed unused `tmpl.isRaw` function (internal).
- Changes to comments.
+- Files to preprocess are moved from the "lib" to the "src" directory, "lib" was removed.
### v2.3.20
- Fixed lint issues with new .eslintrc.yml, almost compatible with [JavaScript Standard Style](http://standardjs.com/)
diff --git a/Makefile b/Makefile
index 0617ed3..a12c10f 100644
--- a/Makefile
+++ b/Makefile
@@ -22,13 +22,13 @@ test: build test-mocha test-karma
build: eslint
# rebuild all
@ mkdir -p $(DIST)
- @ $(JSPP) $(JSPP_RIOT_FLAGS) lib/index.js > $(DIST)riot.tmpl.js
- @ $(JSPP) $(JSPP_ES6_FLAGS) lib/index.js > $(DIST)es6.tmpl.js
- @ $(JSPP) $(JSPP_NODE_FLAGS) lib/index.js > $(DIST)tmpl.js
+ @ $(JSPP) $(JSPP_RIOT_FLAGS) src/index.js > $(DIST)riot.tmpl.js
+ @ $(JSPP) $(JSPP_ES6_FLAGS) src/index.js > $(DIST)es6.tmpl.js
+ @ $(JSPP) $(JSPP_NODE_FLAGS) src/index.js > $(DIST)tmpl.js
eslint:
# check code style
- @ $(ESLINT) -c ./.eslintrc.yml lib
+ @ $(ESLINT) -c ./.eslintrc.yml src
test-karma:
@ $(KARMA) start test/karma.conf.js
diff --git a/dist/es6.tmpl.js b/dist/es6.tmpl.js
index 8a56ded..e5d4bee 100644
--- a/dist/es6.tmpl.js
+++ b/dist/es6.tmpl.js
@@ -75,7 +75,7 @@ var brackets = (function (UNDEF) {
arr = arr.concat(pair.replace(/(?=[[\]()*+?.^$|])/g, '\\').split(' '))
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
- arr[5] = _rewrite(/\\({|})/g, arr)
+ arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
arr[6] = _rewrite(_pairs[6], arr)
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB)
arr[8] = pair
@@ -107,7 +107,7 @@ var brackets = (function (UNDEF) {
if (isexpr) {
if (match[2]) {
- re.lastIndex = skipBraces(match[2], re.lastIndex)
+ re.lastIndex = skipBraces(str, match[2], re.lastIndex)
continue
}
if (!match[3])
@@ -128,25 +128,25 @@ var brackets = (function (UNDEF) {
return parts
- function unescapeStr (str) {
+ function unescapeStr (s) {
if (tmpl || 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 (s, ch, ix) {
var
match,
recch = FINDBRACES[ch]
- recch.lastIndex = pos
- pos = 1
- while (match = recch.exec(str)) {
+ recch.lastIndex = ix
+ ix = 1
+ while (match = recch.exec(s)) {
if (match[1] &&
- !(match[1] === ch ? ++pos : --pos)) break
+ !(match[1] === ch ? ++ix : --ix)) break
}
- return pos ? str.length : recch.lastIndex
+ return ix ? s.length : recch.lastIndex
}
}
@@ -166,7 +166,7 @@ var brackets = (function (UNDEF) {
}
_brackets.array = function array (pair) {
- return pair ? _create(pair) : _pairs
+ return pair ? _create(pair) : _cache
}
function _reset (pair) {
@@ -197,7 +197,7 @@ var brackets = (function (UNDEF) {
get: function () { return _settings }
})
- /* istanbul ignore next: in the node version riot is not in the scope */
+ /* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
diff --git a/dist/riot.tmpl.js b/dist/riot.tmpl.js
index b0ab331..897016d 100644
--- a/dist/riot.tmpl.js
+++ b/dist/riot.tmpl.js
@@ -72,7 +72,7 @@ var brackets = (function (UNDEF) {
arr = arr.concat(pair.replace(/(?=[[\]()*+?.^$|])/g, '\\').split(' '))
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
- arr[5] = _rewrite(/\\({|})/g, arr)
+ arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
arr[6] = _rewrite(_pairs[6], arr)
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB)
arr[8] = pair
@@ -104,7 +104,7 @@ var brackets = (function (UNDEF) {
if (isexpr) {
if (match[2]) {
- re.lastIndex = skipBraces(match[2], re.lastIndex)
+ re.lastIndex = skipBraces(str, match[2], re.lastIndex)
continue
}
if (!match[3])
@@ -125,25 +125,25 @@ var brackets = (function (UNDEF) {
return parts
- function unescapeStr (str) {
+ function unescapeStr (s) {
if (tmpl || 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 (s, ch, ix) {
var
match,
recch = FINDBRACES[ch]
- recch.lastIndex = pos
- pos = 1
- while (match = recch.exec(str)) {
+ recch.lastIndex = ix
+ ix = 1
+ while (match = recch.exec(s)) {
if (match[1] &&
- !(match[1] === ch ? ++pos : --pos)) break
+ !(match[1] === ch ? ++ix : --ix)) break
}
- return pos ? str.length : recch.lastIndex
+ return ix ? s.length : recch.lastIndex
}
}
@@ -163,7 +163,7 @@ var brackets = (function (UNDEF) {
}
_brackets.array = function array (pair) {
- return pair ? _create(pair) : _pairs
+ return pair ? _create(pair) : _cache
}
function _reset (pair) {
@@ -194,7 +194,7 @@ var brackets = (function (UNDEF) {
get: function () { return _settings }
})
- /* istanbul ignore next: in the node version riot is not in the scope */
+ /* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
diff --git a/dist/tmpl.js b/dist/tmpl.js
index a4d8bf5..527178c 100644
--- a/dist/tmpl.js
+++ b/dist/tmpl.js
@@ -71,7 +71,7 @@
arr = arr.concat(pair.replace(/(?=[[\]()*+?.^$|])/g, '\\').split(' '))
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
- arr[5] = _rewrite(/\\({|})/g, arr)
+ arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
arr[6] = _rewrite(_pairs[6], arr)
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB)
arr[8] = pair
@@ -103,7 +103,7 @@
if (isexpr) {
if (match[2]) {
- re.lastIndex = skipBraces(match[2], re.lastIndex)
+ re.lastIndex = skipBraces(str, match[2], re.lastIndex)
continue
}
if (!match[3])
@@ -124,25 +124,25 @@
return parts
- function unescapeStr (str) {
+ function unescapeStr (s) {
if (tmpl || 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 (s, ch, ix) {
var
match,
recch = FINDBRACES[ch]
- recch.lastIndex = pos
- pos = 1
- while (match = recch.exec(str)) {
+ recch.lastIndex = ix
+ ix = 1
+ while (match = recch.exec(s)) {
if (match[1] &&
- !(match[1] === ch ? ++pos : --pos)) break
+ !(match[1] === ch ? ++ix : --ix)) break
}
- return pos ? str.length : recch.lastIndex
+ return ix ? s.length : recch.lastIndex
}
}
@@ -162,7 +162,7 @@
}
_brackets.array = function array (pair) {
- return pair ? _create(pair) : _pairs
+ return pair ? _create(pair) : _cache
}
function _reset (pair) {
@@ -193,7 +193,7 @@
get: function () { return _settings }
})
- /* istanbul ignore next: in the node version riot is not in the scope */
+ /* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
diff --git a/package.json b/package.json
index 7b9fc24..618f10d 100644
--- a/package.json
+++ b/package.json
@@ -5,11 +5,10 @@
"main": "dist/tmpl.js",
"jsnext:main": "dist/es6.tmpl.js",
"directories": {
- "lib": "lib",
"doc": "doc"
},
"files": [
- "lib",
+ "src",
"doc",
"dist/*.js",
"test/**"
@@ -29,18 +28,18 @@
"engine"
],
"devDependencies": {
- "coveralls": "^2.11.4",
+ "coveralls": "^2.11.6",
"eslint": "^1.10.3",
"expect.js": "^0.3.1",
- "istanbul": "^0.4.1",
+ "istanbul": "^0.4.2",
"jspreproc": "^0.2.7",
- "karma": "^0.13.15",
+ "karma": "^0.13.19",
"karma-browserstack-launcher": "^0.1.6",
"karma-coverage": "^0.5.3",
"karma-mocha": "^0.2.1",
- "karma-phantomjs-launcher": "^0.2.1",
- "mocha": "^2.3.4",
- "phantomjs": "^1.9.19",
+ "karma-phantomjs-launcher": "^0.2.3",
+ "mocha": "^2.4.4",
+ "phantomjs": "^2.1.2",
"riot-bump": "^1.0.0"
},
"author": "Muut, Inc. and other contributors",
diff --git a/lib/brackets.js b/src/brackets.js
similarity index 97%
rename from lib/brackets.js
rename to src/brackets.js
index 21a3c20..5efe686 100644
--- a/lib/brackets.js
+++ b/src/brackets.js
@@ -167,7 +167,7 @@ var brackets = (function (UNDEF) {
arr = arr.concat(pair.replace(/(?=[[\]()*+?.^$|])/g, '\\').split(' '))
arr[$_RIX_TEST] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[$_RIX_TEST], arr)
- arr[$_RIX_ESC] = _rewrite(/\\({|})/g, arr)
+ arr[$_RIX_ESC] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[$_RIX_ESC], arr)
arr[$_RIX_OPEN] = _rewrite(_pairs[$_RIX_OPEN], arr) // for _split()
arr[$_RIX_CLOSE] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB)
arr[$_RIX_PAIR] = pair
@@ -314,6 +314,8 @@ var brackets = (function (UNDEF) {
/**
* Returns an array with brackets information, defaults to the current brackets.
+ * (the `brackets` module in the node version of the compiler allways defaults
+ * to the predefined riot brackets `{ }`).
*
* _This function is for internal use._
* @param {string} [pair] - If used, returns info for this brackets
@@ -321,7 +323,7 @@ var brackets = (function (UNDEF) {
* @private
*/
_brackets.array = function array (pair) {
- return pair ? _create(pair) : _pairs
+ return pair ? _create(pair) : _cache
}
/**
@@ -366,7 +368,7 @@ var brackets = (function (UNDEF) {
get: function () { return _settings }
})
- /* istanbul ignore next: in the node version riot is not in the scope */
+ /* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
diff --git a/lib/index.js b/src/index.js
similarity index 100%
rename from lib/index.js
rename to src/index.js
diff --git a/lib/tmpl.js b/src/tmpl.js
similarity index 83%
rename from lib/tmpl.js
rename to src/tmpl.js
index 937d23d..db0f845 100644
--- a/lib/tmpl.js
+++ b/src/tmpl.js
@@ -58,10 +58,11 @@ var tmpl = (function () {
}
/**
- * Checks if the expression or template is marked for output raw HTML text.
+ * Checks if the expression or template is marked for to output raw HTML text.
*
* @param {string } expr - Expression to search
* @returns {boolean} `true` if the expression is for raw html.
+ * @function
*/
_tmpl.haveRaw = brackets.hasRaw
@@ -75,24 +76,30 @@ var tmpl = (function () {
_tmpl.hasExpr = brackets.hasExpr
/**
- * Parse the `each` expression to detect how to map the collection data to the
+ * Parses the `each` expression to detect how to map the collection data to the
* children tags. Used by riot browser/tag/each.js
*
* {key, i in items} -> { key, pos, val }
*
* @param {String} expr - string passed in the 'each' attribute
- * @returns {Object} object needed to check how the items in the collection
+ * @returns {Object} The object needed to check how the items in the collection
* should be mapped to the children tags.
* @function
*/
_tmpl.loopKeys = brackets.loopKeys
/**
- * Function to handle errors in the evaluation of expressions.
+ * Holds a custom function to handle evaluation errors.
+ *
+ * This property allows to detect errors _in the evaluation_, by setting its value to a
+ * function that receives the generated Error object, augmented with an object `riotData`
+ * containing the properties `tagName` and `_riot_id` of the context at error time.
+ *
+ * Other (usually fatal) errors, such as "Parse Error" generated by the Function
+ * constructor, are not intercepted.
*
- * You can set errorHandler to one function that receives the error object
- * generated, with an added "riotData" property, an object containing the
- * tagName and `_riot_id` in the context at the error time.
+ * If this property is not set, or set to falsy, as in previous versions the error
+ * is silently ignored.
*
* @type {function}
* @static
@@ -104,6 +111,7 @@ var tmpl = (function () {
*
* @param {Error} err - The Error instance generated by the exception
* @param {object} ctx - The context
+ * @private
*/
function _logErr (err, ctx) {
@@ -120,8 +128,11 @@ var tmpl = (function () {
/**
* Creates a function instance to get a value from the received template string.
*
+ * It'll halt the app if the expression has errors (Parse Error or SyntaxError).
+ *
* @param {string} str - The template. Can include zero or more expressions
- * @returns {Function} - An instance of Function with the compiled template.
+ * @returns {Function} An instance of Function with the compiled template.
+ * @private
*/
function _create (str) {
@@ -136,9 +147,7 @@ var tmpl = (function () {
//#endif
// Now, we can create the function to return by calling the Function constructor.
- // It'll halt the app if the expression has errors (Parse Error or SyntaxError).
// The parameter `E` is the error handler for runtime only.
-
return new Function('E', expr + ';')
}
@@ -157,6 +166,7 @@ var tmpl = (function () {
*
* @param {string} str - Raw template string, without comments
* @returns {string} Processed template, ready for evaluation.
+ * @private
*/
function _getTmpl (str) {
var
@@ -205,20 +215,6 @@ var tmpl = (function () {
return expr
}
- // For shorthand names, riot supports a limited subset of the full w3c/html specs
- // for non-quoted identifiers (closer to CSS1 that CSS2).
- // This is the regex used for recognition:
- //
- // `-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*`
- //
- // The regex accepts almost all ISO-8859-1 alphanumeric characters within an html
- // identifier. Doesn't works with escaped codepoints.
- // You can use Unicode code points beyond `\u00FF` by quoting the names (not recommended).
- //
- // See:
- // http://www.w3.org/TR/CSS21/grammar.html#scanner
- // http://www.w3.org/TR/CSS21/syndata.html#tokenization
-
var
RE_BREND = {
'(': /[()]/g,
@@ -230,10 +226,21 @@ var tmpl = (function () {
/**
* Parses an individual expression `{expression}` or shorthand `{name: expression, ...}`
*
+ * For shorthand names, riot supports a limited subset of the full w3c/html specs of
+ * non-quoted identifiers (closer to CSS1 that CSS2).
+ *
+ * The regex used for recognition is `-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*`.
+ *
+ * This regex accepts almost all ISO-8859-1 alphanumeric characters within an html
+ * identifier. Doesn't works with escaped codepoints, but you can use Unicode code points
+ * beyond `\u00FF` by quoting the names (not recommended).
+ *
* @param {string} expr - The expression, without brackets
* @param {number} asText - 0: raw value, 1: falsy as "", except 0
* @param {Array} qstr - Where to store hidden quoted strings and regexes
* @returns {string} Code to evaluate the expression.
+ * @see {@link http://www.w3.org/TR/CSS21/grammar.html#scanner}
+ * {@link http://www.w3.org/TR/CSS21/syndata.html#tokenization}
* @private
*/
function _parseExpr (expr, asText, qstr) {
@@ -319,7 +326,21 @@ var tmpl = (function () {
JS_VARNAME = /[,{][$\w]+:|(^ *|[^$\w\.])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g,
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/
- // Generates code to evaluate an expression avoiding breaking on undefined vars.
+ /**
+ * Generates code to evaluate an expression avoiding breaking on undefined vars.
+ *
+ * This function include a try..catch block only if needed, if this block is not included,
+ * the generated code has no return statement.
+ *
+ * This `isFinite`, `isNaN`, `Date`, `RegExp`, and `Math` keywords are not wrapped
+ * for context detection (defaults to the global object).
+ *
+ * @param {string} expr - Normalized expression, without brackets
+ * @param {boolean} asText - If trueish, the output is converted to text, not raw values
+ * @param {string} [key] - For shorthands, the key name
+ * @returns {string} Compiled expression.
+ * @private
+ */
function _wrapExpr (expr, asText, key) {
var tb