handlebars-source 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of handlebars-source might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/handlebars.js +1292 -1157
- data/handlebars.runtime.js +20 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7ed070b2fd379233146670c48e214ac5a591487
|
4
|
+
data.tar.gz: 4957de32810607c0596f94202f44f7832a296a77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44792c0ed6c83f3e3434bf2f06454015a897d55a0417006a4845dec1f6895f3b6f1696e2542591da36a0a883dffdbdba9e06c10bc172a16c37ef98535320339c
|
7
|
+
data.tar.gz: 6428de98a351d402e2ea81e6fbf8fb649fb72e1d24b7f424de3b53db7d6dfe061461137ab8019b59ef8afb98bbfb97b44edbdd5d229309869890c04ee5ca304d
|
data/handlebars.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
2
|
|
3
|
-
handlebars v1.
|
3
|
+
handlebars v1.3.0
|
4
4
|
|
5
5
|
Copyright (C) 2011 by Yehuda Katz
|
6
6
|
|
@@ -132,13 +132,25 @@ var __module5__ = (function() {
|
|
132
132
|
|
133
133
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
134
134
|
|
135
|
-
function Exception(
|
136
|
-
var
|
135
|
+
function Exception(message, node) {
|
136
|
+
var line;
|
137
|
+
if (node && node.firstLine) {
|
138
|
+
line = node.firstLine;
|
139
|
+
|
140
|
+
message += ' - ' + line + ':' + node.firstColumn;
|
141
|
+
}
|
142
|
+
|
143
|
+
var tmp = Error.prototype.constructor.call(this, message);
|
137
144
|
|
138
145
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
139
146
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
140
147
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
141
148
|
}
|
149
|
+
|
150
|
+
if (line) {
|
151
|
+
this.lineNumber = line;
|
152
|
+
this.column = node.firstColumn;
|
153
|
+
}
|
142
154
|
}
|
143
155
|
|
144
156
|
Exception.prototype = new Error();
|
@@ -154,7 +166,7 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
|
|
154
166
|
var Utils = __dependency1__;
|
155
167
|
var Exception = __dependency2__;
|
156
168
|
|
157
|
-
var VERSION = "1.
|
169
|
+
var VERSION = "1.3.0";
|
158
170
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
159
171
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
160
172
|
var REVISION_CHANGES = {
|
@@ -206,7 +218,7 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
|
|
206
218
|
if(arguments.length === 2) {
|
207
219
|
return undefined;
|
208
220
|
} else {
|
209
|
-
throw new
|
221
|
+
throw new Exception("Missing helper: '" + arg + "'");
|
210
222
|
}
|
211
223
|
});
|
212
224
|
|
@@ -350,11 +362,11 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
|
|
350
362
|
if (compilerRevision < currentRevision) {
|
351
363
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
352
364
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
353
|
-
throw new
|
365
|
+
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
354
366
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
355
367
|
} else {
|
356
368
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
357
|
-
throw new
|
369
|
+
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
358
370
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
359
371
|
}
|
360
372
|
}
|
@@ -364,7 +376,7 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
|
|
364
376
|
|
365
377
|
function template(templateSpec, env) {
|
366
378
|
if (!env) {
|
367
|
-
throw new
|
379
|
+
throw new Exception("No environment passed to template");
|
368
380
|
}
|
369
381
|
|
370
382
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
@@ -520,23 +532,52 @@ var __module7__ = (function(__dependency1__) {
|
|
520
532
|
var __exports__;
|
521
533
|
var Exception = __dependency1__;
|
522
534
|
|
535
|
+
function LocationInfo(locInfo){
|
536
|
+
locInfo = locInfo || {};
|
537
|
+
this.firstLine = locInfo.first_line;
|
538
|
+
this.firstColumn = locInfo.first_column;
|
539
|
+
this.lastColumn = locInfo.last_column;
|
540
|
+
this.lastLine = locInfo.last_line;
|
541
|
+
}
|
542
|
+
|
523
543
|
var AST = {
|
524
|
-
ProgramNode: function(statements, inverseStrip, inverse) {
|
544
|
+
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
545
|
+
var inverseLocationInfo, firstInverseNode;
|
546
|
+
if (arguments.length === 3) {
|
547
|
+
locInfo = inverse;
|
548
|
+
inverse = null;
|
549
|
+
} else if (arguments.length === 2) {
|
550
|
+
locInfo = inverseStrip;
|
551
|
+
inverseStrip = null;
|
552
|
+
}
|
553
|
+
|
554
|
+
LocationInfo.call(this, locInfo);
|
525
555
|
this.type = "program";
|
526
556
|
this.statements = statements;
|
527
557
|
this.strip = {};
|
528
558
|
|
529
559
|
if(inverse) {
|
530
|
-
|
560
|
+
firstInverseNode = inverse[0];
|
561
|
+
if (firstInverseNode) {
|
562
|
+
inverseLocationInfo = {
|
563
|
+
first_line: firstInverseNode.firstLine,
|
564
|
+
last_line: firstInverseNode.lastLine,
|
565
|
+
last_column: firstInverseNode.lastColumn,
|
566
|
+
first_column: firstInverseNode.firstColumn
|
567
|
+
};
|
568
|
+
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
569
|
+
} else {
|
570
|
+
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
571
|
+
}
|
531
572
|
this.strip.right = inverseStrip.left;
|
532
573
|
} else if (inverseStrip) {
|
533
574
|
this.strip.left = inverseStrip.right;
|
534
575
|
}
|
535
576
|
},
|
536
577
|
|
537
|
-
MustacheNode: function(rawParams, hash, open, strip) {
|
578
|
+
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
579
|
+
LocationInfo.call(this, locInfo);
|
538
580
|
this.type = "mustache";
|
539
|
-
this.hash = hash;
|
540
581
|
this.strip = strip;
|
541
582
|
|
542
583
|
// Open may be a string parsed from the parser or a passed boolean flag
|
@@ -548,6 +589,29 @@ var __module7__ = (function(__dependency1__) {
|
|
548
589
|
this.escaped = !!open;
|
549
590
|
}
|
550
591
|
|
592
|
+
if (rawParams instanceof AST.SexprNode) {
|
593
|
+
this.sexpr = rawParams;
|
594
|
+
} else {
|
595
|
+
// Support old AST API
|
596
|
+
this.sexpr = new AST.SexprNode(rawParams, hash);
|
597
|
+
}
|
598
|
+
|
599
|
+
this.sexpr.isRoot = true;
|
600
|
+
|
601
|
+
// Support old AST API that stored this info in MustacheNode
|
602
|
+
this.id = this.sexpr.id;
|
603
|
+
this.params = this.sexpr.params;
|
604
|
+
this.hash = this.sexpr.hash;
|
605
|
+
this.eligibleHelper = this.sexpr.eligibleHelper;
|
606
|
+
this.isHelper = this.sexpr.isHelper;
|
607
|
+
},
|
608
|
+
|
609
|
+
SexprNode: function(rawParams, hash, locInfo) {
|
610
|
+
LocationInfo.call(this, locInfo);
|
611
|
+
|
612
|
+
this.type = "sexpr";
|
613
|
+
this.hash = hash;
|
614
|
+
|
551
615
|
var id = this.id = rawParams[0];
|
552
616
|
var params = this.params = rawParams.slice(1);
|
553
617
|
|
@@ -565,19 +629,22 @@ var __module7__ = (function(__dependency1__) {
|
|
565
629
|
// pass or at runtime.
|
566
630
|
},
|
567
631
|
|
568
|
-
PartialNode: function(partialName, context, strip) {
|
632
|
+
PartialNode: function(partialName, context, strip, locInfo) {
|
633
|
+
LocationInfo.call(this, locInfo);
|
569
634
|
this.type = "partial";
|
570
635
|
this.partialName = partialName;
|
571
636
|
this.context = context;
|
572
637
|
this.strip = strip;
|
573
638
|
},
|
574
639
|
|
575
|
-
BlockNode: function(mustache, program, inverse, close) {
|
576
|
-
|
577
|
-
|
640
|
+
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
641
|
+
LocationInfo.call(this, locInfo);
|
642
|
+
|
643
|
+
if(mustache.sexpr.id.original !== close.path.original) {
|
644
|
+
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
578
645
|
}
|
579
646
|
|
580
|
-
this.type =
|
647
|
+
this.type = 'block';
|
581
648
|
this.mustache = mustache;
|
582
649
|
this.program = program;
|
583
650
|
this.inverse = inverse;
|
@@ -595,17 +662,20 @@ var __module7__ = (function(__dependency1__) {
|
|
595
662
|
}
|
596
663
|
},
|
597
664
|
|
598
|
-
ContentNode: function(string) {
|
665
|
+
ContentNode: function(string, locInfo) {
|
666
|
+
LocationInfo.call(this, locInfo);
|
599
667
|
this.type = "content";
|
600
668
|
this.string = string;
|
601
669
|
},
|
602
670
|
|
603
|
-
HashNode: function(pairs) {
|
671
|
+
HashNode: function(pairs, locInfo) {
|
672
|
+
LocationInfo.call(this, locInfo);
|
604
673
|
this.type = "hash";
|
605
674
|
this.pairs = pairs;
|
606
675
|
},
|
607
676
|
|
608
|
-
IdNode: function(parts) {
|
677
|
+
IdNode: function(parts, locInfo) {
|
678
|
+
LocationInfo.call(this, locInfo);
|
609
679
|
this.type = "ID";
|
610
680
|
|
611
681
|
var original = "",
|
@@ -617,11 +687,16 @@ var __module7__ = (function(__dependency1__) {
|
|
617
687
|
original += (parts[i].separator || '') + part;
|
618
688
|
|
619
689
|
if (part === ".." || part === "." || part === "this") {
|
620
|
-
if (dig.length > 0) {
|
621
|
-
|
622
|
-
else
|
690
|
+
if (dig.length > 0) {
|
691
|
+
throw new Exception("Invalid path: " + original, this);
|
692
|
+
} else if (part === "..") {
|
693
|
+
depth++;
|
694
|
+
} else {
|
695
|
+
this.isScoped = true;
|
696
|
+
}
|
697
|
+
} else {
|
698
|
+
dig.push(part);
|
623
699
|
}
|
624
|
-
else { dig.push(part); }
|
625
700
|
}
|
626
701
|
|
627
702
|
this.original = original;
|
@@ -636,37 +711,43 @@ var __module7__ = (function(__dependency1__) {
|
|
636
711
|
this.stringModeValue = this.string;
|
637
712
|
},
|
638
713
|
|
639
|
-
PartialNameNode: function(name) {
|
714
|
+
PartialNameNode: function(name, locInfo) {
|
715
|
+
LocationInfo.call(this, locInfo);
|
640
716
|
this.type = "PARTIAL_NAME";
|
641
717
|
this.name = name.original;
|
642
718
|
},
|
643
719
|
|
644
|
-
DataNode: function(id) {
|
720
|
+
DataNode: function(id, locInfo) {
|
721
|
+
LocationInfo.call(this, locInfo);
|
645
722
|
this.type = "DATA";
|
646
723
|
this.id = id;
|
647
724
|
},
|
648
725
|
|
649
|
-
StringNode: function(string) {
|
726
|
+
StringNode: function(string, locInfo) {
|
727
|
+
LocationInfo.call(this, locInfo);
|
650
728
|
this.type = "STRING";
|
651
729
|
this.original =
|
652
730
|
this.string =
|
653
731
|
this.stringModeValue = string;
|
654
732
|
},
|
655
733
|
|
656
|
-
IntegerNode: function(integer) {
|
734
|
+
IntegerNode: function(integer, locInfo) {
|
735
|
+
LocationInfo.call(this, locInfo);
|
657
736
|
this.type = "INTEGER";
|
658
737
|
this.original =
|
659
738
|
this.integer = integer;
|
660
739
|
this.stringModeValue = Number(integer);
|
661
740
|
},
|
662
741
|
|
663
|
-
BooleanNode: function(bool) {
|
742
|
+
BooleanNode: function(bool, locInfo) {
|
743
|
+
LocationInfo.call(this, locInfo);
|
664
744
|
this.type = "BOOLEAN";
|
665
745
|
this.bool = bool;
|
666
746
|
this.stringModeValue = bool === "true";
|
667
747
|
},
|
668
748
|
|
669
|
-
CommentNode: function(comment) {
|
749
|
+
CommentNode: function(comment, locInfo) {
|
750
|
+
LocationInfo.call(this, locInfo);
|
670
751
|
this.type = "comment";
|
671
752
|
this.comment = comment;
|
672
753
|
}
|
@@ -687,103 +768,105 @@ var __module9__ = (function() {
|
|
687
768
|
var handlebars = (function(){
|
688
769
|
var parser = {trace: function trace() { },
|
689
770
|
yy: {},
|
690
|
-
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"
|
691
|
-
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",32:"STRING",33:"INTEGER",34:"BOOLEAN",
|
692
|
-
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[
|
771
|
+
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
772
|
+
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",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
773
|
+
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
693
774
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
694
775
|
|
695
776
|
var $0 = $$.length - 1;
|
696
777
|
switch (yystate) {
|
697
|
-
case 1: return new yy.ProgramNode($$[$0-1]);
|
778
|
+
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
698
779
|
break;
|
699
|
-
case 2: return new yy.ProgramNode([]);
|
780
|
+
case 2: return new yy.ProgramNode([], this._$);
|
700
781
|
break;
|
701
|
-
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0]);
|
782
|
+
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
702
783
|
break;
|
703
|
-
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0]);
|
784
|
+
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
704
785
|
break;
|
705
|
-
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], []);
|
786
|
+
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
706
787
|
break;
|
707
|
-
case 6:this.$ = new yy.ProgramNode($$[$0]);
|
788
|
+
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
708
789
|
break;
|
709
|
-
case 7:this.$ = new yy.ProgramNode([]);
|
790
|
+
case 7:this.$ = new yy.ProgramNode([], this._$);
|
710
791
|
break;
|
711
|
-
case 8:this.$ = new yy.ProgramNode([]);
|
792
|
+
case 8:this.$ = new yy.ProgramNode([], this._$);
|
712
793
|
break;
|
713
794
|
case 9:this.$ = [$$[$0]];
|
714
795
|
break;
|
715
796
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
716
797
|
break;
|
717
|
-
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
|
798
|
+
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
718
799
|
break;
|
719
|
-
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
|
800
|
+
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
720
801
|
break;
|
721
802
|
case 13:this.$ = $$[$0];
|
722
803
|
break;
|
723
804
|
case 14:this.$ = $$[$0];
|
724
805
|
break;
|
725
|
-
case 15:this.$ = new yy.ContentNode($$[$0]);
|
806
|
+
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
726
807
|
break;
|
727
|
-
case 16:this.$ = new yy.CommentNode($$[$0]);
|
808
|
+
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
728
809
|
break;
|
729
|
-
case 17:this.$ = new yy.MustacheNode($$[$0-1]
|
810
|
+
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
730
811
|
break;
|
731
|
-
case 18:this.$ = new yy.MustacheNode($$[$0-1]
|
812
|
+
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
732
813
|
break;
|
733
814
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
734
815
|
break;
|
735
|
-
case 20:this.$ = new yy.MustacheNode($$[$0-1]
|
816
|
+
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
736
817
|
break;
|
737
|
-
case 21:this.$ = new yy.MustacheNode($$[$0-1]
|
818
|
+
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
738
819
|
break;
|
739
|
-
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]));
|
820
|
+
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
740
821
|
break;
|
741
822
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
742
823
|
break;
|
743
|
-
case 24:this.$ = [
|
824
|
+
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
744
825
|
break;
|
745
|
-
case 25:this.$ = [
|
826
|
+
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
746
827
|
break;
|
747
828
|
case 26:this.$ = $$[$0];
|
748
829
|
break;
|
749
|
-
case 27:this.$ = new yy.StringNode($$[$0]);
|
830
|
+
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
750
831
|
break;
|
751
|
-
case 28:this.$ = new yy.IntegerNode($$[$0]);
|
832
|
+
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
752
833
|
break;
|
753
|
-
case 29:this.$ = new yy.BooleanNode($$[$0]);
|
834
|
+
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
754
835
|
break;
|
755
836
|
case 30:this.$ = $$[$0];
|
756
837
|
break;
|
757
|
-
case 31
|
838
|
+
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
839
|
+
break;
|
840
|
+
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
758
841
|
break;
|
759
|
-
case
|
842
|
+
case 33:this.$ = [$$[$0-2], $$[$0]];
|
760
843
|
break;
|
761
|
-
case
|
844
|
+
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
762
845
|
break;
|
763
|
-
case
|
846
|
+
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
764
847
|
break;
|
765
|
-
case
|
848
|
+
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
766
849
|
break;
|
767
|
-
case
|
850
|
+
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
768
851
|
break;
|
769
|
-
case
|
852
|
+
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
770
853
|
break;
|
771
|
-
case
|
854
|
+
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
772
855
|
break;
|
773
|
-
case
|
856
|
+
case 40:this.$ = [{part: $$[$0]}];
|
774
857
|
break;
|
775
|
-
case
|
858
|
+
case 43:this.$ = [];
|
776
859
|
break;
|
777
|
-
case
|
860
|
+
case 44:$$[$0-1].push($$[$0]);
|
778
861
|
break;
|
779
|
-
case
|
862
|
+
case 47:this.$ = [$$[$0]];
|
780
863
|
break;
|
781
|
-
case
|
864
|
+
case 48:$$[$0-1].push($$[$0]);
|
782
865
|
break;
|
783
866
|
}
|
784
867
|
},
|
785
|
-
table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{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]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{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]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,
|
786
|
-
defaultActions: {3:[2,2],16:[2,1],50:[2,
|
868
|
+
table: [{3:1,4:2,5:[1,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],25:[1,15]},{1:[3]},{5:[1,16],8:17,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],25:[1,15]},{1:[2,2]},{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]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{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]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{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]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{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]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{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]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{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,66]},{18:[2,42]},{18:[1,67]},{8:17,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],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{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]},{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]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
869
|
+
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
787
870
|
parseError: function parseError(str, hash) {
|
788
871
|
throw new Error(str);
|
789
872
|
},
|
@@ -1101,64 +1184,68 @@ var __module9__ = (function() {
|
|
1101
1184
|
break;
|
1102
1185
|
case 3:strip(0,4); this.popState(); return 15;
|
1103
1186
|
break;
|
1104
|
-
case 4:return
|
1187
|
+
case 4:return 35;
|
1188
|
+
break;
|
1189
|
+
case 5:return 36;
|
1190
|
+
break;
|
1191
|
+
case 6:return 25;
|
1105
1192
|
break;
|
1106
|
-
case
|
1193
|
+
case 7:return 16;
|
1107
1194
|
break;
|
1108
|
-
case
|
1195
|
+
case 8:return 20;
|
1109
1196
|
break;
|
1110
|
-
case
|
1197
|
+
case 9:return 19;
|
1111
1198
|
break;
|
1112
|
-
case
|
1199
|
+
case 10:return 19;
|
1113
1200
|
break;
|
1114
|
-
case
|
1201
|
+
case 11:return 23;
|
1115
1202
|
break;
|
1116
|
-
case
|
1203
|
+
case 12:return 22;
|
1117
1204
|
break;
|
1118
|
-
case
|
1205
|
+
case 13:this.popState(); this.begin('com');
|
1119
1206
|
break;
|
1120
|
-
case
|
1207
|
+
case 14:strip(3,5); this.popState(); return 15;
|
1121
1208
|
break;
|
1122
|
-
case
|
1209
|
+
case 15:return 22;
|
1123
1210
|
break;
|
1124
|
-
case
|
1211
|
+
case 16:return 41;
|
1125
1212
|
break;
|
1126
|
-
case
|
1213
|
+
case 17:return 40;
|
1127
1214
|
break;
|
1128
|
-
case
|
1215
|
+
case 18:return 40;
|
1129
1216
|
break;
|
1130
|
-
case
|
1217
|
+
case 19:return 44;
|
1131
1218
|
break;
|
1132
|
-
case
|
1219
|
+
case 20:// ignore whitespace
|
1133
1220
|
break;
|
1134
|
-
case
|
1221
|
+
case 21:this.popState(); return 24;
|
1135
1222
|
break;
|
1136
|
-
case
|
1223
|
+
case 22:this.popState(); return 18;
|
1137
1224
|
break;
|
1138
|
-
case
|
1225
|
+
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
1139
1226
|
break;
|
1140
|
-
case
|
1227
|
+
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
1141
1228
|
break;
|
1142
|
-
case
|
1229
|
+
case 25:return 42;
|
1143
1230
|
break;
|
1144
|
-
case
|
1231
|
+
case 26:return 34;
|
1145
1232
|
break;
|
1146
|
-
case
|
1233
|
+
case 27:return 34;
|
1147
1234
|
break;
|
1148
|
-
case
|
1235
|
+
case 28:return 33;
|
1149
1236
|
break;
|
1150
|
-
case
|
1237
|
+
case 29:return 40;
|
1151
1238
|
break;
|
1152
|
-
case
|
1239
|
+
case 30:yy_.yytext = strip(1,2); return 40;
|
1153
1240
|
break;
|
1154
|
-
case
|
1241
|
+
case 31:return 'INVALID';
|
1155
1242
|
break;
|
1156
|
-
case
|
1243
|
+
case 32:return 5;
|
1157
1244
|
break;
|
1158
1245
|
}
|
1159
1246
|
};
|
1160
|
-
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s])))/,/^(?:false(?=([~}\s])))/,/^(?:-?[0-9]+(?=([~}\s])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
1161
|
-
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,30],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,
|
1247
|
+
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
1248
|
+
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,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
1162
1249
|
return lexer;})()
|
1163
1250
|
parser.lexer = lexer;
|
1164
1251
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
@@ -1189,1382 +1276,1428 @@ var __module8__ = (function(__dependency1__, __dependency2__) {
|
|
1189
1276
|
return __exports__;
|
1190
1277
|
})(__module9__, __module7__);
|
1191
1278
|
|
1192
|
-
// handlebars/compiler/
|
1193
|
-
var
|
1279
|
+
// handlebars/compiler/compiler.js
|
1280
|
+
var __module10__ = (function(__dependency1__) {
|
1194
1281
|
"use strict";
|
1195
|
-
var __exports__;
|
1196
|
-
var
|
1197
|
-
var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
|
1198
|
-
var log = __dependency1__.log;
|
1282
|
+
var __exports__ = {};
|
1283
|
+
var Exception = __dependency1__;
|
1199
1284
|
|
1200
|
-
function
|
1201
|
-
this.value = value;
|
1202
|
-
}
|
1285
|
+
function Compiler() {}
|
1203
1286
|
|
1204
|
-
|
1287
|
+
__exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
|
1288
|
+
// function in a context. This is necessary for mustache compatibility, which
|
1289
|
+
// requires that context functions in blocks are evaluated by blockHelperMissing,
|
1290
|
+
// and then proceed as if the resulting value was provided to blockHelperMissing.
|
1205
1291
|
|
1206
|
-
|
1207
|
-
|
1208
|
-
// alternative compiled forms for name lookup and buffering semantics
|
1209
|
-
nameLookup: function(parent, name /* , type*/) {
|
1210
|
-
var wrap,
|
1211
|
-
ret;
|
1212
|
-
if (parent.indexOf('depth') === 0) {
|
1213
|
-
wrap = true;
|
1214
|
-
}
|
1292
|
+
Compiler.prototype = {
|
1293
|
+
compiler: Compiler,
|
1215
1294
|
|
1216
|
-
|
1217
|
-
|
1218
|
-
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
1219
|
-
ret = parent + "." + name;
|
1220
|
-
}
|
1221
|
-
else {
|
1222
|
-
ret = parent + "['" + name + "']";
|
1223
|
-
}
|
1295
|
+
disassemble: function() {
|
1296
|
+
var opcodes = this.opcodes, opcode, out = [], params, param;
|
1224
1297
|
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1298
|
+
for (var i=0, l=opcodes.length; i<l; i++) {
|
1299
|
+
opcode = opcodes[i];
|
1300
|
+
|
1301
|
+
if (opcode.opcode === 'DECLARE') {
|
1302
|
+
out.push("DECLARE " + opcode.name + "=" + opcode.value);
|
1303
|
+
} else {
|
1304
|
+
params = [];
|
1305
|
+
for (var j=0; j<opcode.args.length; j++) {
|
1306
|
+
param = opcode.args[j];
|
1307
|
+
if (typeof param === "string") {
|
1308
|
+
param = "\"" + param.replace("\n", "\\n") + "\"";
|
1309
|
+
}
|
1310
|
+
params.push(param);
|
1311
|
+
}
|
1312
|
+
out.push(opcode.opcode + " " + params.join(" "));
|
1313
|
+
}
|
1229
1314
|
}
|
1230
|
-
},
|
1231
1315
|
|
1232
|
-
|
1233
|
-
var revision = COMPILER_REVISION,
|
1234
|
-
versions = REVISION_CHANGES[revision];
|
1235
|
-
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
1316
|
+
return out.join("\n");
|
1236
1317
|
},
|
1237
1318
|
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
return {
|
1243
|
-
appendToBuffer: true,
|
1244
|
-
content: string,
|
1245
|
-
toString: function() { return "buffer += " + string + ";"; }
|
1246
|
-
};
|
1319
|
+
equals: function(other) {
|
1320
|
+
var len = this.opcodes.length;
|
1321
|
+
if (other.opcodes.length !== len) {
|
1322
|
+
return false;
|
1247
1323
|
}
|
1248
|
-
},
|
1249
1324
|
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1325
|
+
for (var i = 0; i < len; i++) {
|
1326
|
+
var opcode = this.opcodes[i],
|
1327
|
+
otherOpcode = other.opcodes[i];
|
1328
|
+
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
1329
|
+
return false;
|
1330
|
+
}
|
1331
|
+
for (var j = 0; j < opcode.args.length; j++) {
|
1332
|
+
if (opcode.args[j] !== otherOpcode.args[j]) {
|
1333
|
+
return false;
|
1334
|
+
}
|
1335
|
+
}
|
1336
|
+
}
|
1253
1337
|
|
1254
|
-
|
1255
|
-
|
1338
|
+
len = this.children.length;
|
1339
|
+
if (other.children.length !== len) {
|
1340
|
+
return false;
|
1341
|
+
}
|
1342
|
+
for (i = 0; i < len; i++) {
|
1343
|
+
if (!this.children[i].equals(other.children[i])) {
|
1344
|
+
return false;
|
1345
|
+
}
|
1346
|
+
}
|
1256
1347
|
|
1257
|
-
|
1258
|
-
|
1259
|
-
this.options = options || {};
|
1348
|
+
return true;
|
1349
|
+
},
|
1260
1350
|
|
1261
|
-
|
1351
|
+
guid: 0,
|
1262
1352
|
|
1263
|
-
|
1264
|
-
this.
|
1265
|
-
this.
|
1266
|
-
|
1267
|
-
|
1268
|
-
aliases: { }
|
1269
|
-
};
|
1353
|
+
compile: function(program, options) {
|
1354
|
+
this.opcodes = [];
|
1355
|
+
this.children = [];
|
1356
|
+
this.depths = {list: []};
|
1357
|
+
this.options = options;
|
1270
1358
|
|
1271
|
-
|
1359
|
+
// These changes will propagate to the other compiler components
|
1360
|
+
var knownHelpers = this.options.knownHelpers;
|
1361
|
+
this.options.knownHelpers = {
|
1362
|
+
'helperMissing': true,
|
1363
|
+
'blockHelperMissing': true,
|
1364
|
+
'each': true,
|
1365
|
+
'if': true,
|
1366
|
+
'unless': true,
|
1367
|
+
'with': true,
|
1368
|
+
'log': true
|
1369
|
+
};
|
1370
|
+
if (knownHelpers) {
|
1371
|
+
for (var name in knownHelpers) {
|
1372
|
+
this.options.knownHelpers[name] = knownHelpers[name];
|
1373
|
+
}
|
1374
|
+
}
|
1272
1375
|
|
1273
|
-
this.
|
1274
|
-
|
1275
|
-
this.registers = { list: [] };
|
1276
|
-
this.compileStack = [];
|
1277
|
-
this.inlineStack = [];
|
1376
|
+
return this.accept(program);
|
1377
|
+
},
|
1278
1378
|
|
1279
|
-
|
1379
|
+
accept: function(node) {
|
1380
|
+
var strip = node.strip || {},
|
1381
|
+
ret;
|
1382
|
+
if (strip.left) {
|
1383
|
+
this.opcode('strip');
|
1384
|
+
}
|
1280
1385
|
|
1281
|
-
|
1386
|
+
ret = this[node.type](node);
|
1282
1387
|
|
1283
|
-
|
1388
|
+
if (strip.right) {
|
1389
|
+
this.opcode('strip');
|
1390
|
+
}
|
1284
1391
|
|
1285
|
-
|
1286
|
-
|
1392
|
+
return ret;
|
1393
|
+
},
|
1287
1394
|
|
1288
|
-
|
1289
|
-
|
1290
|
-
} else {
|
1291
|
-
this[opcode.opcode].apply(this, opcode.args);
|
1292
|
-
}
|
1395
|
+
program: function(program) {
|
1396
|
+
var statements = program.statements;
|
1293
1397
|
|
1294
|
-
|
1295
|
-
|
1296
|
-
this.stripNext = false;
|
1297
|
-
}
|
1398
|
+
for(var i=0, l=statements.length; i<l; i++) {
|
1399
|
+
this.accept(statements[i]);
|
1298
1400
|
}
|
1401
|
+
this.isSimple = l === 1;
|
1299
1402
|
|
1300
|
-
|
1301
|
-
|
1403
|
+
this.depths.list = this.depths.list.sort(function(a, b) {
|
1404
|
+
return a - b;
|
1405
|
+
});
|
1302
1406
|
|
1303
|
-
return this
|
1407
|
+
return this;
|
1304
1408
|
},
|
1305
1409
|
|
1306
|
-
|
1307
|
-
var
|
1410
|
+
compileProgram: function(program) {
|
1411
|
+
var result = new this.compiler().compile(program, this.options);
|
1412
|
+
var guid = this.guid++, depth;
|
1308
1413
|
|
1309
|
-
|
1310
|
-
var namespace = this.namespace;
|
1414
|
+
this.usePartial = this.usePartial || result.usePartial;
|
1311
1415
|
|
1312
|
-
|
1313
|
-
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
1314
|
-
if (this.options.data) { copies = copies + " data = data || {};"; }
|
1315
|
-
out.push(copies);
|
1316
|
-
} else {
|
1317
|
-
out.push('');
|
1318
|
-
}
|
1416
|
+
this.children[guid] = result;
|
1319
1417
|
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1418
|
+
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
1419
|
+
depth = result.depths.list[i];
|
1420
|
+
|
1421
|
+
if(depth < 2) { continue; }
|
1422
|
+
else { this.addDepth(depth - 1); }
|
1324
1423
|
}
|
1325
1424
|
|
1326
|
-
|
1327
|
-
// getContext opcode when it would be a noop
|
1328
|
-
this.lastContext = 0;
|
1329
|
-
this.source = out;
|
1425
|
+
return guid;
|
1330
1426
|
},
|
1331
1427
|
|
1332
|
-
|
1333
|
-
var
|
1428
|
+
block: function(block) {
|
1429
|
+
var mustache = block.mustache,
|
1430
|
+
program = block.program,
|
1431
|
+
inverse = block.inverse;
|
1334
1432
|
|
1335
|
-
if(
|
1336
|
-
|
1433
|
+
if (program) {
|
1434
|
+
program = this.compileProgram(program);
|
1337
1435
|
}
|
1338
1436
|
|
1339
|
-
|
1340
|
-
|
1341
|
-
for (var alias in this.context.aliases) {
|
1342
|
-
if (this.context.aliases.hasOwnProperty(alias)) {
|
1343
|
-
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
1344
|
-
}
|
1345
|
-
}
|
1437
|
+
if (inverse) {
|
1438
|
+
inverse = this.compileProgram(inverse);
|
1346
1439
|
}
|
1347
1440
|
|
1348
|
-
|
1349
|
-
|
1350
|
-
}
|
1441
|
+
var sexpr = mustache.sexpr;
|
1442
|
+
var type = this.classifySexpr(sexpr);
|
1351
1443
|
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1444
|
+
if (type === "helper") {
|
1445
|
+
this.helperSexpr(sexpr, program, inverse);
|
1446
|
+
} else if (type === "simple") {
|
1447
|
+
this.simpleSexpr(sexpr);
|
1356
1448
|
|
1357
|
-
|
1358
|
-
|
1449
|
+
// now that the simple mustache is resolved, we need to
|
1450
|
+
// evaluate it by executing `blockHelperMissing`
|
1451
|
+
this.opcode('pushProgram', program);
|
1452
|
+
this.opcode('pushProgram', inverse);
|
1453
|
+
this.opcode('emptyHash');
|
1454
|
+
this.opcode('blockValue');
|
1455
|
+
} else {
|
1456
|
+
this.ambiguousSexpr(sexpr, program, inverse);
|
1457
|
+
|
1458
|
+
// now that the simple mustache is resolved, we need to
|
1459
|
+
// evaluate it by executing `blockHelperMissing`
|
1460
|
+
this.opcode('pushProgram', program);
|
1461
|
+
this.opcode('pushProgram', inverse);
|
1462
|
+
this.opcode('emptyHash');
|
1463
|
+
this.opcode('ambiguousBlockValue');
|
1359
1464
|
}
|
1360
1465
|
|
1361
|
-
|
1466
|
+
this.opcode('append');
|
1467
|
+
},
|
1362
1468
|
|
1363
|
-
|
1364
|
-
|
1365
|
-
}
|
1469
|
+
hash: function(hash) {
|
1470
|
+
var pairs = hash.pairs, pair, val;
|
1366
1471
|
|
1367
|
-
|
1368
|
-
var source = this.mergeSource();
|
1472
|
+
this.opcode('pushHash');
|
1369
1473
|
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1474
|
+
for(var i=0, l=pairs.length; i<l; i++) {
|
1475
|
+
pair = pairs[i];
|
1476
|
+
val = pair[1];
|
1373
1477
|
|
1374
|
-
|
1375
|
-
|
1478
|
+
if (this.options.stringParams) {
|
1479
|
+
if(val.depth) {
|
1480
|
+
this.addDepth(val.depth);
|
1481
|
+
}
|
1482
|
+
this.opcode('getContext', val.depth || 0);
|
1483
|
+
this.opcode('pushStringParam', val.stringModeValue, val.type);
|
1376
1484
|
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
return functionSource;
|
1382
|
-
}
|
1383
|
-
},
|
1384
|
-
mergeSource: function() {
|
1385
|
-
// WARN: We are not handling the case where buffer is still populated as the source should
|
1386
|
-
// not have buffer append operations as their final action.
|
1387
|
-
var source = '',
|
1388
|
-
buffer;
|
1389
|
-
for (var i = 0, len = this.source.length; i < len; i++) {
|
1390
|
-
var line = this.source[i];
|
1391
|
-
if (line.appendToBuffer) {
|
1392
|
-
if (buffer) {
|
1393
|
-
buffer = buffer + '\n + ' + line.content;
|
1394
|
-
} else {
|
1395
|
-
buffer = line.content;
|
1485
|
+
if (val.type === 'sexpr') {
|
1486
|
+
// Subexpressions get evaluated and passed in
|
1487
|
+
// in string params mode.
|
1488
|
+
this.sexpr(val);
|
1396
1489
|
}
|
1397
1490
|
} else {
|
1398
|
-
|
1399
|
-
source += 'buffer += ' + buffer + ';\n ';
|
1400
|
-
buffer = undefined;
|
1401
|
-
}
|
1402
|
-
source += line + '\n ';
|
1491
|
+
this.accept(val);
|
1403
1492
|
}
|
1493
|
+
|
1494
|
+
this.opcode('assignToHash', pair[0]);
|
1404
1495
|
}
|
1405
|
-
|
1496
|
+
this.opcode('popHash');
|
1406
1497
|
},
|
1407
1498
|
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
// On stack, after: return value of blockHelperMissing
|
1412
|
-
//
|
1413
|
-
// The purpose of this opcode is to take a block of the form
|
1414
|
-
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
1415
|
-
// replace it on the stack with the result of properly
|
1416
|
-
// invoking blockHelperMissing.
|
1417
|
-
blockValue: function() {
|
1418
|
-
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
1499
|
+
partial: function(partial) {
|
1500
|
+
var partialName = partial.partialName;
|
1501
|
+
this.usePartial = true;
|
1419
1502
|
|
1420
|
-
|
1421
|
-
|
1503
|
+
if(partial.context) {
|
1504
|
+
this.ID(partial.context);
|
1505
|
+
} else {
|
1506
|
+
this.opcode('push', 'depth0');
|
1507
|
+
}
|
1422
1508
|
|
1423
|
-
this.
|
1424
|
-
|
1425
|
-
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
1426
|
-
});
|
1509
|
+
this.opcode('invokePartial', partialName.name);
|
1510
|
+
this.opcode('append');
|
1427
1511
|
},
|
1428
1512
|
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
// Compiler value, before: lastHelper=value of last found helper, if any
|
1433
|
-
// On stack, after, if no lastHelper: same as [blockValue]
|
1434
|
-
// On stack, after, if lastHelper: value
|
1435
|
-
ambiguousBlockValue: function() {
|
1436
|
-
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
1513
|
+
content: function(content) {
|
1514
|
+
this.opcode('appendContent', content.string);
|
1515
|
+
},
|
1437
1516
|
|
1438
|
-
|
1439
|
-
this.
|
1517
|
+
mustache: function(mustache) {
|
1518
|
+
this.sexpr(mustache.sexpr);
|
1440
1519
|
|
1441
|
-
|
1442
|
-
|
1520
|
+
if(mustache.escaped && !this.options.noEscape) {
|
1521
|
+
this.opcode('appendEscaped');
|
1522
|
+
} else {
|
1523
|
+
this.opcode('append');
|
1524
|
+
}
|
1525
|
+
},
|
1443
1526
|
|
1444
|
-
|
1445
|
-
|
1527
|
+
ambiguousSexpr: function(sexpr, program, inverse) {
|
1528
|
+
var id = sexpr.id,
|
1529
|
+
name = id.parts[0],
|
1530
|
+
isBlock = program != null || inverse != null;
|
1446
1531
|
|
1447
|
-
this.
|
1532
|
+
this.opcode('getContext', id.depth);
|
1533
|
+
|
1534
|
+
this.opcode('pushProgram', program);
|
1535
|
+
this.opcode('pushProgram', inverse);
|
1536
|
+
|
1537
|
+
this.opcode('invokeAmbiguous', name, isBlock);
|
1448
1538
|
},
|
1449
1539
|
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1540
|
+
simpleSexpr: function(sexpr) {
|
1541
|
+
var id = sexpr.id;
|
1542
|
+
|
1543
|
+
if (id.type === 'DATA') {
|
1544
|
+
this.DATA(id);
|
1545
|
+
} else if (id.parts.length) {
|
1546
|
+
this.ID(id);
|
1547
|
+
} else {
|
1548
|
+
// Simplified ID for `this`
|
1549
|
+
this.addDepth(id.depth);
|
1550
|
+
this.opcode('getContext', id.depth);
|
1551
|
+
this.opcode('pushContext');
|
1462
1552
|
}
|
1463
1553
|
|
1464
|
-
this.
|
1554
|
+
this.opcode('resolvePossibleLambda');
|
1465
1555
|
},
|
1466
1556
|
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
this.
|
1557
|
+
helperSexpr: function(sexpr, program, inverse) {
|
1558
|
+
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
1559
|
+
name = sexpr.id.parts[0];
|
1560
|
+
|
1561
|
+
if (this.options.knownHelpers[name]) {
|
1562
|
+
this.opcode('invokeKnownHelper', params.length, name);
|
1563
|
+
} else if (this.options.knownHelpersOnly) {
|
1564
|
+
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
1565
|
+
} else {
|
1566
|
+
this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
|
1477
1567
|
}
|
1478
|
-
this.stripNext = 'strip';
|
1479
1568
|
},
|
1480
1569
|
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
append: function() {
|
1491
|
-
// Force anything that is inlined onto the stack so we don't have duplication
|
1492
|
-
// when we examine local
|
1493
|
-
this.flushInline();
|
1494
|
-
var local = this.popStack();
|
1495
|
-
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
1496
|
-
if (this.environment.isSimple) {
|
1497
|
-
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
1570
|
+
sexpr: function(sexpr) {
|
1571
|
+
var type = this.classifySexpr(sexpr);
|
1572
|
+
|
1573
|
+
if (type === "simple") {
|
1574
|
+
this.simpleSexpr(sexpr);
|
1575
|
+
} else if (type === "helper") {
|
1576
|
+
this.helperSexpr(sexpr);
|
1577
|
+
} else {
|
1578
|
+
this.ambiguousSexpr(sexpr);
|
1498
1579
|
}
|
1499
1580
|
},
|
1500
1581
|
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
// On stack, after: ...
|
1505
|
-
//
|
1506
|
-
// Escape `value` and append it to the buffer
|
1507
|
-
appendEscaped: function() {
|
1508
|
-
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
1582
|
+
ID: function(id) {
|
1583
|
+
this.addDepth(id.depth);
|
1584
|
+
this.opcode('getContext', id.depth);
|
1509
1585
|
|
1510
|
-
|
1586
|
+
var name = id.parts[0];
|
1587
|
+
if (!name) {
|
1588
|
+
this.opcode('pushContext');
|
1589
|
+
} else {
|
1590
|
+
this.opcode('lookupOnContext', id.parts[0]);
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
for(var i=1, l=id.parts.length; i<l; i++) {
|
1594
|
+
this.opcode('lookup', id.parts[i]);
|
1595
|
+
}
|
1511
1596
|
},
|
1512
1597
|
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
this.
|
1598
|
+
DATA: function(data) {
|
1599
|
+
this.options.data = true;
|
1600
|
+
if (data.id.isScoped || data.id.depth) {
|
1601
|
+
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
1602
|
+
}
|
1603
|
+
|
1604
|
+
this.opcode('lookupData');
|
1605
|
+
var parts = data.id.parts;
|
1606
|
+
for(var i=0, l=parts.length; i<l; i++) {
|
1607
|
+
this.opcode('lookup', parts[i]);
|
1523
1608
|
}
|
1524
1609
|
},
|
1525
1610
|
|
1526
|
-
|
1527
|
-
|
1528
|
-
// On stack, before: ...
|
1529
|
-
// On stack, after: currentContext[name], ...
|
1530
|
-
//
|
1531
|
-
// Looks up the value of `name` on the current context and pushes
|
1532
|
-
// it onto the stack.
|
1533
|
-
lookupOnContext: function(name) {
|
1534
|
-
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
1611
|
+
STRING: function(string) {
|
1612
|
+
this.opcode('pushString', string.string);
|
1535
1613
|
},
|
1536
1614
|
|
1537
|
-
|
1538
|
-
|
1539
|
-
// On stack, before: ...
|
1540
|
-
// On stack, after: currentContext, ...
|
1541
|
-
//
|
1542
|
-
// Pushes the value of the current context onto the stack.
|
1543
|
-
pushContext: function() {
|
1544
|
-
this.pushStackLiteral('depth' + this.lastContext);
|
1615
|
+
INTEGER: function(integer) {
|
1616
|
+
this.opcode('pushLiteral', integer.integer);
|
1545
1617
|
},
|
1546
1618
|
|
1547
|
-
|
1548
|
-
|
1549
|
-
// On stack, before: value, ...
|
1550
|
-
// On stack, after: resolved value, ...
|
1551
|
-
//
|
1552
|
-
// If the `value` is a lambda, replace it on the stack by
|
1553
|
-
// the return value of the lambda
|
1554
|
-
resolvePossibleLambda: function() {
|
1555
|
-
this.context.aliases.functionType = '"function"';
|
1556
|
-
|
1557
|
-
this.replaceStack(function(current) {
|
1558
|
-
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
1559
|
-
});
|
1619
|
+
BOOLEAN: function(bool) {
|
1620
|
+
this.opcode('pushLiteral', bool.bool);
|
1560
1621
|
},
|
1561
1622
|
|
1562
|
-
|
1563
|
-
//
|
1564
|
-
// On stack, before: value, ...
|
1565
|
-
// On stack, after: value[name], ...
|
1566
|
-
//
|
1567
|
-
// Replace the value on the stack with the result of looking
|
1568
|
-
// up `name` on `value`
|
1569
|
-
lookup: function(name) {
|
1570
|
-
this.replaceStack(function(current) {
|
1571
|
-
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
1572
|
-
});
|
1573
|
-
},
|
1623
|
+
comment: function() {},
|
1574
1624
|
|
1575
|
-
//
|
1576
|
-
|
1577
|
-
|
1578
|
-
// On stack, after: data, ...
|
1579
|
-
//
|
1580
|
-
// Push the data lookup operator
|
1581
|
-
lookupData: function() {
|
1582
|
-
this.push('data');
|
1625
|
+
// HELPERS
|
1626
|
+
opcode: function(name) {
|
1627
|
+
this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
|
1583
1628
|
},
|
1584
1629
|
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
// On stack, after: string, currentContext, ...
|
1589
|
-
//
|
1590
|
-
// This opcode is designed for use in string mode, which
|
1591
|
-
// provides the string value of a parameter along with its
|
1592
|
-
// depth rather than resolving it immediately.
|
1593
|
-
pushStringParam: function(string, type) {
|
1594
|
-
this.pushStackLiteral('depth' + this.lastContext);
|
1630
|
+
declare: function(name, value) {
|
1631
|
+
this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
|
1632
|
+
},
|
1595
1633
|
|
1596
|
-
|
1634
|
+
addDepth: function(depth) {
|
1635
|
+
if(depth === 0) { return; }
|
1597
1636
|
|
1598
|
-
if
|
1599
|
-
this.
|
1600
|
-
|
1601
|
-
this.pushStackLiteral(string);
|
1637
|
+
if(!this.depths[depth]) {
|
1638
|
+
this.depths[depth] = true;
|
1639
|
+
this.depths.list.push(depth);
|
1602
1640
|
}
|
1603
1641
|
},
|
1604
1642
|
|
1605
|
-
|
1606
|
-
|
1643
|
+
classifySexpr: function(sexpr) {
|
1644
|
+
var isHelper = sexpr.isHelper;
|
1645
|
+
var isEligible = sexpr.eligibleHelper;
|
1646
|
+
var options = this.options;
|
1607
1647
|
|
1608
|
-
if
|
1609
|
-
|
1610
|
-
|
1611
|
-
}
|
1612
|
-
},
|
1613
|
-
pushHash: function() {
|
1614
|
-
this.hash = {values: [], types: [], contexts: []};
|
1615
|
-
},
|
1616
|
-
popHash: function() {
|
1617
|
-
var hash = this.hash;
|
1618
|
-
this.hash = undefined;
|
1648
|
+
// if ambiguous, we can possibly resolve the ambiguity now
|
1649
|
+
if (isEligible && !isHelper) {
|
1650
|
+
var name = sexpr.id.parts[0];
|
1619
1651
|
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1652
|
+
if (options.knownHelpers[name]) {
|
1653
|
+
isHelper = true;
|
1654
|
+
} else if (options.knownHelpersOnly) {
|
1655
|
+
isEligible = false;
|
1656
|
+
}
|
1623
1657
|
}
|
1624
|
-
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
1625
|
-
},
|
1626
1658
|
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
// On stack, after: quotedString(string), ...
|
1631
|
-
//
|
1632
|
-
// Push a quoted version of `string` onto the stack
|
1633
|
-
pushString: function(string) {
|
1634
|
-
this.pushStackLiteral(this.quotedString(string));
|
1659
|
+
if (isHelper) { return "helper"; }
|
1660
|
+
else if (isEligible) { return "ambiguous"; }
|
1661
|
+
else { return "simple"; }
|
1635
1662
|
},
|
1636
1663
|
|
1637
|
-
|
1638
|
-
|
1639
|
-
// On stack, before: ...
|
1640
|
-
// On stack, after: expr, ...
|
1641
|
-
//
|
1642
|
-
// Push an expression onto the stack
|
1643
|
-
push: function(expr) {
|
1644
|
-
this.inlineStack.push(expr);
|
1645
|
-
return expr;
|
1646
|
-
},
|
1664
|
+
pushParams: function(params) {
|
1665
|
+
var i = params.length, param;
|
1647
1666
|
|
1648
|
-
|
1649
|
-
|
1650
|
-
// On stack, before: ...
|
1651
|
-
// On stack, after: value, ...
|
1652
|
-
//
|
1653
|
-
// Pushes a value onto the stack. This operation prevents
|
1654
|
-
// the compiler from creating a temporary variable to hold
|
1655
|
-
// it.
|
1656
|
-
pushLiteral: function(value) {
|
1657
|
-
this.pushStackLiteral(value);
|
1658
|
-
},
|
1667
|
+
while(i--) {
|
1668
|
+
param = params[i];
|
1659
1669
|
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1670
|
+
if(this.options.stringParams) {
|
1671
|
+
if(param.depth) {
|
1672
|
+
this.addDepth(param.depth);
|
1673
|
+
}
|
1674
|
+
|
1675
|
+
this.opcode('getContext', param.depth || 0);
|
1676
|
+
this.opcode('pushStringParam', param.stringModeValue, param.type);
|
1677
|
+
|
1678
|
+
if (param.type === 'sexpr') {
|
1679
|
+
// Subexpressions get evaluated and passed in
|
1680
|
+
// in string params mode.
|
1681
|
+
this.sexpr(param);
|
1682
|
+
}
|
1683
|
+
} else {
|
1684
|
+
this[param.type](param);
|
1685
|
+
}
|
1673
1686
|
}
|
1674
1687
|
},
|
1675
1688
|
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
// On stack, after: result of helper invocation
|
1680
|
-
//
|
1681
|
-
// Pops off the helper's parameters, invokes the helper,
|
1682
|
-
// and pushes the helper's return value onto the stack.
|
1683
|
-
//
|
1684
|
-
// If the helper is not found, `helperMissing` is called.
|
1685
|
-
invokeHelper: function(paramSize, name) {
|
1686
|
-
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
1687
|
-
|
1688
|
-
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
1689
|
-
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
1689
|
+
setupFullMustacheParams: function(sexpr, program, inverse) {
|
1690
|
+
var params = sexpr.params;
|
1691
|
+
this.pushParams(params);
|
1690
1692
|
|
1691
|
-
this.
|
1692
|
-
this.
|
1693
|
-
return name + ' ? ' + name + '.call(' +
|
1694
|
-
helper.callParams + ") " + ": helperMissing.call(" +
|
1695
|
-
helper.helperMissingParams + ")";
|
1696
|
-
});
|
1697
|
-
},
|
1693
|
+
this.opcode('pushProgram', program);
|
1694
|
+
this.opcode('pushProgram', inverse);
|
1698
1695
|
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
// This operation is used when the helper is known to exist,
|
1705
|
-
// so a `helperMissing` fallback is not required.
|
1706
|
-
invokeKnownHelper: function(paramSize, name) {
|
1707
|
-
var helper = this.setupHelper(paramSize, name);
|
1708
|
-
this.push(helper.name + ".call(" + helper.callParams + ")");
|
1709
|
-
},
|
1696
|
+
if (sexpr.hash) {
|
1697
|
+
this.hash(sexpr.hash);
|
1698
|
+
} else {
|
1699
|
+
this.opcode('emptyHash');
|
1700
|
+
}
|
1710
1701
|
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
// On stack, after: result of disambiguation
|
1715
|
-
//
|
1716
|
-
// This operation is used when an expression like `{{foo}}`
|
1717
|
-
// is provided, but we don't know at compile-time whether it
|
1718
|
-
// is a helper or a path.
|
1719
|
-
//
|
1720
|
-
// This operation emits more code than the other options,
|
1721
|
-
// and can be avoided by passing the `knownHelpers` and
|
1722
|
-
// `knownHelpersOnly` flags at compile-time.
|
1723
|
-
invokeAmbiguous: function(name, helperCall) {
|
1724
|
-
this.context.aliases.functionType = '"function"';
|
1702
|
+
return params;
|
1703
|
+
}
|
1704
|
+
};
|
1725
1705
|
|
1726
|
-
|
1727
|
-
|
1706
|
+
function precompile(input, options, env) {
|
1707
|
+
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
1708
|
+
throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
|
1709
|
+
}
|
1728
1710
|
|
1729
|
-
|
1711
|
+
options = options || {};
|
1712
|
+
if (!('data' in options)) {
|
1713
|
+
options.data = true;
|
1714
|
+
}
|
1730
1715
|
|
1731
|
-
|
1732
|
-
|
1716
|
+
var ast = env.parse(input);
|
1717
|
+
var environment = new env.Compiler().compile(ast, options);
|
1718
|
+
return new env.JavaScriptCompiler().compile(environment, options);
|
1719
|
+
}
|
1733
1720
|
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1721
|
+
__exports__.precompile = precompile;function compile(input, options, env) {
|
1722
|
+
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
1723
|
+
throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
|
1724
|
+
}
|
1737
1725
|
|
1738
|
-
|
1739
|
-
//
|
1740
|
-
// On stack, before: context, ...
|
1741
|
-
// On stack after: result of partial invocation
|
1742
|
-
//
|
1743
|
-
// This operation pops off a context, invokes a partial with that context,
|
1744
|
-
// and pushes the result of the invocation back.
|
1745
|
-
invokePartial: function(name) {
|
1746
|
-
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
1726
|
+
options = options || {};
|
1747
1727
|
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1728
|
+
if (!('data' in options)) {
|
1729
|
+
options.data = true;
|
1730
|
+
}
|
1751
1731
|
|
1752
|
-
|
1753
|
-
this.push("self.invokePartial(" + params.join(", ") + ")");
|
1754
|
-
},
|
1732
|
+
var compiled;
|
1755
1733
|
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
// and pushes the hash back onto the stack.
|
1763
|
-
assignToHash: function(key) {
|
1764
|
-
var value = this.popStack(),
|
1765
|
-
context,
|
1766
|
-
type;
|
1734
|
+
function compileInput() {
|
1735
|
+
var ast = env.parse(input);
|
1736
|
+
var environment = new env.Compiler().compile(ast, options);
|
1737
|
+
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
|
1738
|
+
return env.template(templateSpec);
|
1739
|
+
}
|
1767
1740
|
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1741
|
+
// Template is only compiled on first use and cached after that point.
|
1742
|
+
return function(context, options) {
|
1743
|
+
if (!compiled) {
|
1744
|
+
compiled = compileInput();
|
1771
1745
|
}
|
1746
|
+
return compiled.call(this, context, options);
|
1747
|
+
};
|
1748
|
+
}
|
1772
1749
|
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
}
|
1777
|
-
if (type) {
|
1778
|
-
hash.types.push("'" + key + "': " + type);
|
1779
|
-
}
|
1780
|
-
hash.values.push("'" + key + "': (" + value + ")");
|
1781
|
-
},
|
1782
|
-
|
1783
|
-
// HELPERS
|
1784
|
-
|
1785
|
-
compiler: JavaScriptCompiler,
|
1750
|
+
__exports__.compile = compile;
|
1751
|
+
return __exports__;
|
1752
|
+
})(__module5__);
|
1786
1753
|
|
1787
|
-
|
1788
|
-
|
1754
|
+
// handlebars/compiler/javascript-compiler.js
|
1755
|
+
var __module11__ = (function(__dependency1__, __dependency2__) {
|
1756
|
+
"use strict";
|
1757
|
+
var __exports__;
|
1758
|
+
var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
|
1759
|
+
var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
|
1760
|
+
var log = __dependency1__.log;
|
1761
|
+
var Exception = __dependency2__;
|
1789
1762
|
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1763
|
+
function Literal(value) {
|
1764
|
+
this.value = value;
|
1765
|
+
}
|
1793
1766
|
|
1794
|
-
|
1767
|
+
function JavaScriptCompiler() {}
|
1795
1768
|
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
child.index = index;
|
1805
|
-
child.name = 'program' + index;
|
1806
|
-
}
|
1807
|
-
}
|
1808
|
-
},
|
1809
|
-
matchExistingProgram: function(child) {
|
1810
|
-
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
1811
|
-
var environment = this.context.environments[i];
|
1812
|
-
if (environment && environment.equals(child)) {
|
1813
|
-
return i;
|
1814
|
-
}
|
1769
|
+
JavaScriptCompiler.prototype = {
|
1770
|
+
// PUBLIC API: You can override these methods in a subclass to provide
|
1771
|
+
// alternative compiled forms for name lookup and buffering semantics
|
1772
|
+
nameLookup: function(parent, name /* , type*/) {
|
1773
|
+
var wrap,
|
1774
|
+
ret;
|
1775
|
+
if (parent.indexOf('depth') === 0) {
|
1776
|
+
wrap = true;
|
1815
1777
|
}
|
1816
|
-
},
|
1817
|
-
|
1818
|
-
programExpression: function(guid) {
|
1819
|
-
this.context.aliases.self = "this";
|
1820
1778
|
|
1821
|
-
if(
|
1822
|
-
|
1779
|
+
if (/^[0-9]+$/.test(name)) {
|
1780
|
+
ret = parent + "[" + name + "]";
|
1781
|
+
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
1782
|
+
ret = parent + "." + name;
|
1823
1783
|
}
|
1824
|
-
|
1825
|
-
|
1826
|
-
depths = child.depths.list, depth;
|
1827
|
-
|
1828
|
-
var programParams = [child.index, child.name, "data"];
|
1829
|
-
|
1830
|
-
for(var i=0, l = depths.length; i<l; i++) {
|
1831
|
-
depth = depths[i];
|
1832
|
-
|
1833
|
-
if(depth === 1) { programParams.push("depth0"); }
|
1834
|
-
else { programParams.push("depth" + (depth - 1)); }
|
1784
|
+
else {
|
1785
|
+
ret = parent + "['" + name + "']";
|
1835
1786
|
}
|
1836
1787
|
|
1837
|
-
|
1788
|
+
if (wrap) {
|
1789
|
+
return '(' + parent + ' && ' + ret + ')';
|
1790
|
+
} else {
|
1791
|
+
return ret;
|
1792
|
+
}
|
1838
1793
|
},
|
1839
1794
|
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1795
|
+
compilerInfo: function() {
|
1796
|
+
var revision = COMPILER_REVISION,
|
1797
|
+
versions = REVISION_CHANGES[revision];
|
1798
|
+
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
1843
1799
|
},
|
1844
1800
|
|
1845
|
-
|
1846
|
-
if(
|
1847
|
-
|
1848
|
-
|
1801
|
+
appendToBuffer: function(string) {
|
1802
|
+
if (this.environment.isSimple) {
|
1803
|
+
return "return " + string + ";";
|
1804
|
+
} else {
|
1805
|
+
return {
|
1806
|
+
appendToBuffer: true,
|
1807
|
+
content: string,
|
1808
|
+
toString: function() { return "buffer += " + string + ";"; }
|
1809
|
+
};
|
1849
1810
|
}
|
1850
1811
|
},
|
1851
1812
|
|
1852
|
-
|
1853
|
-
return this.
|
1813
|
+
initializeBuffer: function() {
|
1814
|
+
return this.quotedString("");
|
1854
1815
|
},
|
1855
1816
|
|
1856
|
-
|
1857
|
-
|
1858
|
-
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
1859
|
-
this.pendingContent = undefined;
|
1860
|
-
}
|
1817
|
+
namespace: "Handlebars",
|
1818
|
+
// END PUBLIC API
|
1861
1819
|
|
1862
|
-
|
1863
|
-
|
1864
|
-
}
|
1865
|
-
},
|
1820
|
+
compile: function(environment, options, context, asObject) {
|
1821
|
+
this.environment = environment;
|
1822
|
+
this.options = options || {};
|
1866
1823
|
|
1867
|
-
|
1868
|
-
this.flushInline();
|
1824
|
+
log('debug', this.environment.disassemble() + "\n\n");
|
1869
1825
|
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1826
|
+
this.name = this.environment.name;
|
1827
|
+
this.isChild = !!context;
|
1828
|
+
this.context = context || {
|
1829
|
+
programs: [],
|
1830
|
+
environments: [],
|
1831
|
+
aliases: { }
|
1832
|
+
};
|
1877
1833
|
|
1878
|
-
|
1879
|
-
var prefix = '',
|
1880
|
-
inline = this.isInline(),
|
1881
|
-
stack;
|
1834
|
+
this.preamble();
|
1882
1835
|
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1836
|
+
this.stackSlot = 0;
|
1837
|
+
this.stackVars = [];
|
1838
|
+
this.registers = { list: [] };
|
1839
|
+
this.hashes = [];
|
1840
|
+
this.compileStack = [];
|
1841
|
+
this.inlineStack = [];
|
1887
1842
|
|
1888
|
-
|
1889
|
-
// Literals do not need to be inlined
|
1890
|
-
stack = top.value;
|
1891
|
-
} else {
|
1892
|
-
// Get or create the current stack name for use by the inline
|
1893
|
-
var name = this.stackSlot ? this.topStackName() : this.incrStack();
|
1843
|
+
this.compileChildren(environment, options);
|
1894
1844
|
|
1895
|
-
|
1896
|
-
stack = this.topStack();
|
1897
|
-
}
|
1898
|
-
} else {
|
1899
|
-
stack = this.topStack();
|
1900
|
-
}
|
1845
|
+
var opcodes = environment.opcodes, opcode;
|
1901
1846
|
|
1902
|
-
|
1847
|
+
this.i = 0;
|
1903
1848
|
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
if (!/^stack/.test(stack)) {
|
1912
|
-
stack = this.nextStack();
|
1849
|
+
for(var l=opcodes.length; this.i<l; this.i++) {
|
1850
|
+
opcode = opcodes[this.i];
|
1851
|
+
|
1852
|
+
if(opcode.opcode === 'DECLARE') {
|
1853
|
+
this[opcode.name] = opcode.value;
|
1854
|
+
} else {
|
1855
|
+
this[opcode.opcode].apply(this, opcode.args);
|
1913
1856
|
}
|
1914
1857
|
|
1915
|
-
|
1858
|
+
// Reset the stripNext flag if it was not set by this operation.
|
1859
|
+
if (opcode.opcode !== this.stripNext) {
|
1860
|
+
this.stripNext = false;
|
1861
|
+
}
|
1916
1862
|
}
|
1917
|
-
return stack;
|
1918
|
-
},
|
1919
1863
|
|
1920
|
-
|
1921
|
-
|
1922
|
-
},
|
1864
|
+
// Flush any trailing content that might be pending.
|
1865
|
+
this.pushSource('');
|
1923
1866
|
|
1924
|
-
|
1925
|
-
|
1926
|
-
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
1927
|
-
return this.topStackName();
|
1928
|
-
},
|
1929
|
-
topStackName: function() {
|
1930
|
-
return "stack" + this.stackSlot;
|
1931
|
-
},
|
1932
|
-
flushInline: function() {
|
1933
|
-
var inlineStack = this.inlineStack;
|
1934
|
-
if (inlineStack.length) {
|
1935
|
-
this.inlineStack = [];
|
1936
|
-
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
1937
|
-
var entry = inlineStack[i];
|
1938
|
-
if (entry instanceof Literal) {
|
1939
|
-
this.compileStack.push(entry);
|
1940
|
-
} else {
|
1941
|
-
this.pushStack(entry);
|
1942
|
-
}
|
1943
|
-
}
|
1867
|
+
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
1868
|
+
throw new Exception('Compile completed with content left on stack');
|
1944
1869
|
}
|
1945
|
-
|
1946
|
-
|
1947
|
-
return this.inlineStack.length;
|
1870
|
+
|
1871
|
+
return this.createFunctionContext(asObject);
|
1948
1872
|
},
|
1949
1873
|
|
1950
|
-
|
1951
|
-
var
|
1952
|
-
item = (inline ? this.inlineStack : this.compileStack).pop();
|
1874
|
+
preamble: function() {
|
1875
|
+
var out = [];
|
1953
1876
|
|
1954
|
-
if (!
|
1955
|
-
|
1877
|
+
if (!this.isChild) {
|
1878
|
+
var namespace = this.namespace;
|
1879
|
+
|
1880
|
+
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
1881
|
+
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
1882
|
+
if (this.options.data) { copies = copies + " data = data || {};"; }
|
1883
|
+
out.push(copies);
|
1956
1884
|
} else {
|
1957
|
-
|
1958
|
-
this.stackSlot--;
|
1959
|
-
}
|
1960
|
-
return item;
|
1885
|
+
out.push('');
|
1961
1886
|
}
|
1962
|
-
},
|
1963
|
-
|
1964
|
-
topStack: function(wrapped) {
|
1965
|
-
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
1966
|
-
item = stack[stack.length - 1];
|
1967
1887
|
|
1968
|
-
if (!
|
1969
|
-
|
1888
|
+
if (!this.environment.isSimple) {
|
1889
|
+
out.push(", buffer = " + this.initializeBuffer());
|
1970
1890
|
} else {
|
1971
|
-
|
1891
|
+
out.push("");
|
1972
1892
|
}
|
1973
|
-
},
|
1974
1893
|
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
.replace(/\n/g, '\\n')
|
1980
|
-
.replace(/\r/g, '\\r')
|
1981
|
-
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
1982
|
-
.replace(/\u2029/g, '\\u2029') + '"';
|
1894
|
+
// track the last context pushed into place to allow skipping the
|
1895
|
+
// getContext opcode when it would be a noop
|
1896
|
+
this.lastContext = 0;
|
1897
|
+
this.source = out;
|
1983
1898
|
},
|
1984
1899
|
|
1985
|
-
|
1986
|
-
var
|
1987
|
-
this.setupParams(paramSize, params, missingParams);
|
1988
|
-
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
1900
|
+
createFunctionContext: function(asObject) {
|
1901
|
+
var locals = this.stackVars.concat(this.registers.list);
|
1989
1902
|
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
callParams: ["depth0"].concat(params).join(", "),
|
1994
|
-
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
1995
|
-
};
|
1996
|
-
},
|
1903
|
+
if(locals.length > 0) {
|
1904
|
+
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
1905
|
+
}
|
1997
1906
|
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
1907
|
+
// Generate minimizer alias mappings
|
1908
|
+
if (!this.isChild) {
|
1909
|
+
for (var alias in this.context.aliases) {
|
1910
|
+
if (this.context.aliases.hasOwnProperty(alias)) {
|
1911
|
+
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
1912
|
+
}
|
1913
|
+
}
|
1914
|
+
}
|
2002
1915
|
|
2003
|
-
|
1916
|
+
if (this.source[1]) {
|
1917
|
+
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
1918
|
+
}
|
2004
1919
|
|
2005
|
-
|
2006
|
-
|
1920
|
+
// Merge children
|
1921
|
+
if (!this.isChild) {
|
1922
|
+
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
1923
|
+
}
|
2007
1924
|
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
if (!program) {
|
2012
|
-
this.context.aliases.self = "this";
|
2013
|
-
program = "self.noop";
|
2014
|
-
}
|
1925
|
+
if (!this.environment.isSimple) {
|
1926
|
+
this.pushSource("return buffer;");
|
1927
|
+
}
|
2015
1928
|
|
2016
|
-
|
2017
|
-
this.context.aliases.self = "this";
|
2018
|
-
inverse = "self.noop";
|
2019
|
-
}
|
1929
|
+
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
2020
1930
|
|
2021
|
-
|
2022
|
-
|
1931
|
+
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
1932
|
+
params.push("depth" + this.environment.depths.list[i]);
|
2023
1933
|
}
|
2024
1934
|
|
2025
|
-
|
2026
|
-
|
2027
|
-
params.push(param);
|
1935
|
+
// Perform a second pass over the output to merge content when possible
|
1936
|
+
var source = this.mergeSource();
|
2028
1937
|
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
1938
|
+
if (!this.isChild) {
|
1939
|
+
source = this.compilerInfo()+source;
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
if (asObject) {
|
1943
|
+
params.push(source);
|
1944
|
+
|
1945
|
+
return Function.apply(this, params);
|
1946
|
+
} else {
|
1947
|
+
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
1948
|
+
log('debug', functionSource + "\n\n");
|
1949
|
+
return functionSource;
|
1950
|
+
}
|
1951
|
+
},
|
1952
|
+
mergeSource: function() {
|
1953
|
+
// WARN: We are not handling the case where buffer is still populated as the source should
|
1954
|
+
// not have buffer append operations as their final action.
|
1955
|
+
var source = '',
|
1956
|
+
buffer;
|
1957
|
+
for (var i = 0, len = this.source.length; i < len; i++) {
|
1958
|
+
var line = this.source[i];
|
1959
|
+
if (line.appendToBuffer) {
|
1960
|
+
if (buffer) {
|
1961
|
+
buffer = buffer + '\n + ' + line.content;
|
1962
|
+
} else {
|
1963
|
+
buffer = line.content;
|
1964
|
+
}
|
1965
|
+
} else {
|
1966
|
+
if (buffer) {
|
1967
|
+
source += 'buffer += ' + buffer + ';\n ';
|
1968
|
+
buffer = undefined;
|
1969
|
+
}
|
1970
|
+
source += line + '\n ';
|
2032
1971
|
}
|
2033
1972
|
}
|
1973
|
+
return source;
|
1974
|
+
},
|
2034
1975
|
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
1976
|
+
// [blockValue]
|
1977
|
+
//
|
1978
|
+
// On stack, before: hash, inverse, program, value
|
1979
|
+
// On stack, after: return value of blockHelperMissing
|
1980
|
+
//
|
1981
|
+
// The purpose of this opcode is to take a block of the form
|
1982
|
+
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
1983
|
+
// replace it on the stack with the result of properly
|
1984
|
+
// invoking blockHelperMissing.
|
1985
|
+
blockValue: function() {
|
1986
|
+
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
1987
|
+
|
1988
|
+
var params = ["depth0"];
|
1989
|
+
this.setupParams(0, params);
|
1990
|
+
|
1991
|
+
this.replaceStack(function(current) {
|
1992
|
+
params.splice(1, 0, current);
|
1993
|
+
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
1994
|
+
});
|
1995
|
+
},
|
1996
|
+
|
1997
|
+
// [ambiguousBlockValue]
|
1998
|
+
//
|
1999
|
+
// On stack, before: hash, inverse, program, value
|
2000
|
+
// Compiler value, before: lastHelper=value of last found helper, if any
|
2001
|
+
// On stack, after, if no lastHelper: same as [blockValue]
|
2002
|
+
// On stack, after, if lastHelper: value
|
2003
|
+
ambiguousBlockValue: function() {
|
2004
|
+
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
2005
|
+
|
2006
|
+
var params = ["depth0"];
|
2007
|
+
this.setupParams(0, params);
|
2008
|
+
|
2009
|
+
var current = this.topStack();
|
2010
|
+
params.splice(1, 0, current);
|
2011
|
+
|
2012
|
+
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
2013
|
+
},
|
2014
|
+
|
2015
|
+
// [appendContent]
|
2016
|
+
//
|
2017
|
+
// On stack, before: ...
|
2018
|
+
// On stack, after: ...
|
2019
|
+
//
|
2020
|
+
// Appends the string value of `content` to the current buffer
|
2021
|
+
appendContent: function(content) {
|
2022
|
+
if (this.pendingContent) {
|
2023
|
+
content = this.pendingContent + content;
|
2024
|
+
}
|
2025
|
+
if (this.stripNext) {
|
2026
|
+
content = content.replace(/^\s+/, '');
|
2040
2027
|
}
|
2041
2028
|
|
2042
|
-
|
2043
|
-
|
2029
|
+
this.pendingContent = content;
|
2030
|
+
},
|
2031
|
+
|
2032
|
+
// [strip]
|
2033
|
+
//
|
2034
|
+
// On stack, before: ...
|
2035
|
+
// On stack, after: ...
|
2036
|
+
//
|
2037
|
+
// Removes any trailing whitespace from the prior content node and flags
|
2038
|
+
// the next operation for stripping if it is a content node.
|
2039
|
+
strip: function() {
|
2040
|
+
if (this.pendingContent) {
|
2041
|
+
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
2044
2042
|
}
|
2043
|
+
this.stripNext = 'strip';
|
2044
|
+
},
|
2045
2045
|
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2046
|
+
// [append]
|
2047
|
+
//
|
2048
|
+
// On stack, before: value, ...
|
2049
|
+
// On stack, after: ...
|
2050
|
+
//
|
2051
|
+
// Coerces `value` to a String and appends it to the current buffer.
|
2052
|
+
//
|
2053
|
+
// If `value` is truthy, or 0, it is coerced into a string and appended
|
2054
|
+
// Otherwise, the empty string is appended
|
2055
|
+
append: function() {
|
2056
|
+
// Force anything that is inlined onto the stack so we don't have duplication
|
2057
|
+
// when we examine local
|
2058
|
+
this.flushInline();
|
2059
|
+
var local = this.popStack();
|
2060
|
+
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
2061
|
+
if (this.environment.isSimple) {
|
2062
|
+
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
2052
2063
|
}
|
2053
|
-
|
2054
|
-
}
|
2055
|
-
};
|
2064
|
+
},
|
2056
2065
|
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
2064
|
-
|
2065
|
-
" abstract enum int short" +
|
2066
|
-
" boolean export interface static" +
|
2067
|
-
" byte extends long super" +
|
2068
|
-
" char final native synchronized" +
|
2069
|
-
" class float package throws" +
|
2070
|
-
" const goto private transient" +
|
2071
|
-
" debugger implements protected volatile" +
|
2072
|
-
" double import public let yield"
|
2073
|
-
).split(" ");
|
2066
|
+
// [appendEscaped]
|
2067
|
+
//
|
2068
|
+
// On stack, before: value, ...
|
2069
|
+
// On stack, after: ...
|
2070
|
+
//
|
2071
|
+
// Escape `value` and append it to the buffer
|
2072
|
+
appendEscaped: function() {
|
2073
|
+
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
2074
2074
|
|
2075
|
-
|
2075
|
+
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
2076
|
+
},
|
2076
2077
|
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2078
|
+
// [getContext]
|
2079
|
+
//
|
2080
|
+
// On stack, before: ...
|
2081
|
+
// On stack, after: ...
|
2082
|
+
// Compiler value, after: lastContext=depth
|
2083
|
+
//
|
2084
|
+
// Set the value of the `lastContext` compiler value to the depth
|
2085
|
+
getContext: function(depth) {
|
2086
|
+
if(this.lastContext !== depth) {
|
2087
|
+
this.lastContext = depth;
|
2088
|
+
}
|
2089
|
+
},
|
2080
2090
|
|
2081
|
-
|
2082
|
-
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2091
|
+
// [lookupOnContext]
|
2092
|
+
//
|
2093
|
+
// On stack, before: ...
|
2094
|
+
// On stack, after: currentContext[name], ...
|
2095
|
+
//
|
2096
|
+
// Looks up the value of `name` on the current context and pushes
|
2097
|
+
// it onto the stack.
|
2098
|
+
lookupOnContext: function(name) {
|
2099
|
+
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
2100
|
+
},
|
2087
2101
|
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2102
|
+
// [pushContext]
|
2103
|
+
//
|
2104
|
+
// On stack, before: ...
|
2105
|
+
// On stack, after: currentContext, ...
|
2106
|
+
//
|
2107
|
+
// Pushes the value of the current context onto the stack.
|
2108
|
+
pushContext: function() {
|
2109
|
+
this.pushStackLiteral('depth' + this.lastContext);
|
2110
|
+
},
|
2091
2111
|
|
2092
|
-
//
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2112
|
+
// [resolvePossibleLambda]
|
2113
|
+
//
|
2114
|
+
// On stack, before: value, ...
|
2115
|
+
// On stack, after: resolved value, ...
|
2116
|
+
//
|
2117
|
+
// If the `value` is a lambda, replace it on the stack by
|
2118
|
+
// the return value of the lambda
|
2119
|
+
resolvePossibleLambda: function() {
|
2120
|
+
this.context.aliases.functionType = '"function"';
|
2100
2121
|
|
2101
|
-
|
2122
|
+
this.replaceStack(function(current) {
|
2123
|
+
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
2124
|
+
});
|
2125
|
+
},
|
2102
2126
|
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2127
|
+
// [lookup]
|
2128
|
+
//
|
2129
|
+
// On stack, before: value, ...
|
2130
|
+
// On stack, after: value[name], ...
|
2131
|
+
//
|
2132
|
+
// Replace the value on the stack with the result of looking
|
2133
|
+
// up `name` on `value`
|
2134
|
+
lookup: function(name) {
|
2135
|
+
this.replaceStack(function(current) {
|
2136
|
+
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
2137
|
+
});
|
2138
|
+
},
|
2107
2139
|
|
2108
|
-
|
2109
|
-
|
2140
|
+
// [lookupData]
|
2141
|
+
//
|
2142
|
+
// On stack, before: ...
|
2143
|
+
// On stack, after: data, ...
|
2144
|
+
//
|
2145
|
+
// Push the data lookup operator
|
2146
|
+
lookupData: function() {
|
2147
|
+
this.pushStackLiteral('data');
|
2148
|
+
},
|
2110
2149
|
|
2111
|
-
|
2112
|
-
|
2150
|
+
// [pushStringParam]
|
2151
|
+
//
|
2152
|
+
// On stack, before: ...
|
2153
|
+
// On stack, after: string, currentContext, ...
|
2154
|
+
//
|
2155
|
+
// This opcode is designed for use in string mode, which
|
2156
|
+
// provides the string value of a parameter along with its
|
2157
|
+
// depth rather than resolving it immediately.
|
2158
|
+
pushStringParam: function(string, type) {
|
2159
|
+
this.pushStackLiteral('depth' + this.lastContext);
|
2113
2160
|
|
2114
|
-
|
2115
|
-
opcode = opcodes[i];
|
2161
|
+
this.pushString(type);
|
2116
2162
|
|
2117
|
-
|
2118
|
-
|
2163
|
+
// If it's a subexpression, the string result
|
2164
|
+
// will be pushed after this opcode.
|
2165
|
+
if (type !== 'sexpr') {
|
2166
|
+
if (typeof string === 'string') {
|
2167
|
+
this.pushString(string);
|
2119
2168
|
} else {
|
2120
|
-
|
2121
|
-
for (var j=0; j<opcode.args.length; j++) {
|
2122
|
-
param = opcode.args[j];
|
2123
|
-
if (typeof param === "string") {
|
2124
|
-
param = "\"" + param.replace("\n", "\\n") + "\"";
|
2125
|
-
}
|
2126
|
-
params.push(param);
|
2127
|
-
}
|
2128
|
-
out.push(opcode.opcode + " " + params.join(" "));
|
2169
|
+
this.pushStackLiteral(string);
|
2129
2170
|
}
|
2130
2171
|
}
|
2131
|
-
|
2132
|
-
return out.join("\n");
|
2133
2172
|
},
|
2134
2173
|
|
2135
|
-
|
2136
|
-
|
2137
|
-
if (other.opcodes.length !== len) {
|
2138
|
-
return false;
|
2139
|
-
}
|
2174
|
+
emptyHash: function() {
|
2175
|
+
this.pushStackLiteral('{}');
|
2140
2176
|
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
2145
|
-
return false;
|
2146
|
-
}
|
2147
|
-
for (var j = 0; j < opcode.args.length; j++) {
|
2148
|
-
if (opcode.args[j] !== otherOpcode.args[j]) {
|
2149
|
-
return false;
|
2150
|
-
}
|
2151
|
-
}
|
2177
|
+
if (this.options.stringParams) {
|
2178
|
+
this.push('{}'); // hashContexts
|
2179
|
+
this.push('{}'); // hashTypes
|
2152
2180
|
}
|
2153
|
-
|
2154
|
-
|
2155
|
-
if (
|
2156
|
-
|
2181
|
+
},
|
2182
|
+
pushHash: function() {
|
2183
|
+
if (this.hash) {
|
2184
|
+
this.hashes.push(this.hash);
|
2157
2185
|
}
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2186
|
+
this.hash = {values: [], types: [], contexts: []};
|
2187
|
+
},
|
2188
|
+
popHash: function() {
|
2189
|
+
var hash = this.hash;
|
2190
|
+
this.hash = this.hashes.pop();
|
2191
|
+
|
2192
|
+
if (this.options.stringParams) {
|
2193
|
+
this.push('{' + hash.contexts.join(',') + '}');
|
2194
|
+
this.push('{' + hash.types.join(',') + '}');
|
2162
2195
|
}
|
2163
2196
|
|
2164
|
-
|
2197
|
+
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
2165
2198
|
},
|
2166
2199
|
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2200
|
+
// [pushString]
|
2201
|
+
//
|
2202
|
+
// On stack, before: ...
|
2203
|
+
// On stack, after: quotedString(string), ...
|
2204
|
+
//
|
2205
|
+
// Push a quoted version of `string` onto the stack
|
2206
|
+
pushString: function(string) {
|
2207
|
+
this.pushStackLiteral(this.quotedString(string));
|
2208
|
+
},
|
2174
2209
|
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
};
|
2186
|
-
if (knownHelpers) {
|
2187
|
-
for (var name in knownHelpers) {
|
2188
|
-
this.options.knownHelpers[name] = knownHelpers[name];
|
2189
|
-
}
|
2190
|
-
}
|
2210
|
+
// [push]
|
2211
|
+
//
|
2212
|
+
// On stack, before: ...
|
2213
|
+
// On stack, after: expr, ...
|
2214
|
+
//
|
2215
|
+
// Push an expression onto the stack
|
2216
|
+
push: function(expr) {
|
2217
|
+
this.inlineStack.push(expr);
|
2218
|
+
return expr;
|
2219
|
+
},
|
2191
2220
|
|
2192
|
-
|
2221
|
+
// [pushLiteral]
|
2222
|
+
//
|
2223
|
+
// On stack, before: ...
|
2224
|
+
// On stack, after: value, ...
|
2225
|
+
//
|
2226
|
+
// Pushes a value onto the stack. This operation prevents
|
2227
|
+
// the compiler from creating a temporary variable to hold
|
2228
|
+
// it.
|
2229
|
+
pushLiteral: function(value) {
|
2230
|
+
this.pushStackLiteral(value);
|
2193
2231
|
},
|
2194
2232
|
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2233
|
+
// [pushProgram]
|
2234
|
+
//
|
2235
|
+
// On stack, before: ...
|
2236
|
+
// On stack, after: program(guid), ...
|
2237
|
+
//
|
2238
|
+
// Push a program expression onto the stack. This takes
|
2239
|
+
// a compile-time guid and converts it into a runtime-accessible
|
2240
|
+
// expression.
|
2241
|
+
pushProgram: function(guid) {
|
2242
|
+
if (guid != null) {
|
2243
|
+
this.pushStackLiteral(this.programExpression(guid));
|
2244
|
+
} else {
|
2245
|
+
this.pushStackLiteral(null);
|
2200
2246
|
}
|
2247
|
+
},
|
2248
|
+
|
2249
|
+
// [invokeHelper]
|
2250
|
+
//
|
2251
|
+
// On stack, before: hash, inverse, program, params..., ...
|
2252
|
+
// On stack, after: result of helper invocation
|
2253
|
+
//
|
2254
|
+
// Pops off the helper's parameters, invokes the helper,
|
2255
|
+
// and pushes the helper's return value onto the stack.
|
2256
|
+
//
|
2257
|
+
// If the helper is not found, `helperMissing` is called.
|
2258
|
+
invokeHelper: function(paramSize, name, isRoot) {
|
2259
|
+
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
2260
|
+
this.useRegister('helper');
|
2201
2261
|
|
2202
|
-
|
2262
|
+
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
2263
|
+
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
2203
2264
|
|
2204
|
-
|
2205
|
-
|
2265
|
+
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
2266
|
+
if (helper.paramsInit) {
|
2267
|
+
lookup += ',' + helper.paramsInit;
|
2206
2268
|
}
|
2207
2269
|
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2270
|
+
this.push(
|
2271
|
+
'('
|
2272
|
+
+ lookup
|
2273
|
+
+ ',helper '
|
2274
|
+
+ '? helper.call(' + helper.callParams + ') '
|
2275
|
+
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
2213
2276
|
|
2214
|
-
|
2215
|
-
|
2277
|
+
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
2278
|
+
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
2279
|
+
// due to the incorrect options object being passed due to the shared register.
|
2280
|
+
if (!isRoot) {
|
2281
|
+
this.flushInline();
|
2216
2282
|
}
|
2217
|
-
|
2218
|
-
|
2219
|
-
this.depths.list = this.depths.list.sort(function(a, b) {
|
2220
|
-
return a - b;
|
2221
|
-
});
|
2283
|
+
},
|
2222
2284
|
|
2223
|
-
|
2285
|
+
// [invokeKnownHelper]
|
2286
|
+
//
|
2287
|
+
// On stack, before: hash, inverse, program, params..., ...
|
2288
|
+
// On stack, after: result of helper invocation
|
2289
|
+
//
|
2290
|
+
// This operation is used when the helper is known to exist,
|
2291
|
+
// so a `helperMissing` fallback is not required.
|
2292
|
+
invokeKnownHelper: function(paramSize, name) {
|
2293
|
+
var helper = this.setupHelper(paramSize, name);
|
2294
|
+
this.push(helper.name + ".call(" + helper.callParams + ")");
|
2224
2295
|
},
|
2225
2296
|
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2297
|
+
// [invokeAmbiguous]
|
2298
|
+
//
|
2299
|
+
// On stack, before: hash, inverse, program, params..., ...
|
2300
|
+
// On stack, after: result of disambiguation
|
2301
|
+
//
|
2302
|
+
// This operation is used when an expression like `{{foo}}`
|
2303
|
+
// is provided, but we don't know at compile-time whether it
|
2304
|
+
// is a helper or a path.
|
2305
|
+
//
|
2306
|
+
// This operation emits more code than the other options,
|
2307
|
+
// and can be avoided by passing the `knownHelpers` and
|
2308
|
+
// `knownHelpersOnly` flags at compile-time.
|
2309
|
+
invokeAmbiguous: function(name, helperCall) {
|
2310
|
+
this.context.aliases.functionType = '"function"';
|
2311
|
+
this.useRegister('helper');
|
2229
2312
|
|
2230
|
-
this.
|
2313
|
+
this.emptyHash();
|
2314
|
+
var helper = this.setupHelper(0, name, helperCall);
|
2231
2315
|
|
2232
|
-
this.
|
2316
|
+
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
2233
2317
|
|
2234
|
-
|
2235
|
-
|
2318
|
+
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
2319
|
+
var nextStack = this.nextStack();
|
2236
2320
|
|
2237
|
-
|
2238
|
-
|
2321
|
+
if (helper.paramsInit) {
|
2322
|
+
this.pushSource(helper.paramsInit);
|
2239
2323
|
}
|
2240
|
-
|
2241
|
-
|
2324
|
+
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
2325
|
+
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
2242
2326
|
},
|
2243
2327
|
|
2244
|
-
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2250
|
-
|
2251
|
-
|
2328
|
+
// [invokePartial]
|
2329
|
+
//
|
2330
|
+
// On stack, before: context, ...
|
2331
|
+
// On stack after: result of partial invocation
|
2332
|
+
//
|
2333
|
+
// This operation pops off a context, invokes a partial with that context,
|
2334
|
+
// and pushes the result of the invocation back.
|
2335
|
+
invokePartial: function(name) {
|
2336
|
+
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
2252
2337
|
|
2253
|
-
if (
|
2254
|
-
|
2338
|
+
if (this.options.data) {
|
2339
|
+
params.push("data");
|
2255
2340
|
}
|
2256
2341
|
|
2257
|
-
|
2258
|
-
|
2259
|
-
|
2260
|
-
this.helperMustache(mustache, program, inverse);
|
2261
|
-
} else if (type === "simple") {
|
2262
|
-
this.simpleMustache(mustache);
|
2342
|
+
this.context.aliases.self = "this";
|
2343
|
+
this.push("self.invokePartial(" + params.join(", ") + ")");
|
2344
|
+
},
|
2263
2345
|
|
2264
|
-
|
2265
|
-
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2346
|
+
// [assignToHash]
|
2347
|
+
//
|
2348
|
+
// On stack, before: value, hash, ...
|
2349
|
+
// On stack, after: hash, ...
|
2350
|
+
//
|
2351
|
+
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
2352
|
+
// and pushes the hash back onto the stack.
|
2353
|
+
assignToHash: function(key) {
|
2354
|
+
var value = this.popStack(),
|
2355
|
+
context,
|
2356
|
+
type;
|
2272
2357
|
|
2273
|
-
|
2274
|
-
|
2275
|
-
this.
|
2276
|
-
this.opcode('pushProgram', inverse);
|
2277
|
-
this.opcode('emptyHash');
|
2278
|
-
this.opcode('ambiguousBlockValue');
|
2358
|
+
if (this.options.stringParams) {
|
2359
|
+
type = this.popStack();
|
2360
|
+
context = this.popStack();
|
2279
2361
|
}
|
2280
2362
|
|
2281
|
-
this.
|
2363
|
+
var hash = this.hash;
|
2364
|
+
if (context) {
|
2365
|
+
hash.contexts.push("'" + key + "': " + context);
|
2366
|
+
}
|
2367
|
+
if (type) {
|
2368
|
+
hash.types.push("'" + key + "': " + type);
|
2369
|
+
}
|
2370
|
+
hash.values.push("'" + key + "': (" + value + ")");
|
2282
2371
|
},
|
2283
2372
|
|
2284
|
-
|
2285
|
-
var pairs = hash.pairs, pair, val;
|
2373
|
+
// HELPERS
|
2286
2374
|
|
2287
|
-
|
2375
|
+
compiler: JavaScriptCompiler,
|
2288
2376
|
|
2289
|
-
|
2290
|
-
|
2291
|
-
val = pair[1];
|
2377
|
+
compileChildren: function(environment, options) {
|
2378
|
+
var children = environment.children, child, compiler;
|
2292
2379
|
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2380
|
+
for(var i=0, l=children.length; i<l; i++) {
|
2381
|
+
child = children[i];
|
2382
|
+
compiler = new this.compiler();
|
2383
|
+
|
2384
|
+
var index = this.matchExistingProgram(child);
|
2385
|
+
|
2386
|
+
if (index == null) {
|
2387
|
+
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
2388
|
+
index = this.context.programs.length;
|
2389
|
+
child.index = index;
|
2390
|
+
child.name = 'program' + index;
|
2391
|
+
this.context.programs[index] = compiler.compile(child, options, this.context);
|
2392
|
+
this.context.environments[index] = child;
|
2299
2393
|
} else {
|
2300
|
-
|
2394
|
+
child.index = index;
|
2395
|
+
child.name = 'program' + index;
|
2396
|
+
}
|
2397
|
+
}
|
2398
|
+
},
|
2399
|
+
matchExistingProgram: function(child) {
|
2400
|
+
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
2401
|
+
var environment = this.context.environments[i];
|
2402
|
+
if (environment && environment.equals(child)) {
|
2403
|
+
return i;
|
2301
2404
|
}
|
2302
|
-
|
2303
|
-
this.opcode('assignToHash', pair[0]);
|
2304
2405
|
}
|
2305
|
-
this.opcode('popHash');
|
2306
2406
|
},
|
2307
2407
|
|
2308
|
-
|
2309
|
-
|
2310
|
-
this.usePartial = true;
|
2408
|
+
programExpression: function(guid) {
|
2409
|
+
this.context.aliases.self = "this";
|
2311
2410
|
|
2312
|
-
if(
|
2313
|
-
|
2314
|
-
} else {
|
2315
|
-
this.opcode('push', 'depth0');
|
2411
|
+
if(guid == null) {
|
2412
|
+
return "self.noop";
|
2316
2413
|
}
|
2317
2414
|
|
2318
|
-
this.
|
2319
|
-
|
2320
|
-
},
|
2415
|
+
var child = this.environment.children[guid],
|
2416
|
+
depths = child.depths.list, depth;
|
2321
2417
|
|
2322
|
-
|
2323
|
-
this.opcode('appendContent', content.string);
|
2324
|
-
},
|
2418
|
+
var programParams = [child.index, child.name, "data"];
|
2325
2419
|
|
2326
|
-
|
2327
|
-
|
2328
|
-
var type = this.classifyMustache(mustache);
|
2420
|
+
for(var i=0, l = depths.length; i<l; i++) {
|
2421
|
+
depth = depths[i];
|
2329
2422
|
|
2330
|
-
|
2331
|
-
|
2332
|
-
} else if (type === "helper") {
|
2333
|
-
this.helperMustache(mustache);
|
2334
|
-
} else {
|
2335
|
-
this.ambiguousMustache(mustache);
|
2423
|
+
if(depth === 1) { programParams.push("depth0"); }
|
2424
|
+
else { programParams.push("depth" + (depth - 1)); }
|
2336
2425
|
}
|
2337
2426
|
|
2338
|
-
|
2339
|
-
this.opcode('appendEscaped');
|
2340
|
-
} else {
|
2341
|
-
this.opcode('append');
|
2342
|
-
}
|
2427
|
+
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
2343
2428
|
},
|
2344
2429
|
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
this.opcode('getContext', id.depth);
|
2430
|
+
register: function(name, val) {
|
2431
|
+
this.useRegister(name);
|
2432
|
+
this.pushSource(name + " = " + val + ";");
|
2433
|
+
},
|
2351
2434
|
|
2352
|
-
|
2353
|
-
this.
|
2435
|
+
useRegister: function(name) {
|
2436
|
+
if(!this.registers[name]) {
|
2437
|
+
this.registers[name] = true;
|
2438
|
+
this.registers.list.push(name);
|
2439
|
+
}
|
2440
|
+
},
|
2354
2441
|
|
2355
|
-
|
2442
|
+
pushStackLiteral: function(item) {
|
2443
|
+
return this.push(new Literal(item));
|
2356
2444
|
},
|
2357
2445
|
|
2358
|
-
|
2359
|
-
|
2446
|
+
pushSource: function(source) {
|
2447
|
+
if (this.pendingContent) {
|
2448
|
+
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
2449
|
+
this.pendingContent = undefined;
|
2450
|
+
}
|
2360
2451
|
|
2361
|
-
if (
|
2362
|
-
this.
|
2363
|
-
} else if (id.parts.length) {
|
2364
|
-
this.ID(id);
|
2365
|
-
} else {
|
2366
|
-
// Simplified ID for `this`
|
2367
|
-
this.addDepth(id.depth);
|
2368
|
-
this.opcode('getContext', id.depth);
|
2369
|
-
this.opcode('pushContext');
|
2452
|
+
if (source) {
|
2453
|
+
this.source.push(source);
|
2370
2454
|
}
|
2455
|
+
},
|
2371
2456
|
|
2372
|
-
|
2457
|
+
pushStack: function(item) {
|
2458
|
+
this.flushInline();
|
2459
|
+
|
2460
|
+
var stack = this.incrStack();
|
2461
|
+
if (item) {
|
2462
|
+
this.pushSource(stack + " = " + item + ";");
|
2463
|
+
}
|
2464
|
+
this.compileStack.push(stack);
|
2465
|
+
return stack;
|
2373
2466
|
},
|
2374
2467
|
|
2375
|
-
|
2376
|
-
var
|
2377
|
-
|
2468
|
+
replaceStack: function(callback) {
|
2469
|
+
var prefix = '',
|
2470
|
+
inline = this.isInline(),
|
2471
|
+
stack,
|
2472
|
+
createdStack,
|
2473
|
+
usedLiteral;
|
2474
|
+
|
2475
|
+
// If we are currently inline then we want to merge the inline statement into the
|
2476
|
+
// replacement statement via ','
|
2477
|
+
if (inline) {
|
2478
|
+
var top = this.popStack(true);
|
2479
|
+
|
2480
|
+
if (top instanceof Literal) {
|
2481
|
+
// Literals do not need to be inlined
|
2482
|
+
stack = top.value;
|
2483
|
+
usedLiteral = true;
|
2484
|
+
} else {
|
2485
|
+
// Get or create the current stack name for use by the inline
|
2486
|
+
createdStack = !this.stackSlot;
|
2487
|
+
var name = !createdStack ? this.topStackName() : this.incrStack();
|
2378
2488
|
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
|
2489
|
+
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
2490
|
+
stack = this.topStack();
|
2491
|
+
}
|
2383
2492
|
} else {
|
2384
|
-
this.
|
2493
|
+
stack = this.topStack();
|
2385
2494
|
}
|
2386
|
-
},
|
2387
2495
|
|
2388
|
-
|
2389
|
-
this.addDepth(id.depth);
|
2390
|
-
this.opcode('getContext', id.depth);
|
2496
|
+
var item = callback.call(this, stack);
|
2391
2497
|
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2498
|
+
if (inline) {
|
2499
|
+
if (!usedLiteral) {
|
2500
|
+
this.popStack();
|
2501
|
+
}
|
2502
|
+
if (createdStack) {
|
2503
|
+
this.stackSlot--;
|
2504
|
+
}
|
2505
|
+
this.push('(' + prefix + item + ')');
|
2395
2506
|
} else {
|
2396
|
-
|
2397
|
-
|
2507
|
+
// Prevent modification of the context depth variable. Through replaceStack
|
2508
|
+
if (!/^stack/.test(stack)) {
|
2509
|
+
stack = this.nextStack();
|
2510
|
+
}
|
2398
2511
|
|
2399
|
-
|
2400
|
-
this.opcode('lookup', id.parts[i]);
|
2512
|
+
this.pushSource(stack + " = (" + prefix + item + ");");
|
2401
2513
|
}
|
2514
|
+
return stack;
|
2402
2515
|
},
|
2403
2516
|
|
2404
|
-
|
2405
|
-
this.
|
2406
|
-
|
2407
|
-
throw new Exception('Scoped data references are not supported: ' + data.original);
|
2408
|
-
}
|
2517
|
+
nextStack: function() {
|
2518
|
+
return this.pushStack();
|
2519
|
+
},
|
2409
2520
|
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2521
|
+
incrStack: function() {
|
2522
|
+
this.stackSlot++;
|
2523
|
+
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
2524
|
+
return this.topStackName();
|
2525
|
+
},
|
2526
|
+
topStackName: function() {
|
2527
|
+
return "stack" + this.stackSlot;
|
2528
|
+
},
|
2529
|
+
flushInline: function() {
|
2530
|
+
var inlineStack = this.inlineStack;
|
2531
|
+
if (inlineStack.length) {
|
2532
|
+
this.inlineStack = [];
|
2533
|
+
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
2534
|
+
var entry = inlineStack[i];
|
2535
|
+
if (entry instanceof Literal) {
|
2536
|
+
this.compileStack.push(entry);
|
2537
|
+
} else {
|
2538
|
+
this.pushStack(entry);
|
2539
|
+
}
|
2540
|
+
}
|
2414
2541
|
}
|
2415
2542
|
},
|
2416
|
-
|
2417
|
-
|
2418
|
-
this.opcode('pushString', string.string);
|
2543
|
+
isInline: function() {
|
2544
|
+
return this.inlineStack.length;
|
2419
2545
|
},
|
2420
2546
|
|
2421
|
-
|
2422
|
-
this.
|
2423
|
-
|
2547
|
+
popStack: function(wrapped) {
|
2548
|
+
var inline = this.isInline(),
|
2549
|
+
item = (inline ? this.inlineStack : this.compileStack).pop();
|
2424
2550
|
|
2425
|
-
|
2426
|
-
|
2551
|
+
if (!wrapped && (item instanceof Literal)) {
|
2552
|
+
return item.value;
|
2553
|
+
} else {
|
2554
|
+
if (!inline) {
|
2555
|
+
if (!this.stackSlot) {
|
2556
|
+
throw new Exception('Invalid stack pop');
|
2557
|
+
}
|
2558
|
+
this.stackSlot--;
|
2559
|
+
}
|
2560
|
+
return item;
|
2561
|
+
}
|
2427
2562
|
},
|
2428
2563
|
|
2429
|
-
|
2564
|
+
topStack: function(wrapped) {
|
2565
|
+
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
2566
|
+
item = stack[stack.length - 1];
|
2430
2567
|
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2568
|
+
if (!wrapped && (item instanceof Literal)) {
|
2569
|
+
return item.value;
|
2570
|
+
} else {
|
2571
|
+
return item;
|
2572
|
+
}
|
2434
2573
|
},
|
2435
2574
|
|
2436
|
-
|
2437
|
-
|
2575
|
+
quotedString: function(str) {
|
2576
|
+
return '"' + str
|
2577
|
+
.replace(/\\/g, '\\\\')
|
2578
|
+
.replace(/"/g, '\\"')
|
2579
|
+
.replace(/\n/g, '\\n')
|
2580
|
+
.replace(/\r/g, '\\r')
|
2581
|
+
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
2582
|
+
.replace(/\u2029/g, '\\u2029') + '"';
|
2438
2583
|
},
|
2439
2584
|
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2585
|
+
setupHelper: function(paramSize, name, missingParams) {
|
2586
|
+
var params = [],
|
2587
|
+
paramsInit = this.setupParams(paramSize, params, missingParams);
|
2588
|
+
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
2443
2589
|
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2590
|
+
return {
|
2591
|
+
params: params,
|
2592
|
+
paramsInit: paramsInit,
|
2593
|
+
name: foundHelper,
|
2594
|
+
callParams: ["depth0"].concat(params).join(", "),
|
2595
|
+
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
2596
|
+
};
|
2448
2597
|
},
|
2449
2598
|
|
2450
|
-
|
2451
|
-
var
|
2452
|
-
var isEligible = mustache.eligibleHelper;
|
2453
|
-
var options = this.options;
|
2599
|
+
setupOptions: function(paramSize, params) {
|
2600
|
+
var options = [], contexts = [], types = [], param, inverse, program;
|
2454
2601
|
|
2455
|
-
|
2456
|
-
if (isEligible && !isHelper) {
|
2457
|
-
var name = mustache.id.parts[0];
|
2602
|
+
options.push("hash:" + this.popStack());
|
2458
2603
|
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
isEligible = false;
|
2463
|
-
}
|
2604
|
+
if (this.options.stringParams) {
|
2605
|
+
options.push("hashTypes:" + this.popStack());
|
2606
|
+
options.push("hashContexts:" + this.popStack());
|
2464
2607
|
}
|
2465
2608
|
|
2466
|
-
|
2467
|
-
|
2468
|
-
else { return "simple"; }
|
2469
|
-
},
|
2609
|
+
inverse = this.popStack();
|
2610
|
+
program = this.popStack();
|
2470
2611
|
|
2471
|
-
|
2472
|
-
|
2612
|
+
// Avoid setting fn and inverse if neither are set. This allows
|
2613
|
+
// helpers to do a check for `if (options.fn)`
|
2614
|
+
if (program || inverse) {
|
2615
|
+
if (!program) {
|
2616
|
+
this.context.aliases.self = "this";
|
2617
|
+
program = "self.noop";
|
2618
|
+
}
|
2473
2619
|
|
2474
|
-
|
2475
|
-
|
2620
|
+
if (!inverse) {
|
2621
|
+
this.context.aliases.self = "this";
|
2622
|
+
inverse = "self.noop";
|
2623
|
+
}
|
2476
2624
|
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
}
|
2625
|
+
options.push("inverse:" + inverse);
|
2626
|
+
options.push("fn:" + program);
|
2627
|
+
}
|
2481
2628
|
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2629
|
+
for(var i=0; i<paramSize; i++) {
|
2630
|
+
param = this.popStack();
|
2631
|
+
params.push(param);
|
2632
|
+
|
2633
|
+
if(this.options.stringParams) {
|
2634
|
+
types.push(this.popStack());
|
2635
|
+
contexts.push(this.popStack());
|
2486
2636
|
}
|
2487
2637
|
}
|
2488
|
-
},
|
2489
2638
|
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2639
|
+
if (this.options.stringParams) {
|
2640
|
+
options.push("contexts:[" + contexts.join(",") + "]");
|
2641
|
+
options.push("types:[" + types.join(",") + "]");
|
2642
|
+
}
|
2493
2643
|
|
2494
|
-
if(
|
2495
|
-
|
2496
|
-
} else {
|
2497
|
-
this.opcode('emptyHash');
|
2644
|
+
if(this.options.data) {
|
2645
|
+
options.push("data:data");
|
2498
2646
|
}
|
2499
2647
|
|
2500
|
-
return
|
2648
|
+
return options;
|
2501
2649
|
},
|
2502
2650
|
|
2503
|
-
//
|
2504
|
-
|
2505
|
-
|
2506
|
-
this.
|
2507
|
-
|
2508
|
-
this.opcode('pushProgram', program);
|
2509
|
-
this.opcode('pushProgram', inverse);
|
2651
|
+
// the params and contexts arguments are passed in arrays
|
2652
|
+
// to fill in
|
2653
|
+
setupParams: function(paramSize, params, useRegister) {
|
2654
|
+
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
2510
2655
|
|
2511
|
-
if(
|
2512
|
-
this.
|
2656
|
+
if (useRegister) {
|
2657
|
+
this.useRegister('options');
|
2658
|
+
params.push('options');
|
2659
|
+
return 'options=' + options;
|
2513
2660
|
} else {
|
2514
|
-
|
2661
|
+
params.push(options);
|
2662
|
+
return '';
|
2515
2663
|
}
|
2516
|
-
|
2517
|
-
return params;
|
2518
2664
|
}
|
2519
2665
|
};
|
2520
2666
|
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2667
|
+
var reservedWords = (
|
2668
|
+
"break else new var" +
|
2669
|
+
" case finally return void" +
|
2670
|
+
" catch for switch while" +
|
2671
|
+
" continue function this with" +
|
2672
|
+
" default if throw" +
|
2673
|
+
" delete in try" +
|
2674
|
+
" do instanceof typeof" +
|
2675
|
+
" abstract enum int short" +
|
2676
|
+
" boolean export interface static" +
|
2677
|
+
" byte extends long super" +
|
2678
|
+
" char final native synchronized" +
|
2679
|
+
" class float package throws" +
|
2680
|
+
" const goto private transient" +
|
2681
|
+
" debugger implements protected volatile" +
|
2682
|
+
" double import public let yield"
|
2683
|
+
).split(" ");
|
2525
2684
|
|
2526
|
-
|
2527
|
-
if (!('data' in options)) {
|
2528
|
-
options.data = true;
|
2529
|
-
}
|
2685
|
+
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
2530
2686
|
|
2531
|
-
|
2532
|
-
|
2533
|
-
return new JavaScriptCompiler().compile(environment, options);
|
2687
|
+
for(var i=0, l=reservedWords.length; i<l; i++) {
|
2688
|
+
compilerWords[reservedWords[i]] = true;
|
2534
2689
|
}
|
2535
2690
|
|
2536
|
-
|
2537
|
-
if
|
2538
|
-
|
2539
|
-
}
|
2540
|
-
|
2541
|
-
options = options || {};
|
2542
|
-
|
2543
|
-
if (!('data' in options)) {
|
2544
|
-
options.data = true;
|
2545
|
-
}
|
2546
|
-
|
2547
|
-
var compiled;
|
2548
|
-
|
2549
|
-
function compileInput() {
|
2550
|
-
var ast = parse(input);
|
2551
|
-
var environment = new Compiler().compile(ast, options);
|
2552
|
-
var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
|
2553
|
-
return env.template(templateSpec);
|
2691
|
+
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
2692
|
+
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
2693
|
+
return true;
|
2554
2694
|
}
|
2695
|
+
return false;
|
2696
|
+
};
|
2555
2697
|
|
2556
|
-
|
2557
|
-
return function(context, options) {
|
2558
|
-
if (!compiled) {
|
2559
|
-
compiled = compileInput();
|
2560
|
-
}
|
2561
|
-
return compiled.call(this, context, options);
|
2562
|
-
};
|
2563
|
-
}
|
2564
|
-
|
2565
|
-
__exports__.compile = compile;
|
2698
|
+
__exports__ = JavaScriptCompiler;
|
2566
2699
|
return __exports__;
|
2567
|
-
})(
|
2700
|
+
})(__module2__, __module5__);
|
2568
2701
|
|
2569
2702
|
// handlebars.js
|
2570
2703
|
var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
|
@@ -2589,7 +2722,9 @@ var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, _
|
|
2589
2722
|
hb.compile = function(input, options) {
|
2590
2723
|
return compile(input, options, hb);
|
2591
2724
|
};
|
2592
|
-
hb.precompile =
|
2725
|
+
hb.precompile = function (input, options) {
|
2726
|
+
return precompile(input, options, hb);
|
2727
|
+
};
|
2593
2728
|
|
2594
2729
|
hb.AST = AST;
|
2595
2730
|
hb.Compiler = Compiler;
|