Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #8 from component/cache

create and cache a reusable function
  • Loading branch information...
commit 9aa69174a945ee79de65aaad54d7c4b2572c8072 2 parents 8bf05b2 + 6eec7f3
@Swatinem Swatinem authored
Showing with 47 additions and 17 deletions.
  1. +37 −15 index.js
  2. +10 −2 test/index.js
View
52 index.js
@@ -31,10 +31,8 @@ function t(str, obj, lang){
}
lang = lang || _lang;
if (t[lang]) str = t[lang][str] || str;
- return str.replace(/\{([^{}}]+)\}/g, function(_, name){
- var value = get(name, obj);
- return typeof value !== 'undefined' ? value : _;
- });
+ if (!cache[str]) cache[str] = makeFunction(str);
+ return cache[str](obj);
}
/**
@@ -51,19 +49,43 @@ exports.lang = function(code){
};
/**
- * Get Object's path value
+ * A cache for already generated functions
+ */
+var cache = {};
+
+/**
+ * Generate a reusable function from a string
*
- * @param {String} path
- * @param {Object} obj
- * @return {Mixed}
+ * @param {String} str
+ * @return {Function}
* @api private
*/
-
-function get (path, obj) {
- try {
- return new Function('_', 'return _.' + path)(obj);
- } catch (e) {
- return obj[path];
- }
+function makeFunction(str) {
+ var split = str.split(/(\{)([^{}}]+)\}/g);
+ var tries = [];
+ var exprs = [];
+ for (var i = 0; i < split.length; i++) {
+ var path = split[i];
+ if (path === '{') {
+ path = split[++i];
+ var expr;
+ var orig = JSON.stringify(path);
+ try {
+ new Function('_', 'return _.' + path);
+ tries.push('var val' + i + ' = _.' + path);
+ expr = 'val' + i;
+ } catch (e) {
+ expr = '_[' + orig + ']';
+ }
+ orig = '"{' + orig.substring(1, orig.length - 1) + '}"';
+ exprs.push('(val = ' + expr + ', typeof val !== "undefined" ? val : ' + orig + ')');
+ continue;
+ }
+ exprs.push(JSON.stringify(path));
+ }
+ if (tries.length) {
+ tries = 'try { ' + tries.join('; } catch (e) {}\ntry { ') + '; } catch (e) {}';
+ }
+ return new Function('_', 'var val;\n' + tries + '\nreturn [\n ' + exprs.join(',\n ') + '\n].join("");');
}
View
12 test/index.js
@@ -18,10 +18,18 @@ describe('t(str)', function(){
t('"{string}",{number}', {string: '', number: 0}).should.eql('"",0');
})
+ it('should support array lookup', function () {
+ t('{1}, {0}', ['first', 'second']).should.eql('second, first');
+ })
+
+ it('should support special chars', function () {
+ t('{white space punction :-)}', {'white space punction :-)': 'foo'}).should.eql('foo');
+ });
+
it('should ignore undefined tokens', function () {
t('Hello {name}').should.equal('Hello {name}');
- t('Hello {name}, this is odd syntax: {...}', { name: 'Tobi' })
- .should.equal('Hello Tobi, this is odd syntax: {...}');
+ t('Hello {name}, this is odd syntax: {...}, this is a sub-object: {foo.bar}', { name: 'Tobi' })
+ .should.equal('Hello Tobi, this is odd syntax: {...}, this is a sub-object: {foo.bar}');
})
it('should only tokenize innermost brackets', function() {
Please sign in to comment.
Something went wrong with that request. Please try again.