Add Hash arguments to simple mustaches (TODO: add Hash args to block helpers)

This commit is contained in:
tomhuda
2011-03-04 00:11:03 -08:00
parent e0aa705f71
commit ca9b9671a5
6 changed files with 105 additions and 48 deletions
+2 -1
View File
@@ -11,10 +11,11 @@ var Handlebars = require("handlebars");
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
};
Handlebars.AST.MustacheNode = function(params, unescaped) {
Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
this.type = "mustache";
this.id = params[0];
this.params = params.slice(1);
this.hash = hash;
this.escaped = !unescaped;
};
+5 -2
View File
@@ -73,14 +73,17 @@ Handlebars.PrintVisitor.prototype.inverse = function(block) {
Handlebars.PrintVisitor.prototype.mustache = function(mustache) {
var params = mustache.params, paramStrings = [];
var params = mustache.params, paramStrings = [], hash;
for(var i=0, l=params.length; i<l; i++) {
paramStrings.push(this.accept(params[i]));
}
params = "[" + paramStrings.join(", ") + "]";
return this.pad("{{ " + this.accept(mustache.id) + " " + params + " }}");
hash = mustache.hash ? " " + this.accept(mustache.hash) : "";
return this.pad("{{ " + this.accept(mustache.id) + " " + params + hash + " }}");
};
Handlebars.PrintVisitor.prototype.partial = function(partial) {
+47 -6
View File
@@ -19,7 +19,8 @@ Handlebars.JavaScriptCompiler = function() {};
invokeProgram: 11,
invokePartial: 12,
push: 13,
invokeInverse: 14
invokeInverse: 14,
assignToHash: 15
};
Compiler.MULTI_PARAM_OPCODES = {
@@ -34,7 +35,8 @@ Handlebars.JavaScriptCompiler = function() {};
invokeProgram: 2,
invokePartial: 1,
push: 1,
invokeInverse: 1
invokeInverse: 1,
assignToHash: 1
};
Compiler.DISASSEMBLE_MAP = {};
@@ -163,6 +165,20 @@ Handlebars.JavaScriptCompiler = function() {};
this.opcode('append');
},
hash: function(hash) {
var pairs = hash.pairs, pair, val;
this.opcode('push', '{}');
for(var i=0, l=pairs.length; i<l; i++) {
pair = pairs[i];
val = pair[1];
this.accept(val);
this.opcode('assignToHash', pair[0]);
}
},
partial: function(partial) {
var id = partial.id;
this.usePartial = true;
@@ -185,6 +201,13 @@ Handlebars.JavaScriptCompiler = function() {};
var params = mustache.params;
this.pushParams(params);
if(mustache.hash) {
this.hash(mustache.hash);
} else {
this.opcode('push', '{}');
}
this.ID(mustache.id);
this.opcode('invokeMustache', params.length, mustache.id.original);
@@ -466,11 +489,19 @@ Handlebars.JavaScriptCompiler = function() {};
fn = this.popStack();
var hash = this.popStack();
for(var i=0; i<paramSize; i++) {
params.push(this.popStack());
}
if(this.data) { params.push("data"); }
this.register('tmp1', '{hash: ' + hash + '}');
if(this.data) {
this.source.push('tmp1.data = data');
}
params.push('tmp1');
var paramString = params.join(", ");
var helperMissing = ["context"].concat(this.quotedString(original)).concat(params.slice(1));
@@ -479,7 +510,7 @@ Handlebars.JavaScriptCompiler = function() {};
if(paramSize === 0) {
// TODO: This case is not listed in the mustache spec. Is it important?
this.source.push("if(typeof " + fn + " === 'function') { " + slot + " = " + fn + ".call(" + paramString + "); }");
this.source.push("if(typeof " + fn + " === 'function') { " + slot + " = " + fn + ".call(" + paramString + "); } else { " + slot + " = " + fn + "; }");
} else {
this.source.push("if(typeof " + fn + " === 'function') { " + slot + " = " + fn + ".call(" + paramString + "); } else { " + slot + " = helpers.helperMissing.call(" + helperMissing + ") }");
}
@@ -506,8 +537,11 @@ Handlebars.JavaScriptCompiler = function() {};
blockMissingParams.push(mainProgram, inverse);
if(this.data) {
params.push("data");
blockMissingParams.push("data");
this.register('tmp1', '{data: data}');
params.push("tmp1");
params.push("tmp1");
blockMissingParams.push("tmp1");
}
var nextStack = this.nextStack();
@@ -527,6 +561,13 @@ Handlebars.JavaScriptCompiler = function() {};
this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
},
assignToHash: function(key) {
var value = this.popStack();
var hash = this.topStack();
this.source.push(hash + "['" + key + "'] = " + value + ";");
},
// HELPERS
compiler: JavaScriptCompiler,