dist/handlebars.js in handlebars-source-1.0.0 vs dist/handlebars.js in handlebars-source-1.0.7

- old
+ new

@@ -3,11 +3,11 @@ /*jshint eqnull:true*/ this.Handlebars = {}; (function(Handlebars) { -Handlebars.VERSION = "1.0.rc.1"; +Handlebars.VERSION = "1.0.rc.2"; Handlebars.helpers = {}; Handlebars.partials = {}; Handlebars.registerHelper = function(name, fn, inverse) { @@ -60,26 +60,57 @@ var obj = new Handlebars.K(); Handlebars.K.prototype = null; return obj; }; +Handlebars.logger = { + DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3, + + methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'}, + + // can be overridden in the host environment + log: function(level, obj) { + if (Handlebars.logger.level <= level) { + var method = Handlebars.logger.methodMap[level]; + if (typeof console !== 'undefined' && console[method]) { + console[method].call(console, obj); + } + } + } +}; + +Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); }; + Handlebars.registerHelper('each', function(context, options) { var fn = options.fn, inverse = options.inverse; - var ret = "", data; + var i = 0, ret = "", data; if (options.data) { data = Handlebars.createFrame(options.data); } - if(context && context.length > 0) { - for(var i=0, j=context.length; i<j; i++) { - if (data) { data.index = i; } - ret = ret + fn(context[i], { data: data }); + if(context && typeof context === 'object') { + if(context instanceof Array){ + for(var j = context.length; i<j; i++) { + if (data) { data.index = i; } + ret = ret + fn(context[i], { data: data }); + } + } else { + for(var key in context) { + if(context.hasOwnProperty(key)) { + if(data) { data.key = key; } + ret = ret + fn(context[key], {data: data}); + i++; + } + } } - } else { + } + + if(i === 0){ ret = inverse(this); } + return ret; }); Handlebars.registerHelper('if', function(context, options) { var type = toString.call(context); @@ -102,118 +133,127 @@ Handlebars.registerHelper('with', function(context, options) { return options.fn(context); }); -Handlebars.registerHelper('log', function(context) { - Handlebars.log(context); +Handlebars.registerHelper('log', function(context, options) { + var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1; + Handlebars.log(level, context); }); }(this.Handlebars)); ; // lib/handlebars/compiler/parser.js /* Jison generated parser */ var handlebars = (function(){ var parser = {trace: function trace() { }, yy: {}, -symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"DATA":27,"param":28,"STRING":29,"INTEGER":30,"BOOLEAN":31,"hashSegments":32,"hashSegment":33,"ID":34,"EQUALS":35,"pathSegments":36,"SEP":37,"$accept":0,"$end":1}, -terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",27:"DATA",29:"STRING",30:"INTEGER",31:"BOOLEAN",34:"ID",35:"EQUALS",37:"SEP"}, -productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[17,1],[25,2],[25,1],[28,1],[28,1],[28,1],[28,1],[28,1],[26,1],[32,2],[32,1],[33,3],[33,3],[33,3],[33,3],[33,3],[21,1],[36,3],[36,1]], +symbols_: {"error":2,"root":3,"program":4,"EOF":5,"simpleInverse":6,"statements":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"partialName":25,"params":26,"hash":27,"DATA":28,"param":29,"STRING":30,"INTEGER":31,"BOOLEAN":32,"hashSegments":33,"hashSegment":34,"ID":35,"EQUALS":36,"PARTIAL_NAME":37,"pathSegments":38,"SEP":39,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"DATA",30:"STRING",31:"INTEGER",32:"BOOLEAN",35:"ID",36:"EQUALS",37:"PARTIAL_NAME",39:"SEP"}, +productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[26,2],[26,1],[29,1],[29,1],[29,1],[29,1],[29,1],[27,1],[33,2],[33,1],[34,3],[34,3],[34,3],[34,3],[34,3],[25,1],[21,1],[38,3],[38,1]], performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { var $0 = $$.length - 1; switch (yystate) { case 1: return $$[$0-1]; break; -case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]); +case 2: this.$ = new yy.ProgramNode([], $$[$0]); break; -case 3: this.$ = new yy.ProgramNode($$[$0]); +case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]); break; -case 4: this.$ = new yy.ProgramNode([]); +case 4: this.$ = new yy.ProgramNode($$[$0-1], []); break; -case 5: this.$ = [$$[$0]]; +case 5: this.$ = new yy.ProgramNode($$[$0]); break; -case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; +case 6: this.$ = new yy.ProgramNode([], []); break; -case 7: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]); +case 7: this.$ = new yy.ProgramNode([]); break; -case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]); +case 8: this.$ = [$$[$0]]; break; -case 9: this.$ = $$[$0]; +case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; break; -case 10: this.$ = $$[$0]; +case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]); break; -case 11: this.$ = new yy.ContentNode($$[$0]); +case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]); break; -case 12: this.$ = new yy.CommentNode($$[$0]); +case 12: this.$ = $$[$0]; break; -case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); +case 13: this.$ = $$[$0]; break; -case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); +case 14: this.$ = new yy.ContentNode($$[$0]); break; -case 15: this.$ = $$[$0-1]; +case 15: this.$ = new yy.CommentNode($$[$0]); break; case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); break; -case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true); +case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); break; -case 18: this.$ = new yy.PartialNode($$[$0-1]); +case 18: this.$ = $$[$0-1]; break; -case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]); +case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); break; -case 20: +case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true); break; -case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]; +case 21: this.$ = new yy.PartialNode($$[$0-1]); break; -case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]; +case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]); break; -case 23: this.$ = [[$$[$0-1]], $$[$0]]; +case 23: break; -case 24: this.$ = [[$$[$0]], null]; +case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]; break; -case 25: this.$ = [[new yy.DataNode($$[$0])], null]; +case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null]; break; -case 26: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; +case 26: this.$ = [[$$[$0-1]], $$[$0]]; break; -case 27: this.$ = [$$[$0]]; +case 27: this.$ = [[$$[$0]], null]; break; -case 28: this.$ = $$[$0]; +case 28: this.$ = [[new yy.DataNode($$[$0])], null]; break; -case 29: this.$ = new yy.StringNode($$[$0]); +case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; break; -case 30: this.$ = new yy.IntegerNode($$[$0]); +case 30: this.$ = [$$[$0]]; break; -case 31: this.$ = new yy.BooleanNode($$[$0]); +case 31: this.$ = $$[$0]; break; -case 32: this.$ = new yy.DataNode($$[$0]); +case 32: this.$ = new yy.StringNode($$[$0]); break; -case 33: this.$ = new yy.HashNode($$[$0]); +case 33: this.$ = new yy.IntegerNode($$[$0]); break; -case 34: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; +case 34: this.$ = new yy.BooleanNode($$[$0]); break; -case 35: this.$ = [$$[$0]]; +case 35: this.$ = new yy.DataNode($$[$0]); break; -case 36: this.$ = [$$[$0-2], $$[$0]]; +case 36: this.$ = new yy.HashNode($$[$0]); break; -case 37: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]; +case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; break; -case 38: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]; +case 38: this.$ = [$$[$0]]; break; -case 39: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]; +case 39: this.$ = [$$[$0-2], $$[$0]]; break; -case 40: this.$ = [$$[$0-2], new yy.DataNode($$[$0])]; +case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]; break; -case 41: this.$ = new yy.IdNode($$[$0]); +case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]; break; -case 42: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; +case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]; break; -case 43: this.$ = [$$[$0]]; +case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])]; break; +case 44: this.$ = new yy.PartialNameNode($$[$0]); +break; +case 45: this.$ = new yy.IdNode($$[$0]); +break; +case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; +break; +case 47: this.$ = [$$[$0]]; +break; } }, -table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,27:[1,24],34:[1,26],36:25},{17:27,21:23,27:[1,24],34:[1,26],36:25},{17:28,21:23,27:[1,24],34:[1,26],36:25},{17:29,21:23,27:[1,24],34:[1,26],36:25},{21:30,34:[1,26],36:25},{1:[2,1]},{6:31,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,32],21:23,27:[1,24],34:[1,26],36:25},{10:33,20:[1,34]},{10:35,20:[1,34]},{18:[1,36]},{18:[2,24],21:41,25:37,26:38,27:[1,45],28:39,29:[1,42],30:[1,43],31:[1,44],32:40,33:46,34:[1,47],36:25},{18:[2,25]},{18:[2,41],27:[2,41],29:[2,41],30:[2,41],31:[2,41],34:[2,41],37:[1,48]},{18:[2,43],27:[2,43],29:[2,43],30:[2,43],31:[2,43],34:[2,43],37:[2,43]},{18:[1,49]},{18:[1,50]},{18:[1,51]},{18:[1,52],21:53,34:[1,26],36:25},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:54,34:[1,26],36:25},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:41,26:55,27:[1,45],28:56,29:[1,42],30:[1,43],31:[1,44],32:40,33:46,34:[1,47],36:25},{18:[2,23]},{18:[2,27],27:[2,27],29:[2,27],30:[2,27],31:[2,27],34:[2,27]},{18:[2,33],33:57,34:[1,58]},{18:[2,28],27:[2,28],29:[2,28],30:[2,28],31:[2,28],34:[2,28]},{18:[2,29],27:[2,29],29:[2,29],30:[2,29],31:[2,29],34:[2,29]},{18:[2,30],27:[2,30],29:[2,30],30:[2,30],31:[2,30],34:[2,30]},{18:[2,31],27:[2,31],29:[2,31],30:[2,31],31:[2,31],34:[2,31]},{18:[2,32],27:[2,32],29:[2,32],30:[2,32],31:[2,32],34:[2,32]},{18:[2,35],34:[2,35]},{18:[2,43],27:[2,43],29:[2,43],30:[2,43],31:[2,43],34:[2,43],35:[1,59],37:[2,43]},{34:[1,60]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,61]},{18:[1,62]},{18:[2,21]},{18:[2,26],27:[2,26],29:[2,26],30:[2,26],31:[2,26],34:[2,26]},{18:[2,34],34:[2,34]},{35:[1,59]},{21:63,27:[1,67],29:[1,64],30:[1,65],31:[1,66],34:[1,26],36:25},{18:[2,42],27:[2,42],29:[2,42],30:[2,42],31:[2,42],34:[2,42],37:[2,42]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,36],34:[2,36]},{18:[2,37],34:[2,37]},{18:[2,38],34:[2,38]},{18:[2,39],34:[2,39]},{18:[2,40],34:[2,40]}], -defaultActions: {16:[2,1],24:[2,25],38:[2,23],55:[2,21]}, +table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],24:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22:[1,14],23:[1,15],24:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],24:[1,16]},{17:23,18:[1,22],21:24,28:[1,25],35:[1,27],38:26},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{4:28,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{17:30,21:24,28:[1,25],35:[1,27],38:26},{17:31,21:24,28:[1,25],35:[1,27],38:26},{17:32,21:24,28:[1,25],35:[1,27],38:26},{25:33,37:[1,34]},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],24:[1,16]},{17:23,21:24,28:[1,25],35:[1,27],38:26},{5:[2,4],7:35,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],24:[1,16]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],24:[2,23]},{18:[1,36]},{18:[2,27],21:41,26:37,27:38,28:[1,45],29:39,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,28]},{18:[2,45],28:[2,45],30:[2,45],31:[2,45],32:[2,45],35:[2,45],39:[1,48]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],39:[2,47]},{10:49,20:[1,50]},{10:51,20:[1,50]},{18:[1,52]},{18:[1,53]},{18:[1,54]},{18:[1,55],21:56,35:[1,27],38:26},{18:[2,44],35:[2,44]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],24:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{18:[2,25],21:41,27:57,28:[1,45],29:58,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,26]},{18:[2,30],28:[2,30],30:[2,30],31:[2,30],32:[2,30],35:[2,30]},{18:[2,36],34:59,35:[1,60]},{18:[2,31],28:[2,31],30:[2,31],31:[2,31],32:[2,31],35:[2,31]},{18:[2,32],28:[2,32],30:[2,32],31:[2,32],32:[2,32],35:[2,32]},{18:[2,33],28:[2,33],30:[2,33],31:[2,33],32:[2,33],35:[2,33]},{18:[2,34],28:[2,34],30:[2,34],31:[2,34],32:[2,34],35:[2,34]},{18:[2,35],28:[2,35],30:[2,35],31:[2,35],32:[2,35],35:[2,35]},{18:[2,38],35:[2,38]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],36:[1,61],39:[2,47]},{35:[1,62]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{21:63,35:[1,27],38:26},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],24:[2,21]},{18:[1,64]},{18:[2,24]},{18:[2,29],28:[2,29],30:[2,29],31:[2,29],32:[2,29],35:[2,29]},{18:[2,37],35:[2,37]},{36:[1,61]},{21:65,28:[1,69],30:[1,66],31:[1,67],32:[1,68],35:[1,27],38:26},{18:[2,46],28:[2,46],30:[2,46],31:[2,46],32:[2,46],35:[2,46],39:[2,46]},{18:[1,70]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],24:[2,22]},{18:[2,39],35:[2,39]},{18:[2,40],35:[2,40]},{18:[2,41],35:[2,41]},{18:[2,42],35:[2,42]},{18:[2,43],35:[2,43]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]}], +defaultActions: {17:[2,1],25:[2,28],38:[2,26],57:[2,24]}, parseError: function parseError(str, hash) { throw new Error(str); }, parse: function parse(input) { var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; @@ -504,112 +544,90 @@ if(yy_.yytext.slice(-1) !== "\\") this.popState(); if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1); return 14; break; -case 3: return 24; +case 3: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15; break; -case 4: return 16; +case 4: this.begin("par"); return 24; break; -case 5: return 20; +case 5: return 16; break; -case 6: return 19; +case 6: return 20; break; case 7: return 19; break; -case 8: return 23; +case 8: return 19; break; case 9: return 23; break; -case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; +case 10: return 23; break; -case 11: return 22; +case 11: this.popState(); this.begin('com'); break; -case 12: return 35; +case 12: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; break; -case 13: return 34; +case 13: return 22; break; -case 14: return 34; +case 14: return 36; break; -case 15: return 37; +case 15: return 35; break; -case 16: /*ignore whitespace*/ +case 16: return 35; break; -case 17: this.popState(); return 18; +case 17: return 39; break; -case 18: this.popState(); return 18; +case 18: /*ignore whitespace*/ break; -case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 29; +case 19: this.popState(); return 18; break; -case 20: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 29; +case 20: this.popState(); return 18; break; -case 21: yy_.yytext = yy_.yytext.substr(1); return 27; +case 21: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30; break; -case 22: return 31; +case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30; break; -case 23: return 31; +case 23: yy_.yytext = yy_.yytext.substr(1); return 28; break; -case 24: return 30; +case 24: return 32; break; -case 25: return 34; +case 25: return 32; break; -case 26: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 34; +case 26: return 31; break; -case 27: return 'INVALID'; +case 27: return 35; break; -case 28: return 5; +case 28: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35; break; +case 29: return 'INVALID'; +break; +case 30: /*ignore whitespace*/ +break; +case 31: this.popState(); return 37; +break; +case 32: return 5; +break; } }; -lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; -lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,28],"inclusive":true}}; +lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/]; +lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"par":{"rules":[30,31],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}}; return lexer;})(); parser.lexer = lexer; function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; return new Parser; -})(); -if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = handlebars; -exports.Parser = handlebars.Parser; -exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }; -exports.main = function commonjsMain(args) { - if (!args[1]) - throw new Error('Usage: '+args[0]+' FILE'); - var source, cwd; - if (typeof process !== 'undefined') { - source = require('fs').readFileSync(require('path').resolve(args[1]), "utf8"); - } else { - source = require("file").path(require("file").cwd()).join(args[1]).read({charset: "utf-8"}); - } - return exports.parser.parse(source); -}; -if (typeof module !== 'undefined' && require.main === module) { - exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); -} -}; -; +})();; // lib/handlebars/compiler/base.js Handlebars.Parser = handlebars; Handlebars.parse = function(string) { Handlebars.Parser.yy = Handlebars.AST; return Handlebars.Parser.parse(string); }; Handlebars.print = function(ast) { return new Handlebars.PrintVisitor().accept(ast); -}; - -Handlebars.logger = { - DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3, - - // override in the host environment - log: function(level, str) {} -}; - -Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); }; -; +};; // lib/handlebars/compiler/ast.js (function() { Handlebars.AST = {}; @@ -639,17 +657,14 @@ // if a mustache is an eligible helper but not a definite // helper, it is ambiguous, and will be resolved in a later // pass or at runtime. }; - Handlebars.AST.PartialNode = function(id, context) { - this.type = "partial"; - - // TODO: disallow complex IDs - - this.id = id; - this.context = context; + Handlebars.AST.PartialNode = function(partialName, context) { + this.type = "partial"; + this.partialName = partialName; + this.context = context; }; var verifyMatch = function(open, close) { if(open.original !== close.original) { throw new Handlebars.Exception(open.original + " doesn't match " + close.original); @@ -697,47 +712,59 @@ this.depth = depth; // an ID is simple if it only has one part, and that part is not // `..` or `this`. this.isSimple = parts.length === 1 && !this.isScoped && depth === 0; + + this.stringModeValue = this.string; }; + Handlebars.AST.PartialNameNode = function(name) { + this.type = "PARTIAL_NAME"; + this.name = name; + }; + Handlebars.AST.DataNode = function(id) { this.type = "DATA"; this.id = id; }; Handlebars.AST.StringNode = function(string) { this.type = "STRING"; this.string = string; + this.stringModeValue = string; }; Handlebars.AST.IntegerNode = function(integer) { this.type = "INTEGER"; this.integer = integer; + this.stringModeValue = Number(integer); }; Handlebars.AST.BooleanNode = function(bool) { this.type = "BOOLEAN"; this.bool = bool; + this.stringModeValue = bool === "true"; }; Handlebars.AST.CommentNode = function(comment) { this.type = "comment"; this.comment = comment; }; })();; // lib/handlebars/utils.js + +var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; + Handlebars.Exception = function(message) { var tmp = Error.prototype.constructor.apply(this, arguments); - for (var p in tmp) { - if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; } + // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. + for (var idx = 0; idx < errorProps.length; idx++) { + this[errorProps[idx]] = tmp[errorProps[idx]]; } - - this.message = tmp.message; }; Handlebars.Exception.prototype = new Error(); // Build out our basic SafeString type Handlebars.SafeString = function(string) { @@ -776,16 +803,12 @@ if(!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); }, isEmpty: function(value) { - if (typeof value === "undefined") { + if (!value && value !== 0) { return true; - } else if (value === null) { - return true; - } else if (value === false) { - return true; } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) { return true; } else { return false; } @@ -919,51 +942,56 @@ // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); - this.opcode('pushLiteral', '{}'); + this.opcode('pushHash'); this.opcode('blockValue'); } else { this.ambiguousMustache(mustache, program, inverse); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); - this.opcode('pushLiteral', '{}'); + this.opcode('pushHash'); this.opcode('ambiguousBlockValue'); } this.opcode('append'); }, hash: function(hash) { var pairs = hash.pairs, pair, val; - this.opcode('push', '{}'); + this.opcode('pushHash'); for(var i=0, l=pairs.length; i<l; i++) { pair = pairs[i]; val = pair[1]; - this.accept(val); + if (this.options.stringParams) { + this.opcode('pushStringParam', val.stringModeValue, val.type); + } else { + this.accept(val); + } + this.opcode('assignToHash', pair[0]); } }, partial: function(partial) { - var id = partial.id; + var partialName = partial.partialName; this.usePartial = true; if(partial.context) { this.ID(partial.context); } else { this.opcode('push', 'depth0'); } - this.opcode('invokePartial', id.original); + this.opcode('invokePartial', partialName.name); this.opcode('append'); }, content: function(content) { this.opcode('appendContent', content.string); @@ -1114,11 +1142,11 @@ if(param.depth) { this.addDepth(param.depth); } this.opcode('getContext', param.depth || 0); - this.opcode('pushStringParam', param.string); + this.opcode('pushStringParam', param.stringModeValue, param.type); } else { this[param.type](param); } } }, @@ -1128,11 +1156,11 @@ this.pushParams(params); if(mustache.hash) { this.hash(mustache.hash); } else { - this.opcode('pushLiteral', '{}'); + this.opcode('pushHash'); } return params; }, @@ -1145,11 +1173,11 @@ this.opcode('pushProgram', inverse); if(mustache.hash) { this.hash(mustache.hash); } else { - this.opcode('pushLiteral', '{}'); + this.opcode('pushHash'); } return params; } }; @@ -1320,11 +1348,11 @@ var params = ["depth0"]; this.setupParams(0, params); this.replaceStack(function(current) { params.splice(1, 0, current); - return current + " = blockHelperMissing.call(" + params.join(", ") + ")"; + return "blockHelperMissing.call(" + params.join(", ") + ")"; }); }, // [ambiguousBlockValue] // @@ -1432,11 +1460,11 @@ // the return value of the lambda resolvePossibleLambda: function() { this.context.aliases.functionType = '"function"'; this.replaceStack(function(current) { - return "typeof " + current + " === functionType ? " + current + "() : " + current; + return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current; }); }, // [lookup] // @@ -1467,15 +1495,30 @@ // On stack, after: string, currentContext, ... // // This opcode is designed for use in string mode, which // provides the string value of a parameter along with its // depth rather than resolving it immediately. - pushStringParam: function(string) { + pushStringParam: function(string, type) { this.pushStackLiteral('depth' + this.lastContext); - this.pushString(string); + + this.pushString(type); + + if (typeof string === 'string') { + this.pushString(string); + } else { + this.pushStackLiteral(string); + } }, + pushHash: function() { + this.push('{}'); + + if (this.options.stringParams) { + this.register('hashTypes', '{}'); + } + }, + // [pushString] // // On stack, before: ... // On stack, after: quotedString(string), ... // @@ -1577,11 +1620,11 @@ var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context'); var nextStack = this.nextStack(); this.source.push('if (foundHelper) { ' + nextStack + ' = foundHelper.call(' + helper.callParams + '); }'); - this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '() : ' + nextStack + '; }'); + this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.apply(depth0) : ' + nextStack + '; }'); }, // [invokePartial] // // On stack, before: context, ... @@ -1595,11 +1638,11 @@ if (this.options.data) { params.push("data"); } this.context.aliases.self = "this"; - this.pushStack("self.invokePartial(" + params.join(", ") + ");"); + this.pushStack("self.invokePartial(" + params.join(", ") + ")"); }, // [assignToHash] // // On stack, before: value, hash, ... @@ -1607,10 +1650,17 @@ // // Pops a value and hash off the stack, assigns `hash[key] = value` // and pushes the hash back onto the stack. assignToHash: function(key) { var value = this.popStack(); + + if (this.options.stringParams) { + var type = this.popStack(); + this.popStack(); + this.source.push("hashTypes['" + key + "'] = " + type + ";"); + } + var hash = this.topStack(); this.source.push(hash + "['" + key + "'] = " + value + ";"); }, @@ -1676,25 +1726,32 @@ this.compileStack.push(new Literal(item)); return item; }, pushStack: function(item) { - this.source.push(this.incrStack() + " = " + item + ";"); - this.compileStack.push("stack" + this.stackSlot); - return "stack" + this.stackSlot; + var stack = this.incrStack(); + this.source.push(stack + " = " + item + ";"); + this.compileStack.push(stack); + return stack; }, replaceStack: function(callback) { - var item = callback.call(this, this.topStack()); + var stack = this.topStack(), + item = callback.call(this, stack); - this.source.push(this.topStack() + " = " + item + ";"); - return "stack" + this.stackSlot; + // Prevent modification of the context depth variable. Through replaceStack + if (/^depth/.test(stack)) { + stack = this.nextStack(); + } + + this.source.push(stack + " = " + item + ";"); + return stack; }, nextStack: function(skipCompileStack) { var name = this.incrStack(); - this.compileStack.push("stack" + this.stackSlot); + this.compileStack.push(name); return name; }, incrStack: function() { this.stackSlot++; @@ -1745,11 +1802,11 @@ }, // the params and contexts arguments are passed in arrays // to fill in setupParams: function(paramSize, params) { - var options = [], contexts = [], param, inverse, program; + var options = [], contexts = [], types = [], param, inverse, program; options.push("hash:" + this.popStack()); inverse = this.popStack(); program = this.popStack(); @@ -1774,16 +1831,19 @@ for(var i=0; i<paramSize; i++) { param = this.popStack(); params.push(param); if(this.options.stringParams) { + types.push(this.popStack()); contexts.push(this.popStack()); } } if (this.options.stringParams) { options.push("contexts:[" + contexts.join(",") + "]"); + options.push("types:[" + types.join(",") + "]"); + options.push("hashTypes:hashTypes"); } if(this.options.data) { options.push("data:data"); } @@ -1825,19 +1885,31 @@ }; })(Handlebars.Compiler, Handlebars.JavaScriptCompiler); Handlebars.precompile = function(string, options) { - options = options || {}; + if (typeof string !== 'string') { + throw new Handlebars.Exception("You must pass a string to Handlebars.compile. You passed " + string); + } + options = options || {}; + if (!('data' in options)) { + options.data = true; + } var ast = Handlebars.parse(string); var environment = new Handlebars.Compiler().compile(ast, options); return new Handlebars.JavaScriptCompiler().compile(environment, options); }; Handlebars.compile = function(string, options) { - options = options || {}; + if (typeof string !== 'string') { + throw new Handlebars.Exception("You must pass a string to Handlebars.compile. You passed " + string); + } + options = options || {}; + if (!('data' in options)) { + options.data = true; + } var compiled; function compile() { var ast = Handlebars.parse(string); var environment = new Handlebars.Compiler().compile(ast, options); var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);