summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/handlebars/ast.js2
-rw-r--r--lib/handlebars/compiler.js19
-rw-r--r--spec/qunit_spec.js44
3 files changed, 58 insertions, 7 deletions
diff --git a/lib/handlebars/ast.js b/lib/handlebars/ast.js
index d7cc150..6c3711b 100644
--- a/lib/handlebars/ast.js
+++ b/lib/handlebars/ast.js
@@ -68,7 +68,7 @@ var Handlebars = require("handlebars");
var part = parts[i];
if(part === "..") { depth++; }
- else if(part === "." || part === "this") { continue; }
+ else if(part === "." || part === "this") { this.isScoped = true; }
else { dig.push(part); }
}
diff --git a/lib/handlebars/compiler.js b/lib/handlebars/compiler.js
index b8a9e04..843e0b9 100644
--- a/lib/handlebars/compiler.js
+++ b/lib/handlebars/compiler.js
@@ -26,7 +26,7 @@ Handlebars.JavaScriptCompiler = function() {};
Compiler.MULTI_PARAM_OPCODES = {
appendContent: 1,
getContext: 1,
- lookupWithHelpers: 1,
+ lookupWithHelpers: 2,
lookup: 1,
invokeMustache: 2,
pushString: 1,
@@ -214,7 +214,7 @@ Handlebars.JavaScriptCompiler = function() {};
this.opcode('getContext', id.depth);
- this.opcode('lookupWithHelpers', id.parts[0] || null);
+ this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);
for(var i=1, l=id.parts.length; i<l; i++) {
this.opcode('lookup', id.parts[i]);
@@ -479,15 +479,22 @@ Handlebars.JavaScriptCompiler = function() {};
}
},
- lookupWithHelpers: function(name) {
+ lookupWithHelpers: function(name, isScoped) {
if(name) {
var topStack = this.nextStack();
- var toPush = "if('" + name + "' in helpers) { " + topStack +
+ var lookupScoped = topStack + " = " + this.nameLookup('currentContext', name, 'context'),
+ toPush;
+
+ if (isScoped) {
+ toPush = lookupScoped;
+ } else {
+ toPush = "if('" + name + "' in helpers) { " + topStack +
" = " + this.nameLookup('helpers', name, 'helper') +
- "; } else { " + topStack + " = " +
- this.nameLookup('currentContext', name, 'context') +
+ "; } else { " +
+ lookupScoped +
"; }";
+ }
this.source.push(toPush);
} else {
diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js
index bdec68b..3b08bc5 100644
--- a/spec/qunit_spec.js
+++ b/spec/qunit_spec.js
@@ -683,6 +683,50 @@ test("helpers take precedence over same-named context properties", function() {
equals(result, "GOODBYE cruel WORLD", "Helper executed");
});
+test("Scoped names take precedence over helpers", function() {
+ var template = Handlebars.compile("{{this.goodbye}} {{cruel world}} {{cruel this.goodbye}}");
+
+ 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: helpers});
+ equals(result, "goodbye cruel WORLD cruel GOODBYE", "Helper not executed");
+});
+
+test("Scoped names take precedence over block helpers", function() {
+ var template = Handlebars.compile("{{#goodbye}} {{cruel world}}{{/goodbye}} {{this.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: helpers});
+ equals(result, "GOODBYE cruel WORLD goodbye", "Helper executed");
+});
+
test("helpers can take an optional hash", function() {
var template = Handlebars.compile('{{goodbye cruel="CRUEL" world="WORLD" times=12}}');