dist/handlebars.js in handlebars-source-1.0.9 vs dist/handlebars.js in handlebars-source-1.0.12

- old
+ new

@@ -18,49 +18,62 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@license */ // lib/handlebars/browser-prefix.js -var Handlebars = {}; - -(function(Handlebars, undefined) { +(function(undefined) { + var Handlebars = {}; ; // lib/handlebars/base.js -Handlebars.VERSION = "1.0.0-rc.3"; -Handlebars.COMPILER_REVISION = 2; +Handlebars.VERSION = "1.0.0"; +Handlebars.COMPILER_REVISION = 4; Handlebars.REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it - 2: '>= 1.0.0-rc.3' + 2: '== 1.0.0-rc.3', + 3: '== 1.0.0-rc.4', + 4: '>= 1.0.0' }; Handlebars.helpers = {}; Handlebars.partials = {}; +var toString = Object.prototype.toString, + functionType = '[object Function]', + objectType = '[object Object]'; + Handlebars.registerHelper = function(name, fn, inverse) { - if(inverse) { fn.not = inverse; } - this.helpers[name] = fn; + if (toString.call(name) === objectType) { + if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); } + Handlebars.Utils.extend(this.helpers, name); + } else { + if (inverse) { fn.not = inverse; } + this.helpers[name] = fn; + } }; Handlebars.registerPartial = function(name, str) { - this.partials[name] = str; + if (toString.call(name) === objectType) { + Handlebars.Utils.extend(this.partials, name); + } else { + this.partials[name] = str; + } }; Handlebars.registerHelper('helperMissing', function(arg) { if(arguments.length === 2) { return undefined; } else { - throw new Error("Could not find property '" + arg + "'"); + throw new Error("Missing helper: '" + arg + "'"); } }); -var toString = Object.prototype.toString, functionType = "[object Function]"; - Handlebars.registerHelper('blockHelperMissing', function(context, options) { var inverse = options.inverse || function() {}, fn = options.fn; var type = toString.call(context); @@ -110,10 +123,13 @@ Handlebars.registerHelper('each', function(context, options) { var fn = options.fn, inverse = options.inverse; var i = 0, ret = "", data; + var type = toString.call(context); + if(type === functionType) { context = context.call(this); } + if (options.data) { data = Handlebars.createFrame(options.data); } if(context && typeof context === 'object') { @@ -138,27 +154,30 @@ } return ret; }); -Handlebars.registerHelper('if', function(context, options) { - var type = toString.call(context); - if(type === functionType) { context = context.call(this); } +Handlebars.registerHelper('if', function(conditional, options) { + var type = toString.call(conditional); + if(type === functionType) { conditional = conditional.call(this); } - if(!context || Handlebars.Utils.isEmpty(context)) { + if(!conditional || Handlebars.Utils.isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); } }); -Handlebars.registerHelper('unless', function(context, options) { - return Handlebars.helpers['if'].call(this, context, {fn: options.inverse, inverse: options.fn}); +Handlebars.registerHelper('unless', function(conditional, options) { + return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn}); }); Handlebars.registerHelper('with', function(context, options) { - return options.fn(context); + var type = toString.call(context); + if(type === functionType) { context = context.call(this); } + + if (!Handlebars.Utils.isEmpty(context)) return options.fn(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); @@ -167,13 +186,13 @@ // 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,"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]], +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,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"params":27,"hash":28,"dataName":29,"param":30,"STRING":31,"INTEGER":32,"BOOLEAN":33,"hashSegments":34,"hashSegment":35,"ID":36,"EQUALS":37,"DATA":38,"pathSegments":39,"SEP":40,"$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:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",31:"STRING",32:"INTEGER",33:"BOOLEAN",36:"ID",37:"EQUALS",38:"DATA",40:"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],[27,2],[27,1],[30,1],[30,1],[30,1],[30,1],[30,1],[28,1],[34,2],[34,1],[35,3],[35,3],[35,3],[35,3],[35,3],[26,1],[26,1],[26,1],[29,2],[21,1],[39,3],[39,1]], performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { var $0 = $$.length - 1; switch (yystate) { case 1: return $$[$0-1]; @@ -210,11 +229,14 @@ break; case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); break; case 18: this.$ = $$[$0-1]; break; -case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]); +case 19: + // Parsing out the '&' escape token at this level saves ~500 bytes after min due to the removal of one parser node. + this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2][2] === '&'); + break; case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true); break; case 21: this.$ = new yy.PartialNode($$[$0-1]); break; @@ -228,11 +250,11 @@ break; case 26: this.$ = [[$$[$0-1]], $$[$0]]; break; case 27: this.$ = [[$$[$0]], null]; break; -case 28: this.$ = [[new yy.DataNode($$[$0])], null]; +case 28: this.$ = [[$$[$0]], null]; break; case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; break; case 30: this.$ = [$$[$0]]; break; @@ -242,11 +264,11 @@ break; case 33: this.$ = new yy.IntegerNode($$[$0]); break; case 34: this.$ = new yy.BooleanNode($$[$0]); break; -case 35: this.$ = new yy.DataNode($$[$0]); +case 35: this.$ = $$[$0]; break; case 36: this.$ = new yy.HashNode($$[$0]); break; case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; break; @@ -258,24 +280,30 @@ break; case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]; break; case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]; break; -case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])]; +case 43: this.$ = [$$[$0-2], $$[$0]]; break; case 44: this.$ = new yy.PartialNameNode($$[$0]); break; -case 45: this.$ = new yy.IdNode($$[$0]); +case 45: this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0])); break; -case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; +case 46: this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0])); break; -case 47: this.$ = [$$[$0]]; +case 47: this.$ = new yy.DataNode($$[$0]); break; +case 48: this.$ = new yy.IdNode($$[$0]); +break; +case 49: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; +break; +case 50: this.$ = [{part: $$[$0]}]; +break; } }, -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]}, +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],25:[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],25:[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],25:[1,16]},{17:23,18:[1,22],21:24,29:25,36:[1,28],38:[1,27],39: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],25:[2,8]},{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],25:[1,16]},{4:30,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],25:[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],25:[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],25:[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],25:[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],25:[2,15]},{17:31,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:32,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:33,21:24,29:25,36:[1,28],38:[1,27],39:26},{21:35,26:34,31:[1,36],32:[1,37],36:[1,28],39:26},{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],25:[1,16]},{17:23,21:24,29:25,36:[1,28],38:[1,27],39:26},{5:[2,4],7:38,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],25:[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],25:[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],25:[2,23]},{18:[1,39]},{18:[2,27],21:44,24:[2,27],27:40,28:41,29:48,30:42,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,28],24:[2,28]},{18:[2,48],24:[2,48],31:[2,48],32:[2,48],33:[2,48],36:[2,48],38:[2,48],40:[1,51]},{21:52,36:[1,28],39:26},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],38:[2,50],40:[2,50]},{10:53,20:[1,54]},{10:55,20:[1,54]},{18:[1,56]},{18:[1,57]},{24:[1,58]},{18:[1,59],21:60,36:[1,28],39:26},{18:[2,44],36:[2,44]},{18:[2,45],36:[2,45]},{18:[2,46],36:[2,46]},{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],25:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{18:[2,25],21:44,24:[2,25],28:61,29:48,30:62,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,26],24:[2,26]},{18:[2,30],24:[2,30],31:[2,30],32:[2,30],33:[2,30],36:[2,30],38:[2,30]},{18:[2,36],24:[2,36],35:63,36:[1,64]},{18:[2,31],24:[2,31],31:[2,31],32:[2,31],33:[2,31],36:[2,31],38:[2,31]},{18:[2,32],24:[2,32],31:[2,32],32:[2,32],33:[2,32],36:[2,32],38:[2,32]},{18:[2,33],24:[2,33],31:[2,33],32:[2,33],33:[2,33],36:[2,33],38:[2,33]},{18:[2,34],24:[2,34],31:[2,34],32:[2,34],33:[2,34],36:[2,34],38:[2,34]},{18:[2,35],24:[2,35],31:[2,35],32:[2,35],33:[2,35],36:[2,35],38:[2,35]},{18:[2,38],24:[2,38],36:[2,38]},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],37:[1,65],38:[2,50],40:[2,50]},{36:[1,66]},{18:[2,47],24:[2,47],31:[2,47],32:[2,47],33:[2,47],36:[2,47],38:[2,47]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{21:67,36:[1,28],39: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],25:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[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],25:[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],25:[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],25:[2,21]},{18:[1,68]},{18:[2,24],24:[2,24]},{18:[2,29],24:[2,29],31:[2,29],32:[2,29],33:[2,29],36:[2,29],38:[2,29]},{18:[2,37],24:[2,37],36:[2,37]},{37:[1,65]},{21:69,29:73,31:[1,70],32:[1,71],33:[1,72],36:[1,28],38:[1,27],39:26},{18:[2,49],24:[2,49],31:[2,49],32:[2,49],33:[2,49],36:[2,49],38:[2,49],40:[2,49]},{18:[1,74]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{18:[2,39],24:[2,39],36:[2,39]},{18:[2,40],24:[2,40],36:[2,40]},{18:[2,41],24:[2,41],36:[2,41]},{18:[2,42],24:[2,42],36:[2,42]},{18:[2,43],24:[2,43],36:[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],25:[2,18]}], +defaultActions: {17:[2,1]}, 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; @@ -552,88 +580,86 @@ lexer.options = {}; lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { var YYSTATE=YY_START switch($avoiding_name_collisions) { -case 0: +case 0: yy_.yytext = "\\"; return 14; +break; +case 1: if(yy_.yytext.slice(-1) !== "\\") this.begin("mu"); if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu"); if(yy_.yytext) return 14; break; -case 1: return 14; +case 2: return 14; break; -case 2: +case 3: 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: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15; +case 4: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15; break; -case 4: this.begin("par"); return 24; +case 5: return 25; break; -case 5: return 16; +case 6: return 16; break; -case 6: return 20; +case 7: return 20; break; -case 7: return 19; -break; case 8: return 19; break; -case 9: return 23; +case 9: return 19; break; case 10: return 23; break; -case 11: this.popState(); this.begin('com'); +case 11: return 22; break; -case 12: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; +case 12: this.popState(); this.begin('com'); break; -case 13: return 22; +case 13: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; break; -case 14: return 36; +case 14: return 22; break; -case 15: return 35; +case 15: return 37; break; -case 16: return 35; +case 16: return 36; break; -case 17: return 39; +case 17: return 36; break; -case 18: /*ignore whitespace*/ +case 18: return 40; break; -case 19: this.popState(); return 18; +case 19: /*ignore whitespace*/ break; -case 20: this.popState(); return 18; +case 20: this.popState(); return 24; break; -case 21: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30; +case 21: this.popState(); return 18; break; -case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30; +case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 31; break; -case 23: yy_.yytext = yy_.yytext.substr(1); return 28; +case 23: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 31; break; -case 24: return 32; +case 24: return 38; break; -case 25: return 32; +case 25: return 33; break; -case 26: return 31; +case 26: return 33; break; -case 27: return 35; +case 27: return 32; break; -case 28: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35; +case 28: return 36; break; -case 29: return 'INVALID'; +case 29: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 36; break; -case 30: /*ignore whitespace*/ +case 30: return 'INVALID'; break; -case 31: this.popState(); return 37; +case 31: return 5; break; -case 32: return 5; -break; } }; -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}}; +lexer.rules = [/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}\/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; +lexer.conditions = {"mu":{"rules":[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,30,31],"inclusive":false},"emu":{"rules":[3],"inclusive":false},"com":{"rules":[4],"inclusive":false},"INITIAL":{"rules":[0,1,2,31],"inclusive":true}}; return lexer;})() parser.lexer = lexer; function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; return new Parser; })();; @@ -686,17 +712,14 @@ this.partialName = partialName; this.context = context; }; Handlebars.AST.BlockNode = function(mustache, program, inverse, close) { - var verifyMatch = function(open, close) { - if(open.original !== close.original) { - throw new Handlebars.Exception(open.original + " doesn't match " + close.original); - } - }; + if(mustache.id.original !== close.original) { + throw new Handlebars.Exception(mustache.id.original + " doesn't match " + close.original); + } - verifyMatch(mustache.id, close); this.type = "block"; this.mustache = mustache; this.program = program; this.inverse = inverse; @@ -715,25 +738,28 @@ this.pairs = pairs; }; Handlebars.AST.IdNode = function(parts) { this.type = "ID"; - this.original = parts.join("."); - var dig = [], depth = 0; + var original = "", + dig = [], + depth = 0; for(var i=0,l=parts.length; i<l; i++) { - var part = parts[i]; + var part = parts[i].part; + original += (parts[i].separator || '') + part; if (part === ".." || part === "." || part === "this") { - if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + this.original); } + if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + original); } else if (part === "..") { depth++; } else { this.isScoped = true; } } else { dig.push(part); } } + this.original = original; this.parts = dig; this.string = dig.join('.'); this.depth = depth; // an ID is simple if it only has one part, and that part is not @@ -743,27 +769,29 @@ this.stringModeValue = this.string; }; Handlebars.AST.PartialNameNode = function(name) { this.type = "PARTIAL_NAME"; - this.name = name; + this.name = name.original; }; 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; + this.original = + this.string = + this.stringModeValue = string; }; Handlebars.AST.IntegerNode = function(integer) { this.type = "INTEGER"; - this.integer = integer; + this.original = + this.integer = integer; this.stringModeValue = Number(integer); }; Handlebars.AST.BooleanNode = function(bool) { this.type = "BOOLEAN"; @@ -813,18 +841,31 @@ var escapeChar = function(chr) { return escape[chr] || "&amp;"; }; Handlebars.Utils = { + extend: function(obj, value) { + for(var key in value) { + if(value.hasOwnProperty(key)) { + obj[key] = value[key]; + } + } + }, + escapeExpression: function(string) { // don't escape SafeStrings, since they're already safe if (string instanceof Handlebars.SafeString) { return string.toString(); } else if (string == null || string === false) { return ""; } + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = string.toString(); + if(!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); }, isEmpty: function(value) { @@ -840,11 +881,10 @@ ; // lib/handlebars/compiler/compiler.js /*jshint eqnull:true*/ var Compiler = Handlebars.Compiler = function() {}; -var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {}; // the foundHelper register will disambiguate helper lookup from finding a // function in a context. This is necessary for mustache compatibility, which // requires that context functions in blocks are evaluated by blockHelperMissing, // and then proceed as if the resulting value was provided to blockHelperMissing. @@ -1021,10 +1061,14 @@ for(var i=0, l=pairs.length; i<l; i++) { pair = pairs[i]; val = pair[1]; if (this.options.stringParams) { + if(val.depth) { + this.addDepth(val.depth); + } + this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', val.stringModeValue, val.type); } else { this.accept(val); } @@ -1104,11 +1148,11 @@ var params = this.setupFullMustacheParams(mustache, program, inverse), name = mustache.id.parts[0]; if (this.options.knownHelpers[name]) { this.opcode('invokeKnownHelper', params.length, name); - } else if (this.knownHelpersOnly) { + } else if (this.options.knownHelpersOnly) { throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name); } else { this.opcode('invokeHelper', params.length, name); } }, @@ -1129,11 +1173,19 @@ } }, DATA: function(data) { this.options.data = true; - this.opcode('lookupData', data.id); + if (data.id.isScoped || data.id.depth) { + throw new Handlebars.Exception('Scoped data references are not supported: ' + data.original); + } + + this.opcode('lookupData'); + var parts = data.id.parts; + for(var i=0, l=parts.length; i<l; i++) { + this.opcode('lookup', parts[i]); + } }, STRING: function(string) { this.opcode('pushString', string.string); }, @@ -1236,14 +1288,61 @@ return params; } }; +Handlebars.precompile = function(input, options) { + if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) { + throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input); + } + + options = options || {}; + if (!('data' in options)) { + options.data = true; + } + var ast = Handlebars.parse(input); + var environment = new Compiler().compile(ast, options); + return new Handlebars.JavaScriptCompiler().compile(environment, options); +}; + +Handlebars.compile = function(input, options) { + if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) { + throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input); + } + + options = options || {}; + if (!('data' in options)) { + options.data = true; + } + var compiled; + function compile() { + var ast = Handlebars.parse(input); + var environment = new Compiler().compile(ast, options); + var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true); + return Handlebars.template(templateSpec); + } + + // Template is only compiled on first use and cached after that point. + return function(context, options) { + if (!compiled) { + compiled = compile(); + } + return compiled.call(this, context, options); + }; +}; + +; +// lib/handlebars/compiler/javascript-compiler.js +/*jshint eqnull:true*/ + var Literal = function(value) { this.value = value; }; + +var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {}; + JavaScriptCompiler.prototype = { // PUBLIC API: You can override these methods in a subclass to provide // alternative compiled forms for name lookup and buffering semantics nameLookup: function(parent, name /* , type*/) { if (/^[0-9]+$/.test(name)) { @@ -1301,11 +1400,11 @@ var opcodes = environment.opcodes, opcode; this.i = 0; - for(l=opcodes.length; this.i<l; this.i++) { + for(var l=opcodes.length; this.i<l; this.i++) { opcode = opcodes[this.i]; if(opcode.opcode === 'DECLARE') { this[opcode.name] = opcode.value; } else { @@ -1328,12 +1427,13 @@ preamble: function() { var out = []; if (!this.isChild) { var namespace = this.namespace; - var copies = "helpers = helpers || " + namespace + ".helpers;"; - if (this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; } + + var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);"; + if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; } if (this.options.data) { copies = copies + " data = data || {};"; } out.push(copies); } else { out.push(''); } @@ -1358,11 +1458,13 @@ } // Generate minimizer alias mappings if (!this.isChild) { for (var alias in this.context.aliases) { - this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; + if (this.context.aliases.hasOwnProperty(alias)) { + this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; + } } } if (this.source[1]) { this.source[1] = "var " + this.source[1].substring(2) + ";"; @@ -1577,11 +1679,11 @@ // On stack, before: ... // On stack, after: data[id], ... // // Push the result of looking up `id` on the current data lookupData: function(id) { - this.push(this.nameLookup('data', id, 'data')); + this.push('data'); }, // [pushStringParam] // // On stack, before: ... @@ -1605,20 +1707,22 @@ emptyHash: function() { this.pushStackLiteral('{}'); if (this.options.stringParams) { this.register('hashTypes', '{}'); + this.register('hashContexts', '{}'); } }, pushHash: function() { - this.hash = {values: [], types: []}; + this.hash = {values: [], types: [], contexts: []}; }, popHash: function() { var hash = this.hash; this.hash = undefined; if (this.options.stringParams) { + this.register('hashContexts', '{' + hash.contexts.join(',') + '}'); this.register('hashTypes', '{' + hash.types.join(',') + '}'); } this.push('{\n ' + hash.values.join(',\n ') + '\n }'); }, @@ -1682,12 +1786,13 @@ // If the helper is not found, `helperMissing` is called. invokeHelper: function(paramSize, name) { this.context.aliases.helperMissing = 'helpers.helperMissing'; var helper = this.lastHelper = this.setupHelper(paramSize, name, true); + var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context'); - this.push(helper.name); + this.push(helper.name + ' || ' + nonHelper); this.replaceStack(function(name) { return name + ' ? ' + name + '.call(' + helper.callParams + ") " + ": helperMissing.call(" + helper.helperMissingParams + ")"; }); @@ -1757,18 +1862,22 @@ // // 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(), + context, type; if (this.options.stringParams) { type = this.popStack(); - this.popStack(); + context = this.popStack(); } var hash = this.hash; + if (context) { + hash.contexts.push("'" + key + "': " + context); + } if (type) { hash.types.push("'" + key + "': " + type); } hash.values.push("'" + key + "': (" + value + ")"); }, @@ -1825,16 +1934,11 @@ if(depth === 1) { programParams.push("depth0"); } else { programParams.push("depth" + (depth - 1)); } } - if(depths.length === 0) { - return "self.program(" + programParams.join(", ") + ")"; - } else { - programParams.shift(); - return "self.programWithDepth(" + programParams.join(", ") + ")"; - } + return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")"; }, register: function(name, val) { this.useRegister(name); this.source.push(name + " = " + val + ";"); @@ -1962,11 +2066,13 @@ quotedString: function(str) { return '"' + str .replace(/\\/g, '\\\\') .replace(/"/g, '\\"') .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') + '"'; + .replace(/\r/g, '\\r') + .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 + .replace(/\u2029/g, '\\u2029') + '"'; }, setupHelper: function(paramSize, name, missingParams) { var params = []; this.setupParams(paramSize, params, missingParams); @@ -2018,10 +2124,11 @@ } if (this.options.stringParams) { options.push("contexts:[" + contexts.join(",") + "]"); options.push("types:[" + types.join(",") + "]"); + options.push("hashContexts:hashContexts"); options.push("hashTypes:hashTypes"); } if(this.options.data) { options.push("data:data"); @@ -2066,51 +2173,10 @@ if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) { return true; } return false; }; - -Handlebars.precompile = function(input, options) { - if (!input || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) { - throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input); - } - - options = options || {}; - if (!('data' in options)) { - options.data = true; - } - var ast = Handlebars.parse(input); - var environment = new Compiler().compile(ast, options); - return new JavaScriptCompiler().compile(environment, options); -}; - -Handlebars.compile = function(input, options) { - if (!input || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) { - throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input); - } - - options = options || {}; - if (!('data' in options)) { - options.data = true; - } - var compiled; - function compile() { - var ast = Handlebars.parse(input); - var environment = new Compiler().compile(ast, options); - var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true); - return Handlebars.template(templateSpec); - } - - // Template is only compiled on first use and cached after that point. - return function(context, options) { - if (!compiled) { - compiled = compile(); - } - return compiled.call(this, context, options); - }; -}; - ; // lib/handlebars/runtime.js Handlebars.VM = { template: function(templateSpec) { @@ -2120,18 +2186,26 @@ invokePartial: Handlebars.VM.invokePartial, programs: [], program: function(i, fn, data) { var programWrapper = this.programs[i]; if(data) { - return Handlebars.VM.program(fn, data); - } else if(programWrapper) { - return programWrapper; - } else { - programWrapper = this.programs[i] = Handlebars.VM.program(fn); - return programWrapper; + programWrapper = Handlebars.VM.program(i, fn, data); + } else if (!programWrapper) { + programWrapper = this.programs[i] = Handlebars.VM.program(i, fn); } + return programWrapper; }, + merge: function(param, common) { + var ret = param || common; + + if (param && common) { + ret = {}; + Handlebars.Utils.extend(ret, common); + Handlebars.Utils.extend(ret, param); + } + return ret; + }, programWithDepth: Handlebars.VM.programWithDepth, noop: Handlebars.VM.noop, compilerInfo: null }; @@ -2158,25 +2232,31 @@ return result; }; }, - programWithDepth: function(fn, data, $depth) { - var args = Array.prototype.slice.call(arguments, 2); + programWithDepth: function(i, fn, data /*, $depth */) { + var args = Array.prototype.slice.call(arguments, 3); - return function(context, options) { + var program = function(context, options) { options = options || {}; return fn.apply(this, [context, options.data || data].concat(args)); }; + program.program = i; + program.depth = args.length; + return program; }, - program: function(fn, data) { - return function(context, options) { + program: function(i, fn, data) { + var program = function(context, options) { options = options || {}; return fn(context, options.data || data); }; + program.program = i; + program.depth = 0; + return program; }, noop: function() { return ""; }, invokePartial: function(partial, name, context, helpers, partials, data) { var options = { helpers: helpers, partials: partials, data: data }; @@ -2194,7 +2274,19 @@ }; Handlebars.template = Handlebars.VM.template; ; // lib/handlebars/browser-suffix.js -})(Handlebars); + if (typeof module === 'object' && module.exports) { + // CommonJS + module.exports = Handlebars; + + } else if (typeof define === "function" && define.amd) { + // AMD modules + define(function() { return Handlebars; }); + + } else { + // other, i.e. browser + this.Handlebars = Handlebars; + } +}).call(this); ;