handlebar_wax 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,2 @@
1
+ //= require handlebars.js
2
+ //= require handlebars_templates.js
@@ -0,0 +1,1417 @@
1
+ // lib/handlebars/parser.js
2
+ /* Jison generated parser */
3
+ var handlebars = (function(){
4
+ var parser = {trace: function trace() { },
5
+ yy: {},
6
+ symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"hashSegments":29,"hashSegment":30,"ID":31,"EQUALS":32,"pathSegments":33,"SEP":34,"$accept":0,"$end":1},
7
+ terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",31:"ID",32:"EQUALS",34:"SEP"},
8
+ productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[26,1],[29,2],[29,1],[30,3],[30,3],[21,1],[33,3],[33,1]],
9
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
10
+
11
+ var $0 = $$.length - 1;
12
+ switch (yystate) {
13
+ case 1: return $$[$0-1]
14
+ break;
15
+ case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
16
+ break;
17
+ case 3: this.$ = new yy.ProgramNode($$[$0])
18
+ break;
19
+ case 4: this.$ = new yy.ProgramNode([])
20
+ break;
21
+ case 5: this.$ = [$$[$0]]
22
+ break;
23
+ case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
24
+ break;
25
+ case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
26
+ break;
27
+ case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
28
+ break;
29
+ case 9: this.$ = $$[$0]
30
+ break;
31
+ case 10: this.$ = $$[$0]
32
+ break;
33
+ case 11: this.$ = new yy.ContentNode($$[$0])
34
+ break;
35
+ case 12: this.$ = new yy.CommentNode($$[$0])
36
+ break;
37
+ case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
38
+ break;
39
+ case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
40
+ break;
41
+ case 15: this.$ = $$[$0-1]
42
+ break;
43
+ case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
44
+ break;
45
+ case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
46
+ break;
47
+ case 18: this.$ = new yy.PartialNode($$[$0-1])
48
+ break;
49
+ case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
50
+ break;
51
+ case 20:
52
+ break;
53
+ case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
54
+ break;
55
+ case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
56
+ break;
57
+ case 23: this.$ = [[$$[$0-1]], $$[$0]]
58
+ break;
59
+ case 24: this.$ = [[$$[$0]], null]
60
+ break;
61
+ case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
62
+ break;
63
+ case 26: this.$ = [$$[$0]]
64
+ break;
65
+ case 27: this.$ = $$[$0]
66
+ break;
67
+ case 28: this.$ = new yy.StringNode($$[$0])
68
+ break;
69
+ case 29: this.$ = new yy.HashNode($$[$0])
70
+ break;
71
+ case 30: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
72
+ break;
73
+ case 31: this.$ = [$$[$0]]
74
+ break;
75
+ case 32: this.$ = [$$[$0-2], $$[$0]]
76
+ break;
77
+ case 33: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
78
+ break;
79
+ case 34: this.$ = new yy.IdNode($$[$0])
80
+ break;
81
+ case 35: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
82
+ break;
83
+ case 36: this.$ = [$$[$0]]
84
+ break;
85
+ }
86
+ },
87
+ table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,31:[1,25],33:24},{17:26,21:23,31:[1,25],33:24},{17:27,21:23,31:[1,25],33:24},{17:28,21:23,31:[1,25],33:24},{21:29,31:[1,25],33:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,31:[1,25],33:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:39,30:42,31:[1,43],33:24},{18:[2,34],28:[2,34],31:[2,34],34:[1,44]},{18:[2,36],28:[2,36],31:[2,36],34:[2,36]},{18:[1,45]},{18:[1,46]},{18:[1,47]},{18:[1,48],21:49,31:[1,25],33:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:50,31:[1,25],33:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:51,27:52,28:[1,41],29:39,30:42,31:[1,43],33:24},{18:[2,23]},{18:[2,26],28:[2,26],31:[2,26]},{18:[2,29],30:53,31:[1,54]},{18:[2,27],28:[2,27],31:[2,27]},{18:[2,28],28:[2,28],31:[2,28]},{18:[2,31],31:[2,31]},{18:[2,36],28:[2,36],31:[2,36],32:[1,55],34:[2,36]},{31:[1,56]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,57]},{18:[1,58]},{18:[2,21]},{18:[2,25],28:[2,25],31:[2,25]},{18:[2,30],31:[2,30]},{32:[1,55]},{21:59,28:[1,60],31:[1,25],33:24},{18:[2,35],28:[2,35],31:[2,35],34:[2,35]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,32],31:[2,32]},{18:[2,33],31:[2,33]}],
88
+ defaultActions: {16:[2,1],37:[2,23],51:[2,21]},
89
+ parseError: function parseError(str, hash) {
90
+ throw new Error(str);
91
+ },
92
+ parse: function parse(input) {
93
+ var self = this,
94
+ stack = [0],
95
+ vstack = [null], // semantic value stack
96
+ lstack = [], // location stack
97
+ table = this.table,
98
+ yytext = '',
99
+ yylineno = 0,
100
+ yyleng = 0,
101
+ recovering = 0,
102
+ TERROR = 2,
103
+ EOF = 1;
104
+
105
+ //this.reductionCount = this.shiftCount = 0;
106
+
107
+ this.lexer.setInput(input);
108
+ this.lexer.yy = this.yy;
109
+ this.yy.lexer = this.lexer;
110
+ var yyloc = this.lexer.yylloc;
111
+ lstack.push(yyloc);
112
+
113
+ if (typeof this.yy.parseError === 'function')
114
+ this.parseError = this.yy.parseError;
115
+
116
+ function popStack (n) {
117
+ stack.length = stack.length - 2*n;
118
+ vstack.length = vstack.length - n;
119
+ lstack.length = lstack.length - n;
120
+ }
121
+
122
+ function lex() {
123
+ var token;
124
+ token = self.lexer.lex() || 1; // $end = 1
125
+ // if token isn't its numeric value, convert
126
+ if (typeof token !== 'number') {
127
+ token = self.symbols_[token] || token;
128
+ }
129
+ return token;
130
+ };
131
+
132
+ var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
133
+ while (true) {
134
+ // retreive state number from top of stack
135
+ state = stack[stack.length-1];
136
+
137
+ // use default actions if available
138
+ if (this.defaultActions[state]) {
139
+ action = this.defaultActions[state];
140
+ } else {
141
+ if (symbol == null)
142
+ symbol = lex();
143
+ // read action for current state and first input
144
+ action = table[state] && table[state][symbol];
145
+ }
146
+
147
+ // handle parse error
148
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
149
+
150
+ if (!recovering) {
151
+ // Report error
152
+ expected = [];
153
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
154
+ expected.push("'"+this.terminals_[p]+"'");
155
+ }
156
+ var errStr = '';
157
+ if (this.lexer.showPosition) {
158
+ errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
159
+ } else {
160
+ errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
161
+ (symbol == 1 /*EOF*/ ? "end of input" :
162
+ ("'"+(this.terminals_[symbol] || symbol)+"'"));
163
+ }
164
+ this.parseError(errStr,
165
+ {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
166
+ }
167
+
168
+ // just recovered from another error
169
+ if (recovering == 3) {
170
+ if (symbol == EOF) {
171
+ throw new Error(errStr || 'Parsing halted.');
172
+ }
173
+
174
+ // discard current lookahead and grab another
175
+ yyleng = this.lexer.yyleng;
176
+ yytext = this.lexer.yytext;
177
+ yylineno = this.lexer.yylineno;
178
+ yyloc = this.lexer.yylloc;
179
+ symbol = lex();
180
+ }
181
+
182
+ // try to recover from error
183
+ while (1) {
184
+ // check for error recovery rule in this state
185
+ if ((TERROR.toString()) in table[state]) {
186
+ break;
187
+ }
188
+ if (state == 0) {
189
+ throw new Error(errStr || 'Parsing halted.');
190
+ }
191
+ popStack(1);
192
+ state = stack[stack.length-1];
193
+ }
194
+
195
+ preErrorSymbol = symbol; // save the lookahead token
196
+ symbol = TERROR; // insert generic error symbol as new lookahead
197
+ state = stack[stack.length-1];
198
+ action = table[state] && table[state][TERROR];
199
+ recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
200
+ }
201
+
202
+ // this shouldn't happen, unless resolve defaults are off
203
+ if (action[0] instanceof Array && action.length > 1) {
204
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
205
+ }
206
+
207
+ switch (action[0]) {
208
+
209
+ case 1: // shift
210
+ //this.shiftCount++;
211
+
212
+ stack.push(symbol);
213
+ vstack.push(this.lexer.yytext);
214
+ lstack.push(this.lexer.yylloc);
215
+ stack.push(action[1]); // push state
216
+ symbol = null;
217
+ if (!preErrorSymbol) { // normal execution/no error
218
+ yyleng = this.lexer.yyleng;
219
+ yytext = this.lexer.yytext;
220
+ yylineno = this.lexer.yylineno;
221
+ yyloc = this.lexer.yylloc;
222
+ if (recovering > 0)
223
+ recovering--;
224
+ } else { // error just occurred, resume old lookahead f/ before error
225
+ symbol = preErrorSymbol;
226
+ preErrorSymbol = null;
227
+ }
228
+ break;
229
+
230
+ case 2: // reduce
231
+ //this.reductionCount++;
232
+
233
+ len = this.productions_[action[1]][1];
234
+
235
+ // perform semantic action
236
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
237
+ // default location, uses first token for firsts, last for lasts
238
+ yyval._$ = {
239
+ first_line: lstack[lstack.length-(len||1)].first_line,
240
+ last_line: lstack[lstack.length-1].last_line,
241
+ first_column: lstack[lstack.length-(len||1)].first_column,
242
+ last_column: lstack[lstack.length-1].last_column,
243
+ };
244
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
245
+
246
+ if (typeof r !== 'undefined') {
247
+ return r;
248
+ }
249
+
250
+ // pop off stack
251
+ if (len) {
252
+ stack = stack.slice(0,-1*len*2);
253
+ vstack = vstack.slice(0, -1*len);
254
+ lstack = lstack.slice(0, -1*len);
255
+ }
256
+
257
+ stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
258
+ vstack.push(yyval.$);
259
+ lstack.push(yyval._$);
260
+ // goto new state = table[STATE][NONTERMINAL]
261
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
262
+ stack.push(newState);
263
+ break;
264
+
265
+ case 3: // accept
266
+ return true;
267
+ }
268
+
269
+ }
270
+
271
+ return true;
272
+ }};/* Jison generated lexer */
273
+ var lexer = (function(){var lexer = ({EOF:1,
274
+ parseError:function parseError(str, hash) {
275
+ if (this.yy.parseError) {
276
+ this.yy.parseError(str, hash);
277
+ } else {
278
+ throw new Error(str);
279
+ }
280
+ },
281
+ setInput:function (input) {
282
+ this._input = input;
283
+ this._more = this._less = this.done = false;
284
+ this.yylineno = this.yyleng = 0;
285
+ this.yytext = this.matched = this.match = '';
286
+ this.conditionStack = ['INITIAL'];
287
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
288
+ return this;
289
+ },
290
+ input:function () {
291
+ var ch = this._input[0];
292
+ this.yytext+=ch;
293
+ this.yyleng++;
294
+ this.match+=ch;
295
+ this.matched+=ch;
296
+ var lines = ch.match(/\n/);
297
+ if (lines) this.yylineno++;
298
+ this._input = this._input.slice(1);
299
+ return ch;
300
+ },
301
+ unput:function (ch) {
302
+ this._input = ch + this._input;
303
+ return this;
304
+ },
305
+ more:function () {
306
+ this._more = true;
307
+ return this;
308
+ },
309
+ pastInput:function () {
310
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
311
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
312
+ },
313
+ upcomingInput:function () {
314
+ var next = this.match;
315
+ if (next.length < 20) {
316
+ next += this._input.substr(0, 20-next.length);
317
+ }
318
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
319
+ },
320
+ showPosition:function () {
321
+ var pre = this.pastInput();
322
+ var c = new Array(pre.length + 1).join("-");
323
+ return pre + this.upcomingInput() + "\n" + c+"^";
324
+ },
325
+ next:function () {
326
+ if (this.done) {
327
+ return this.EOF;
328
+ }
329
+ if (!this._input) this.done = true;
330
+
331
+ var token,
332
+ match,
333
+ col,
334
+ lines;
335
+ if (!this._more) {
336
+ this.yytext = '';
337
+ this.match = '';
338
+ }
339
+ var rules = this._currentRules();
340
+ for (var i=0;i < rules.length; i++) {
341
+ match = this._input.match(this.rules[rules[i]]);
342
+ if (match) {
343
+ lines = match[0].match(/\n.*/g);
344
+ if (lines) this.yylineno += lines.length;
345
+ this.yylloc = {first_line: this.yylloc.last_line,
346
+ last_line: this.yylineno+1,
347
+ first_column: this.yylloc.last_column,
348
+ last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match.length}
349
+ this.yytext += match[0];
350
+ this.match += match[0];
351
+ this.matches = match;
352
+ this.yyleng = this.yytext.length;
353
+ this._more = false;
354
+ this._input = this._input.slice(match[0].length);
355
+ this.matched += match[0];
356
+ token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
357
+ if (token) return token;
358
+ else return;
359
+ }
360
+ }
361
+ if (this._input === "") {
362
+ return this.EOF;
363
+ } else {
364
+ this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
365
+ {text: "", token: null, line: this.yylineno});
366
+ }
367
+ },
368
+ lex:function lex() {
369
+ var r = this.next();
370
+ if (typeof r !== 'undefined') {
371
+ return r;
372
+ } else {
373
+ return this.lex();
374
+ }
375
+ },
376
+ begin:function begin(condition) {
377
+ this.conditionStack.push(condition);
378
+ },
379
+ popState:function popState() {
380
+ return this.conditionStack.pop();
381
+ },
382
+ _currentRules:function _currentRules() {
383
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
384
+ }});
385
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
386
+
387
+ var YYSTATE=YY_START
388
+ switch($avoiding_name_collisions) {
389
+ case 0: this.begin("mu"); if (yy_.yytext) return 14;
390
+ break;
391
+ case 1: return 14;
392
+ break;
393
+ case 2: return 24;
394
+ break;
395
+ case 3: return 16;
396
+ break;
397
+ case 4: return 20;
398
+ break;
399
+ case 5: return 19;
400
+ break;
401
+ case 6: return 19;
402
+ break;
403
+ case 7: return 23;
404
+ break;
405
+ case 8: return 23;
406
+ break;
407
+ case 9: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.begin("INITIAL"); return 15;
408
+ break;
409
+ case 10: return 22;
410
+ break;
411
+ case 11: return 32;
412
+ break;
413
+ case 12: return 31;
414
+ break;
415
+ case 13: return 31;
416
+ break;
417
+ case 14: return 34;
418
+ break;
419
+ case 15: /*ignore whitespace*/
420
+ break;
421
+ case 16: this.begin("INITIAL"); return 18;
422
+ break;
423
+ case 17: this.begin("INITIAL"); return 18;
424
+ break;
425
+ case 18: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
426
+ break;
427
+ case 19: return 31;
428
+ break;
429
+ case 20: return 'INVALID';
430
+ break;
431
+ case 21: return 5;
432
+ break;
433
+ }
434
+ };
435
+ lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{!.*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^[a-zA-Z0-9_]+(?=[=} /.])/,/^./,/^$/];
436
+ lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21],"inclusive":false},"INITIAL":{"rules":[0,1,21],"inclusive":true}};return lexer;})()
437
+ parser.lexer = lexer;
438
+ return parser;
439
+ })();
440
+ if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
441
+ exports.parser = handlebars;
442
+ exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
443
+ exports.main = function commonjsMain(args) {
444
+ if (!args[1])
445
+ throw new Error('Usage: '+args[0]+' FILE');
446
+ if (typeof process !== 'undefined') {
447
+ var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
448
+ } else {
449
+ var cwd = require("file").path(require("file").cwd());
450
+ var source = cwd.join(args[1]).read({charset: "utf-8"});
451
+ }
452
+ return exports.parser.parse(source);
453
+ }
454
+ if (typeof module !== 'undefined' && require.main === module) {
455
+ exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
456
+ }
457
+ };
458
+ // lib/handlebars/base.js
459
+ var Handlebars = {};
460
+
461
+ Handlebars.Parser = handlebars;
462
+
463
+ Handlebars.parse = function(string) {
464
+ Handlebars.Parser.yy = Handlebars.AST;
465
+ return Handlebars.Parser.parse(string);
466
+ };
467
+
468
+ Handlebars.print = function(ast) {
469
+ return new Handlebars.PrintVisitor().accept(ast);
470
+ };
471
+
472
+ Handlebars.Runtime = {};
473
+
474
+ Handlebars.Runtime.compile = function(string) {
475
+ var ast = Handlebars.parse(string);
476
+
477
+ return function(context, helpers, partials) {
478
+ helpers = helpers || Handlebars.helpers;
479
+ partials = partials || Handlebars.partials;
480
+
481
+ var internalContext = new Handlebars.Context(context, helpers, partials);
482
+ var runtime = new Handlebars.Runtime(internalContext);
483
+ runtime.accept(ast);
484
+ return runtime.buffer;
485
+ };
486
+ };
487
+
488
+ Handlebars.helpers = {};
489
+ Handlebars.partials = {};
490
+
491
+ Handlebars.registerHelper = function(name, fn, inverse) {
492
+ if(inverse) { fn.not = inverse; }
493
+ this.helpers[name] = fn;
494
+ };
495
+
496
+ Handlebars.registerPartial = function(name, str) {
497
+ this.partials[name] = str;
498
+ };
499
+
500
+ Handlebars.registerHelper('blockHelperMissing', function(context, fn, inverse) {
501
+ inverse = inverse || function() {};
502
+
503
+ var ret = "";
504
+ var type = Object.prototype.toString.call(context);
505
+
506
+ if(type === "[object Function]") {
507
+ context = context();
508
+ }
509
+
510
+ if(context === true) {
511
+ return fn(this);
512
+ } else if(context === false || context == null) {
513
+ return inverse(this);
514
+ } else if(type === "[object Array]") {
515
+ if(context.length > 0) {
516
+ for(var i=0, j=context.length; i<j; i++) {
517
+ ret = ret + fn(context[i]);
518
+ }
519
+ } else {
520
+ ret = inverse(this);
521
+ }
522
+ return ret;
523
+ } else {
524
+ return fn(context);
525
+ }
526
+ }, function(context, fn) {
527
+ return fn(context);
528
+ });
529
+
530
+ Handlebars.registerHelper('each', function(context, fn, inverse) {
531
+ var ret = "";
532
+
533
+ if(context && context.length > 0) {
534
+ for(var i=0, j=context.length; i<j; i++) {
535
+ ret = ret + fn(context[i]);
536
+ }
537
+ } else {
538
+ ret = inverse(this);
539
+ }
540
+ return ret;
541
+ });
542
+
543
+ Handlebars.registerHelper('if', function(context, fn, inverse) {
544
+ if(!context || context == []) {
545
+ return inverse(this);
546
+ } else {
547
+ return fn(this);
548
+ }
549
+ });
550
+
551
+ Handlebars.registerHelper('unless', function(context, fn, inverse) {
552
+ return Handlebars.helpers['if'].call(this, context, inverse, fn);
553
+ });
554
+
555
+ Handlebars.registerHelper('with', function(context, fn) {
556
+ return fn(context);
557
+ });
558
+
559
+ Handlebars.logger = {
560
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
561
+
562
+ // override in the host environment
563
+ log: function(level, str) {}
564
+ };
565
+
566
+ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
567
+ ;
568
+ // lib/handlebars/ast.js
569
+ (function() {
570
+
571
+ Handlebars.AST = {};
572
+
573
+ Handlebars.AST.ProgramNode = function(statements, inverse) {
574
+ this.type = "program";
575
+ this.statements = statements;
576
+ if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
577
+ };
578
+
579
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
580
+ this.type = "mustache";
581
+ this.id = params[0];
582
+ this.params = params.slice(1);
583
+ this.hash = hash;
584
+ this.escaped = !unescaped;
585
+ };
586
+
587
+ Handlebars.AST.PartialNode = function(id, context) {
588
+ this.type = "partial";
589
+
590
+ // TODO: disallow complex IDs
591
+
592
+ this.id = id;
593
+ this.context = context;
594
+ };
595
+
596
+ var verifyMatch = function(open, close) {
597
+ if(open.original !== close.original) {
598
+ throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
599
+ }
600
+ };
601
+
602
+ Handlebars.AST.BlockNode = function(mustache, program, close) {
603
+ verifyMatch(mustache.id, close);
604
+ this.type = "block";
605
+ this.mustache = mustache;
606
+ this.program = program;
607
+ };
608
+
609
+ Handlebars.AST.InverseNode = function(mustache, program, close) {
610
+ verifyMatch(mustache.id, close);
611
+ this.type = "inverse";
612
+ this.mustache = mustache;
613
+ this.program = program;
614
+ };
615
+
616
+ Handlebars.AST.ContentNode = function(string) {
617
+ this.type = "content";
618
+ this.string = string;
619
+ };
620
+
621
+ Handlebars.AST.HashNode = function(pairs) {
622
+ this.type = "hash";
623
+ this.pairs = pairs;
624
+ };
625
+
626
+ Handlebars.AST.IdNode = function(parts) {
627
+ this.type = "ID";
628
+ this.original = parts.join("/");
629
+
630
+ var dig = [], depth = 0;
631
+
632
+ for(var i=0,l=parts.length; i<l; i++) {
633
+ var part = parts[i];
634
+
635
+ if(part === "..") { depth++; }
636
+ else if(part === "." || part === "this") { continue; }
637
+ else { dig.push(part); }
638
+ }
639
+
640
+ this.parts = dig;
641
+ this.depth = depth;
642
+ this.isSimple = (dig.length === 1) && (depth === 0);
643
+ };
644
+
645
+ Handlebars.AST.StringNode = function(string) {
646
+ this.type = "STRING";
647
+ this.string = string;
648
+ };
649
+
650
+ Handlebars.AST.CommentNode = function(comment) {
651
+ this.type = "comment";
652
+ this.comment = comment;
653
+ };
654
+
655
+ })();;
656
+ // lib/handlebars/visitor.js
657
+
658
+ Handlebars.Visitor = function() {};
659
+
660
+ Handlebars.Visitor.prototype = {
661
+ accept: function(object) {
662
+ return this[object.type](object);
663
+ }
664
+ };;
665
+ // lib/handlebars/utils.js
666
+ Handlebars.Exception = function(message) {
667
+ this.message = message;
668
+ };
669
+
670
+ // Build out our basic SafeString type
671
+ Handlebars.SafeString = function(string) {
672
+ this.string = string;
673
+ };
674
+ Handlebars.SafeString.prototype.toString = function() {
675
+ return this.string.toString();
676
+ };
677
+
678
+ (function() {
679
+ var escape = {
680
+ "<": "&lt;",
681
+ ">": "&gt;"
682
+ };
683
+
684
+ var badChars = /&(?!\w+;)|[<>]/g;
685
+ var possible = /[&<>]/
686
+
687
+ var escapeChar = function(chr) {
688
+ return escape[chr] || "&amp;"
689
+ };
690
+
691
+ Handlebars.Utils = {
692
+ escapeExpression: function(string) {
693
+ // don't escape SafeStrings, since they're already safe
694
+ if (string instanceof Handlebars.SafeString) {
695
+ return string.toString();
696
+ } else if (string == null || string === false) {
697
+ return "";
698
+ }
699
+
700
+ if(!possible.test(string)) { return string; }
701
+ return string.replace(badChars, escapeChar);
702
+ },
703
+
704
+ isEmpty: function(value) {
705
+ if (typeof value === "undefined") {
706
+ return true;
707
+ } else if (value === null) {
708
+ return true;
709
+ } else if (value === false) {
710
+ return true;
711
+ } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
712
+ return true;
713
+ } else {
714
+ return false;
715
+ }
716
+ }
717
+ };
718
+ })();;
719
+ // lib/handlebars/vm.js
720
+ Handlebars.Compiler = function() {};
721
+ Handlebars.JavaScriptCompiler = function() {};
722
+
723
+ (function(Compiler, JavaScriptCompiler) {
724
+ Compiler.OPCODE_MAP = {
725
+ appendContent: 1,
726
+ getContext: 2,
727
+ lookupWithHelpers: 3,
728
+ lookup: 4,
729
+ append: 5,
730
+ invokeMustache: 6,
731
+ appendEscaped: 7,
732
+ pushString: 8,
733
+ truthyOrFallback: 9,
734
+ functionOrFallback: 10,
735
+ invokeProgram: 11,
736
+ invokePartial: 12,
737
+ push: 13,
738
+ invokeInverse: 14,
739
+ assignToHash: 15
740
+ };
741
+
742
+ Compiler.MULTI_PARAM_OPCODES = {
743
+ appendContent: 1,
744
+ getContext: 1,
745
+ lookupWithHelpers: 1,
746
+ lookup: 1,
747
+ invokeMustache: 2,
748
+ pushString: 1,
749
+ truthyOrFallback: 1,
750
+ functionOrFallback: 1,
751
+ invokeProgram: 2,
752
+ invokePartial: 1,
753
+ push: 1,
754
+ invokeInverse: 1,
755
+ assignToHash: 1
756
+ };
757
+
758
+ Compiler.DISASSEMBLE_MAP = {};
759
+
760
+ for(var prop in Compiler.OPCODE_MAP) {
761
+ var value = Compiler.OPCODE_MAP[prop];
762
+ Compiler.DISASSEMBLE_MAP[value] = prop;
763
+ }
764
+
765
+ Compiler.multiParamSize = function(code) {
766
+ return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
767
+ };
768
+
769
+ Compiler.prototype = {
770
+ disassemble: function() {
771
+ var opcodes = this.opcodes, opcode, nextCode;
772
+ var out = [], str, name, value;
773
+
774
+ for(var i=0, l=opcodes.length; i<l; i++) {
775
+ opcode = opcodes[i];
776
+
777
+ if(opcode === 'DECLARE') {
778
+ name = opcodes[++i];
779
+ value = opcodes[++i];
780
+ out.push("DECLARE " + name + " = " + value);
781
+ } else {
782
+ str = Compiler.DISASSEMBLE_MAP[opcode];
783
+
784
+ var extraParams = Compiler.multiParamSize(opcode);
785
+ var codes = [];
786
+
787
+ for(var j=0; j<extraParams; j++) {
788
+ nextCode = opcodes[++i];
789
+
790
+ if(typeof nextCode === "string") {
791
+ nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
792
+ }
793
+
794
+ codes.push(nextCode);
795
+ }
796
+
797
+ str = str + " " + codes.join(" ");
798
+
799
+ out.push(str);
800
+ }
801
+ }
802
+
803
+ return out.join("\n");
804
+ },
805
+
806
+ guid: 0,
807
+
808
+ compile: function(program) {
809
+ this.children = [];
810
+ this.depths = {list: []};
811
+ return this.program(program);
812
+ },
813
+
814
+ accept: function(node) {
815
+ return this[node.type](node);
816
+ },
817
+
818
+ program: function(program) {
819
+ var statements = program.statements, statement;
820
+ this.opcodes = [];
821
+
822
+ for(var i=0, l=statements.length; i<l; i++) {
823
+ statement = statements[i];
824
+ this[statement.type](statement);
825
+ }
826
+
827
+ this.depths.list = this.depths.list.sort(function(a, b) {
828
+ return a - b;
829
+ });
830
+
831
+ return this;
832
+ },
833
+
834
+ compileProgram: function(program) {
835
+ var result = new Compiler().compile(program);
836
+ var guid = this.guid++;
837
+
838
+ this.usePartial = this.usePartial || result.usePartial;
839
+
840
+ this.children[guid] = result;
841
+
842
+ for(var i=0, l=result.depths.list.length; i<l; i++) {
843
+ depth = result.depths.list[i];
844
+
845
+ if(depth < 2) { continue; }
846
+ else { this.addDepth(depth - 1); }
847
+ }
848
+
849
+ return guid;
850
+ },
851
+
852
+ block: function(block) {
853
+ var mustache = block.mustache;
854
+ var depth, child, inverse, inverseGuid;
855
+
856
+ var params = this.setupStackForMustache(mustache);
857
+
858
+ var programGuid = this.compileProgram(block.program);
859
+
860
+ if(block.program.inverse) {
861
+ inverseGuid = this.compileProgram(block.program.inverse);
862
+ this.declare('inverse', inverseGuid);
863
+ }
864
+
865
+ this.opcode('invokeProgram', programGuid, params.length);
866
+ this.declare('inverse', null);
867
+ this.opcode('append');
868
+ },
869
+
870
+ inverse: function(block) {
871
+ this.ID(block.mustache.id);
872
+ var programGuid = this.compileProgram(block.program);
873
+
874
+ this.opcode('invokeInverse', programGuid);
875
+ this.opcode('append');
876
+ },
877
+
878
+ hash: function(hash) {
879
+ var pairs = hash.pairs, pair, val;
880
+
881
+ this.opcode('push', '{}');
882
+
883
+ for(var i=0, l=pairs.length; i<l; i++) {
884
+ pair = pairs[i];
885
+ val = pair[1];
886
+
887
+ this.accept(val);
888
+ this.opcode('assignToHash', pair[0]);
889
+ }
890
+ },
891
+
892
+ partial: function(partial) {
893
+ var id = partial.id;
894
+ this.usePartial = true;
895
+
896
+ if(partial.context) {
897
+ this.ID(partial.context);
898
+ } else {
899
+ this.opcode('push', 'context');
900
+ }
901
+
902
+ this.opcode('invokePartial', id.original);
903
+ this.opcode('append');
904
+ },
905
+
906
+ content: function(content) {
907
+ this.opcode('appendContent', content.string);
908
+ },
909
+
910
+ mustache: function(mustache) {
911
+ var params = this.setupStackForMustache(mustache);
912
+
913
+ this.opcode('invokeMustache', params.length, mustache.id.original);
914
+
915
+ if(mustache.escaped) {
916
+ this.opcode('appendEscaped');
917
+ } else {
918
+ this.opcode('append');
919
+ }
920
+ },
921
+
922
+ ID: function(id) {
923
+ this.addDepth(id.depth);
924
+
925
+ this.opcode('getContext', id.depth);
926
+
927
+ this.opcode('lookupWithHelpers', id.parts[0] || null);
928
+
929
+ for(var i=1, l=id.parts.length; i<l; i++) {
930
+ this.opcode('lookup', id.parts[i]);
931
+ }
932
+ },
933
+
934
+ STRING: function(string) {
935
+ this.opcode('pushString', string.string);
936
+ },
937
+
938
+ comment: function() {},
939
+
940
+ // HELPERS
941
+ pushParams: function(params) {
942
+ var i = params.length, param;
943
+
944
+ while(i--) {
945
+ param = params[i];
946
+ this[param.type](param);
947
+ }
948
+ },
949
+
950
+ opcode: function(name, val1, val2) {
951
+ this.opcodes.push(Compiler.OPCODE_MAP[name]);
952
+ if(val1 !== undefined) { this.opcodes.push(val1); }
953
+ if(val2 !== undefined) { this.opcodes.push(val2); }
954
+ },
955
+
956
+ declare: function(name, value) {
957
+ this.opcodes.push('DECLARE');
958
+ this.opcodes.push(name);
959
+ this.opcodes.push(value);
960
+ },
961
+
962
+ addDepth: function(depth) {
963
+ if(depth === 0) { return; }
964
+
965
+ if(!this.depths[depth]) {
966
+ this.depths[depth] = true;
967
+ this.depths.list.push(depth);
968
+ }
969
+ },
970
+
971
+ setupStackForMustache: function(mustache) {
972
+ var params = mustache.params;
973
+
974
+ this.pushParams(params);
975
+
976
+ if(mustache.hash) {
977
+ this.hash(mustache.hash);
978
+ } else {
979
+ this.opcode('push', '{}');
980
+ }
981
+
982
+ this.ID(mustache.id);
983
+
984
+ return params;
985
+ }
986
+ };
987
+
988
+ JavaScriptCompiler.prototype = {
989
+ // PUBLIC API: You can override these methods in a subclass to provide
990
+ // alternative compiled forms for name lookup and buffering semantics
991
+ nameLookup: function(parent, name, type) {
992
+ if(JavaScriptCompiler.RESERVED_WORDS[name]) {
993
+ return parent + "['" + name + "']";
994
+ } else {
995
+ return parent + "." + name;
996
+ }
997
+ },
998
+
999
+ appendToBuffer: function(string) {
1000
+ return "buffer = buffer + " + string + ";";
1001
+ },
1002
+
1003
+ initializeBuffer: function() {
1004
+ return this.quotedString("");
1005
+ },
1006
+ // END PUBLIC API
1007
+
1008
+ compile: function(environment, data) {
1009
+ this.environment = environment;
1010
+ this.data = data;
1011
+
1012
+ this.preamble();
1013
+
1014
+ this.stackSlot = 0;
1015
+ this.stackVars = [];
1016
+ this.registers = {list: []};
1017
+
1018
+ this.compileChildren(environment, data);
1019
+
1020
+ Handlebars.log(Handlebars.logger.DEBUG, environment.disassemble() + "\n\n");
1021
+
1022
+ var opcodes = environment.opcodes, opcode, name, declareName, declareVal;
1023
+
1024
+ this.i = 0;
1025
+
1026
+ for(l=opcodes.length; this.i<l; this.i++) {
1027
+ opcode = this.nextOpcode(0);
1028
+
1029
+ if(opcode[0] === 'DECLARE') {
1030
+ this.i = this.i + 2;
1031
+ this[opcode[1]] = opcode[2];
1032
+ } else {
1033
+ this.i = this.i + opcode[1].length;
1034
+ this[opcode[0]].apply(this, opcode[1]);
1035
+ }
1036
+ }
1037
+
1038
+ return this.createFunction();
1039
+ },
1040
+
1041
+ nextOpcode: function(n) {
1042
+ var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
1043
+ var extraParams, codes;
1044
+
1045
+ if(opcode === 'DECLARE') {
1046
+ name = opcodes[this.i + 1];
1047
+ val = opcodes[this.i + 2];
1048
+ return ['DECLARE', name, val];
1049
+ } else {
1050
+ name = Compiler.DISASSEMBLE_MAP[opcode];
1051
+
1052
+ extraParams = Compiler.multiParamSize(opcode);
1053
+ codes = [];
1054
+
1055
+ for(var j=0; j<extraParams; j++) {
1056
+ codes.push(opcodes[this.i + j + 1 + n]);
1057
+ }
1058
+
1059
+ return [name, codes];
1060
+ }
1061
+ },
1062
+
1063
+ eat: function(opcode) {
1064
+ this.i = this.i + opcode.length;
1065
+ },
1066
+
1067
+ preamble: function() {
1068
+ var out = [];
1069
+ out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context");
1070
+
1071
+ var copies = "helpers = helpers || Handlebars.helpers;";
1072
+ if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
1073
+ out.push(copies);
1074
+
1075
+ // track the last context pushed into place to allow skipping the
1076
+ // getContext opcode when it would be a noop
1077
+ this.lastContext = 0;
1078
+ this.source = out;
1079
+ },
1080
+
1081
+ createFunction: function() {
1082
+ var container = {
1083
+ escapeExpression: Handlebars.Utils.escapeExpression,
1084
+ invokePartial: Handlebars.VM.invokePartial,
1085
+ programs: [],
1086
+ program: function(i, helpers, partials, data) {
1087
+ var programWrapper = this.programs[i];
1088
+ if(data) {
1089
+ return Handlebars.VM.program(this.children[i], helpers, partials, data);
1090
+ } else if(programWrapper) {
1091
+ return programWrapper;
1092
+ } else {
1093
+ programWrapper = this.programs[i] = Handlebars.VM.program(this.children[i], helpers, partials);
1094
+ return programWrapper;
1095
+ }
1096
+ },
1097
+ programWithDepth: Handlebars.VM.programWithDepth,
1098
+ noop: Handlebars.VM.noop
1099
+ };
1100
+ var locals = this.stackVars.concat(this.registers.list);
1101
+
1102
+ if(locals.length > 0) {
1103
+ this.source[0] = this.source[0] + ", " + locals.join(", ");
1104
+ }
1105
+
1106
+ this.source[0] = this.source[0] + ";";
1107
+
1108
+ this.source.push("return buffer;");
1109
+
1110
+ var params = ["Handlebars", "context", "helpers", "partials"];
1111
+
1112
+ if(this.data) { params.push("data"); }
1113
+
1114
+ for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1115
+ params.push("depth" + this.environment.depths.list[i]);
1116
+ }
1117
+
1118
+
1119
+ if(params.length === 4 && !this.environment.usePartial) { params.pop(); }
1120
+
1121
+ params.push(this.source.join("\n"));
1122
+
1123
+ var fn = Function.apply(this, params);
1124
+ fn.displayName = "Handlebars.js";
1125
+
1126
+ Handlebars.log(Handlebars.logger.DEBUG, fn.toString() + "\n\n");
1127
+
1128
+ container.render = fn;
1129
+
1130
+ container.children = this.environment.children;
1131
+
1132
+ return function(context, helpers, partials, data, $depth) {
1133
+ try {
1134
+ var args = Array.prototype.slice.call(arguments);
1135
+ args.unshift(Handlebars);
1136
+ return container.render.apply(container, args);
1137
+ } catch(e) {
1138
+ throw e;
1139
+ }
1140
+ };
1141
+ },
1142
+
1143
+ appendContent: function(content) {
1144
+ this.source.push(this.appendToBuffer(this.quotedString(content)));
1145
+ },
1146
+
1147
+ append: function() {
1148
+ var local = this.popStack();
1149
+ this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1150
+ },
1151
+
1152
+ appendEscaped: function() {
1153
+ var opcode = this.nextOpcode(1), extra = "";
1154
+
1155
+ if(opcode[0] === 'appendContent') {
1156
+ extra = " + " + this.quotedString(opcode[1][0]);
1157
+ this.eat(opcode);
1158
+ }
1159
+
1160
+ this.source.push(this.appendToBuffer("this.escapeExpression(" + this.popStack() + ")" + extra));
1161
+ },
1162
+
1163
+ getContext: function(depth) {
1164
+ if(this.lastContext !== depth) {
1165
+ this.lastContext = depth;
1166
+
1167
+ if(depth === 0) {
1168
+ this.source.push("currentContext = context;");
1169
+ } else {
1170
+ this.source.push("currentContext = depth" + depth + ";");
1171
+ }
1172
+ }
1173
+ },
1174
+
1175
+ lookupWithHelpers: function(name) {
1176
+ if(name) {
1177
+ var topStack = this.nextStack();
1178
+
1179
+ var toPush = "if('" + name + "' in helpers) { " + topStack +
1180
+ " = " + this.nameLookup('helpers', name, 'helper') +
1181
+ "; } else { " + topStack + " = " +
1182
+ this.nameLookup('currentContext', name, 'context') +
1183
+ "; }";
1184
+
1185
+ this.source.push(toPush);
1186
+ } else {
1187
+ this.pushStack("currentContext");
1188
+ }
1189
+ },
1190
+
1191
+ lookup: function(name) {
1192
+ var topStack = this.topStack();
1193
+ this.source.push(topStack + " = " + this.nameLookup(topStack, name, 'context') + ";");
1194
+ },
1195
+
1196
+ pushString: function(string) {
1197
+ this.pushStack(this.quotedString(string));
1198
+ },
1199
+
1200
+ push: function(name) {
1201
+ this.pushStack(name);
1202
+ },
1203
+
1204
+ invokeMustache: function(paramSize, original) {
1205
+ this.populateParams(paramSize, this.quotedString(original), "{}", null, function(nextStack, helperMissingString, id) {
1206
+ this.source.push("else if(" + id + "=== undefined) { " + nextStack + " = helpers.helperMissing.call(" + helperMissingString + "); }");
1207
+ this.source.push("else { " + nextStack + " = " + id + "; }");
1208
+ });
1209
+ },
1210
+
1211
+ invokeProgram: function(guid, paramSize) {
1212
+ var inverse = this.programExpression(this.inverse);
1213
+ var mainProgram = this.programExpression(guid);
1214
+
1215
+ this.populateParams(paramSize, null, mainProgram, inverse, function(nextStack, helperMissingString, id) {
1216
+ this.source.push("else { " + nextStack + " = helpers.blockHelperMissing.call(" + helperMissingString + "); }");
1217
+ });
1218
+ },
1219
+
1220
+ populateParams: function(paramSize, helperId, program, inverse, fn) {
1221
+ var id = this.popStack(), nextStack;
1222
+ var params = [];
1223
+
1224
+ var hash = this.popStack();
1225
+
1226
+ for(var i=0; i<paramSize; i++) {
1227
+ var param = this.popStack();
1228
+ params.push(param);
1229
+ }
1230
+
1231
+ this.register('tmp1', program);
1232
+ this.source.push('tmp1.hash = ' + hash + ';');
1233
+
1234
+ if(inverse) {
1235
+ this.source.push('tmp1.fn = tmp1;');
1236
+ this.source.push('tmp1.inverse = ' + inverse + ';');
1237
+ }
1238
+
1239
+ if(this.data) {
1240
+ this.source.push('tmp1.data = data;');
1241
+ }
1242
+
1243
+ params.push('tmp1');
1244
+
1245
+ // TODO: This is legacy behavior. Deprecate and remove.
1246
+ if(inverse) {
1247
+ params.push(inverse);
1248
+ }
1249
+
1250
+ this.populateCall(params, id, helperId || id, fn);
1251
+ },
1252
+
1253
+ populateCall: function(params, id, helperId, fn) {
1254
+ var paramString = ["context"].concat(params).join(", ");
1255
+ var helperMissingString = ["context"].concat(helperId).concat(params).join(", ");
1256
+
1257
+ nextStack = this.nextStack();
1258
+
1259
+ this.source.push("if(typeof " + id + " === 'function') { " + nextStack + " = " + id + ".call(" + paramString + "); }");
1260
+ fn.call(this, nextStack, helperMissingString, id);
1261
+ },
1262
+
1263
+ invokeInverse: function(guid) {
1264
+ var program = this.programExpression(guid);
1265
+
1266
+ var blockMissingParams = ["context", this.topStack(), "this.noop", program];
1267
+ this.pushStack("helpers.blockHelperMissing.call(" + blockMissingParams.join(", ") + ")");
1268
+ },
1269
+
1270
+ invokePartial: function(context) {
1271
+ this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
1272
+ },
1273
+
1274
+ assignToHash: function(key) {
1275
+ var value = this.popStack();
1276
+ var hash = this.topStack();
1277
+
1278
+ this.source.push(hash + "['" + key + "'] = " + value + ";");
1279
+ },
1280
+
1281
+ // HELPERS
1282
+
1283
+ compiler: JavaScriptCompiler,
1284
+
1285
+ compileChildren: function(environment, data) {
1286
+ var children = environment.children, child, compiler;
1287
+ var compiled = [];
1288
+
1289
+ for(var i=0, l=children.length; i<l; i++) {
1290
+ child = children[i];
1291
+ compiler = new this.compiler();
1292
+
1293
+ compiled[i] = compiler.compile(child, data);
1294
+ }
1295
+
1296
+ environment.rawChildren = children;
1297
+ environment.children = compiled;
1298
+ },
1299
+
1300
+ programExpression: function(guid) {
1301
+ if(guid == null) { return "this.noop"; }
1302
+
1303
+ var programParams = [guid, "helpers", "partials"];
1304
+
1305
+ var depths = this.environment.rawChildren[guid].depths.list;
1306
+
1307
+ if(this.data) { programParams.push("data"); }
1308
+
1309
+ for(var i=0, l = depths.length; i<l; i++) {
1310
+ depth = depths[i];
1311
+
1312
+ if(depth === 1) { programParams.push("context"); }
1313
+ else { programParams.push("depth" + (depth - 1)); }
1314
+ }
1315
+
1316
+ if(!this.environment.usePartial) {
1317
+ if(programParams[3]) {
1318
+ programParams[2] = "null";
1319
+ } else {
1320
+ programParams.pop();
1321
+ }
1322
+ }
1323
+
1324
+ if(depths.length === 0) {
1325
+ return "this.program(" + programParams.join(", ") + ")";
1326
+ } else {
1327
+ programParams[0] = "this.children[" + guid + "]";
1328
+ return "this.programWithDepth(" + programParams.join(", ") + ")";
1329
+ }
1330
+ },
1331
+
1332
+ register: function(name, val) {
1333
+ this.useRegister(name);
1334
+ this.source.push(name + " = " + val + ";");
1335
+ },
1336
+
1337
+ useRegister: function(name) {
1338
+ if(!this.registers[name]) {
1339
+ this.registers[name] = true;
1340
+ this.registers.list.push(name);
1341
+ }
1342
+ },
1343
+
1344
+ pushStack: function(item) {
1345
+ this.source.push(this.nextStack() + " = " + item + ";");
1346
+ return "stack" + this.stackSlot;
1347
+ },
1348
+
1349
+ nextStack: function() {
1350
+ this.stackSlot++;
1351
+ if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1352
+ return "stack" + this.stackSlot;
1353
+ },
1354
+
1355
+ popStack: function() {
1356
+ return "stack" + this.stackSlot--;
1357
+ },
1358
+
1359
+ topStack: function() {
1360
+ return "stack" + this.stackSlot;
1361
+ },
1362
+
1363
+ quotedString: function(str) {
1364
+ return '"' + str
1365
+ .replace(/\\/, '\\\\')
1366
+ .replace(/"/g, '\\"')
1367
+ .replace(/\n/g, '\\n')
1368
+ .replace(/\r/g, '\\r') + '"';
1369
+ }
1370
+ };
1371
+
1372
+ var reservedWords = ("break case catch continue default delete do else finally " +
1373
+ "for function if in instanceof new return switch this throw " +
1374
+ "try typeof var void while with null true false").split(" ");
1375
+
1376
+ compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
1377
+
1378
+ for(var i=0, l=reservedWords.length; i<l; i++) {
1379
+ compilerWords[reservedWords[i]] = true;
1380
+ }
1381
+
1382
+ })(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
1383
+
1384
+ Handlebars.VM = {
1385
+ programWithDepth: function(fn) {
1386
+ var args = Array.prototype.slice.call(arguments, 1);
1387
+ return function(context, helpers, partials, data) {
1388
+ args[0] = helpers || args[0];
1389
+ args[1] = partials || args[1];
1390
+ args[2] = data || args[2];
1391
+ return fn.apply(this, [context].concat(args));
1392
+ };
1393
+ },
1394
+ program: function(fn, helpers, partials, data) {
1395
+ return function(context, h2, p2, d2) {
1396
+ return fn(context, h2 || helpers, p2 || partials, d2 || data);
1397
+ };
1398
+ },
1399
+ noop: function() { return ""; },
1400
+ compile: function(string, data) {
1401
+ var ast = Handlebars.parse(string);
1402
+ var environment = new Handlebars.Compiler().compile(ast);
1403
+ return new Handlebars.JavaScriptCompiler().compile(environment, data);
1404
+ },
1405
+ invokePartial: function(partial, name, context, helpers, partials) {
1406
+ if(partial === undefined) {
1407
+ throw new Handlebars.Exception("The partial " + name + " could not be found");
1408
+ } else if(partial instanceof Function) {
1409
+ return partial(context, helpers, partials);
1410
+ } else {
1411
+ partials[name] = Handlebars.VM.compile(partial);
1412
+ return partials[name](context, helpers, partials);
1413
+ }
1414
+ }
1415
+ };
1416
+
1417
+ Handlebars.compile = Handlebars.VM.compile;;