Skip to content

Instantly share code, notes, and snippets.

@aMarCruz
Created August 31, 2015 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aMarCruz/7875b23c77012ff55d89 to your computer and use it in GitHub Desktop.
Save aMarCruz/7875b23c77012ff55d89 to your computer and use it in GitHub Desktop.
Alternative riot tmpl() function for precompiled expressions.
/*
-----------------------------------------------------------------------------
riot-tmpl/lib/brackets.js
brackets function returns a string or regexp based on fix '#@ #' brackets.
With a numeric parameter...
0,1 - the current left (0) or right (1) current brackets characters.
2,3 - the current left (2) or right (3) escaped brackets characters.
4 - regexp based on `/{|}/g`, matches any bracket.
5 - regexp based on `/\\({|})/g`, matches escaped brackets.
6 - regexp for test expression existence.
7 - regexp used by lib/browser/tag/each.js/loopkeys (internal)
With a regexp, returns the original regexp if the current brackets are the defaults,
or a new regexp with the default brackets replaced by the current, custom brackets.
**WARNING:** recreated regexps discards the /i and /m flags.
*/
// IIFE
var brackets = (function (undefined) {
// Cache on closure, initialized on first use and on bracket changes
var _b = [
'#@', '#',
'#@', '#',
/#@|#/g,
/\\(#@|#)/g,
/#@[^#]*#/,
/^\s*(#@)\s*([$\w]+)(?:\s*,\s*([$\w]+))?\s+in\s+(\S+?)\s*(#)/
]
/*
Rewrite regexp with the default brackets replaced with the custom ones.
Let the user choose whether to double escape characters.
*/
function regex(e) {
return new RegExp(
e.source.replace(/[{}]/g, function (b) { return pairs[b === '{' ? 2 : 3] }),
e.global ? 'g' : ''
)
}
/*
Exposed brackets() function, for track bracket changes.
*/
return function _brackets(reOrIdx) {
return reOrIdx instanceof RegExp ? regex(reOrIdx) : _b[reOrIdx]
}
})()
// IIFE for tmpl()
var tmpl = (function (undefined) {
var
cache = {
'#0': function () { return '' },
'#1': function () { return 'number' }
},
GLOB = typeof window === 'undefined' ? global : window
////------------------------------------------------------------------------
//// PUBLIC ENTRY POINT
////------------------------------------------------------------------------
/**
* Exposed tmpl() function.
* Return the template value of the cache, render with data.
* For precompiled expressions only.
*
* @param {string} str - One expression, or template with zero or more expressions
* @param {Object} data - For setting the context
* @returns {*} - Raw value of the expression, or the processed template
* @private
*/
return function _tmpl(str, data) {
// by using .call(data,data) there's no need to wrap `this`
return str && (
str.indexOf(brackets(0)) < 0 ?
str.replace(/\r\n?/g, '\n') : _getValue(str, data)
)
}
/*
Gets the value for the _tmpl function.
*/
function _getValue(str, D) {
var idx
idx = str.match(/#(@[^#])#$/)
if (!idx) {
throw new Error('Not a precompiled expression: "' + str + '"')
}
idx = idx[1]
if (idx) {
if (idx in cache) {
return cache[idx].call(D, D)
}
if (D && (idx in D)) {
return D[idx]
}
if (idx in GLOB) {
return GLOB[idx]
}
}
return undefined
}
/*
Adapted from:
http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
*/
_tmpl.hashCode = function _hashCode(str) {
var
hash = 0
if (str) {
for (var i = 0; i < str.length; ++i) {
hash = (hash << 5) - hash + str.charCodeAt(i)
}
}
return '@' + hash
}
/*
Register a new function in the cache
*/
_tmpl.addGetter = function _addExpr(idx, fn) {
if (!/^@[$\w\xA0-\xFF]+$/.test(idx)) {
throw new Error('Not an expression index: "' + idx + '"')
}
cache[idx] = fn
}
return _tmpl
})()
// end of IIFE for tmpl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment