Merge branch 'master' of http://github.com/wycats/handlebars.js
This commit is contained in:
+19
-10
@@ -8,7 +8,7 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
Compiler.OPCODE_MAP = {
|
||||
appendContent: 1,
|
||||
getContext: 2,
|
||||
lookupWithFallback: 3,
|
||||
lookupWithHelpers: 3,
|
||||
lookup: 4,
|
||||
append: 5,
|
||||
invokeMustache: 6,
|
||||
@@ -25,7 +25,7 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
Compiler.MULTI_PARAM_OPCODES = {
|
||||
appendContent: 1,
|
||||
getContext: 1,
|
||||
lookupWithFallback: 1,
|
||||
lookupWithHelpers: 1,
|
||||
lookup: 1,
|
||||
invokeMustache: 2,
|
||||
pushString: 1,
|
||||
@@ -201,7 +201,7 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
|
||||
this.opcode('getContext', id.depth);
|
||||
|
||||
this.opcode('lookupWithFallback', id.parts[0] || null);
|
||||
this.opcode('lookupWithHelpers', id.parts[0] || null);
|
||||
|
||||
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||
this.opcode('lookup', id.parts[i]);
|
||||
@@ -432,11 +432,17 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
}
|
||||
},
|
||||
|
||||
lookupWithFallback: function(name) {
|
||||
lookupWithHelpers: function(name) {
|
||||
if(name) {
|
||||
this.pushStack(this.nameLookup('currentContext', name, 'context'));
|
||||
var topStack = this.topStack();
|
||||
this.source.push("if(" + topStack + " === undefined) { " + topStack + " = " + this.nameLookup('helpers', name, 'helper') + "; }");
|
||||
var topStack = this.nextStack();
|
||||
|
||||
var toPush = "if('" + name + "' in helpers) { " + topStack +
|
||||
" = " + this.nameLookup('helpers', name, 'helper') +
|
||||
"; } else { " + topStack + " = " +
|
||||
this.nameLookup('currentContext', name, 'context') +
|
||||
"; }";
|
||||
|
||||
this.source.push(toPush);
|
||||
} else {
|
||||
this.pushStack("currentContext");
|
||||
}
|
||||
@@ -627,13 +633,16 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
Handlebars.VM = {
|
||||
programWithDepth: function(fn) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return function(context) {
|
||||
return function(context, helpers, partials, data) {
|
||||
args[0] = helpers || args[0];
|
||||
args[1] = partials || args[1];
|
||||
args[2] = data || args[2];
|
||||
return fn.apply(this, [context].concat(args));
|
||||
};
|
||||
},
|
||||
program: function(fn, helpers, partials, data) {
|
||||
return function(context) {
|
||||
return fn(context, helpers, partials, data);
|
||||
return function(context, h2, p2, d2) {
|
||||
return fn(context, h2 || helpers, p2 || partials, d2 || data);
|
||||
};
|
||||
},
|
||||
noop: function() { return ""; },
|
||||
|
||||
@@ -600,5 +600,80 @@ test("passing in data to a compiled function that expects data - works with bloc
|
||||
equals("#win happy world?", result);
|
||||
});
|
||||
|
||||
test("you can override inherited data when invoking a helper", function() {
|
||||
var template = Handlebars.compile("{{#hello}}{{world zomg}}{{/hello}}", true);
|
||||
|
||||
var helpers = {
|
||||
hello: function(fn) {
|
||||
return fn({exclaim: "?", zomg: "world"}, null, null, {adjective: "sad"});
|
||||
},
|
||||
world: function(thing, data) {
|
||||
return data.adjective + " " + thing + (this.exclaim || "");
|
||||
}
|
||||
};
|
||||
|
||||
var result = template({exclaim: true, zomg: "planet"}, helpers, null, {adjective: "happy"});
|
||||
equals("sad world?", result);
|
||||
});
|
||||
|
||||
|
||||
test("you can override inherited data when invoking a helper with depth", function() {
|
||||
var template = Handlebars.compile("{{#hello}}{{world ../zomg}}{{/hello}}", true);
|
||||
|
||||
var helpers = {
|
||||
hello: function(fn) {
|
||||
return fn({exclaim: "?"}, null, null, {adjective: "sad"});
|
||||
},
|
||||
world: function(thing, data) {
|
||||
return data.adjective + " " + thing + (this.exclaim || "");
|
||||
}
|
||||
};
|
||||
|
||||
var result = template({exclaim: true, zomg: "world"}, helpers, null, {adjective: "happy"});
|
||||
equals("sad world?", result);
|
||||
});
|
||||
|
||||
test("helpers take precedence over same-named context properties", function() {
|
||||
var template = Handlebars.compile("{{goodbye}} {{cruel world}}");
|
||||
|
||||
var helpers = {
|
||||
goodbye: function() {
|
||||
return this.goodbye.toUpperCase();
|
||||
}
|
||||
};
|
||||
|
||||
var context = {
|
||||
cruel: function(world) {
|
||||
return "cruel " + world.toUpperCase();
|
||||
},
|
||||
|
||||
goodbye: "goodbye",
|
||||
world: "world"
|
||||
};
|
||||
|
||||
var result = template(context, helpers);
|
||||
equals(result, "GOODBYE cruel WORLD");
|
||||
});
|
||||
|
||||
test("helpers take precedence over same-named context properties", function() {
|
||||
var template = Handlebars.compile("{{#goodbye}} {{cruel world}}{{/goodbye}}");
|
||||
|
||||
var helpers = {
|
||||
goodbye: function(fn) {
|
||||
return this.goodbye.toUpperCase() + fn(this);
|
||||
}
|
||||
};
|
||||
|
||||
var context = {
|
||||
cruel: function(world) {
|
||||
return "cruel " + world.toUpperCase();
|
||||
},
|
||||
|
||||
goodbye: "goodbye",
|
||||
world: "world"
|
||||
};
|
||||
|
||||
var result = template(context, helpers);
|
||||
equals(result, "GOODBYE cruel WORLD");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user