summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-01-04 11:05:57 -0600
committerkpdecker <kpdecker@gmail.com>2014-01-06 16:07:56 -0600
commit0f328f375e9682642676d6c58d1cf307a63155f0 (patch)
treec597a39674570bf9e38e9cf035ece2f8c0fed39f /lib
parentc73aceb3d3415e9847fa0680f42bf80d5a652bac (diff)
downloadhandlebars.js-0f328f375e9682642676d6c58d1cf307a63155f0.zip
handlebars.js-0f328f375e9682642676d6c58d1cf307a63155f0.tar.gz
handlebars.js-0f328f375e9682642676d6c58d1cf307a63155f0.tar.bz2
Include name option for all helper calls
All helper calls will have access to `options.name` which is the first id value of the mustache operation. As part of this the helperMissing call has been simplified to remove the indexed name in order to optimize the call. This is a breaking change. Fixes #634
Diffstat (limited to 'lib')
-rw-r--r--lib/handlebars/base.js8
-rw-r--r--lib/handlebars/compiler/compiler.js2
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js26
3 files changed, 17 insertions, 19 deletions
diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js
index 00c8bf1..059b1c3 100644
--- a/lib/handlebars/base.js
+++ b/lib/handlebars/base.js
@@ -49,11 +49,13 @@ HandlebarsEnvironment.prototype = {
};
function registerDefaultHelpers(instance) {
- instance.registerHelper('helperMissing', function(arg) {
- if(arguments.length === 2) {
+ instance.registerHelper('helperMissing', function(/* [args, ]options */) {
+ if(arguments.length === 1) {
+ // A missing field in a {{foo}} constuct.
return undefined;
} else {
- throw new Exception("Missing helper: '" + arg + "'");
+ // Someone is actually trying to call something, blow up.
+ throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
}
});
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index b428c5f..3c4a9b7 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -170,7 +170,7 @@ Compiler.prototype = {
this.opcode('pushProgram', program);
this.opcode('pushProgram', inverse);
this.opcode('emptyHash');
- this.opcode('blockValue');
+ this.opcode('blockValue', sexpr.id.original);
} else {
this.ambiguousSexpr(sexpr, program, inverse);
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 2136724..809322f 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -224,11 +224,11 @@ JavaScriptCompiler.prototype = {
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
// replace it on the stack with the result of properly
// invoking blockHelperMissing.
- blockValue: function() {
+ blockValue: function(name) {
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
var params = ["depth0"];
- this.setupParams(0, params);
+ this.setupParams(name, 0, params);
this.replaceStack(function(current) {
params.splice(1, 0, current);
@@ -247,7 +247,7 @@ JavaScriptCompiler.prototype = {
// We're being a bit cheeky and reusing the options value from the prior exec
var params = ["depth0"];
- this.setupParams(0, params, true);
+ this.setupParams('', 0, params, true);
this.flushInline();
@@ -504,20 +504,15 @@ JavaScriptCompiler.prototype = {
this.context.aliases.helperMissing = 'helpers.helperMissing';
this.useRegister('helper');
- var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
+ var helper = this.lastHelper = this.setupHelper(paramSize, name);
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
- var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
+ var lookup = 'helper = ' + helper.name + ' || ' + nonHelper + ' || helperMissing';
if (helper.paramsInit) {
lookup += ',' + helper.paramsInit;
}
- this.push(
- '('
- + lookup
- + ',helper '
- + '? helper.call(' + helper.callParams + ') '
- + ': helperMissing.call(' + helper.helperMissingParams + '))');
+ this.push('(' + lookup + ',helper.call(' + helper.callParams + '))');
// Always flush subexpressions. This is both to prevent the compounding size issue that
// occurs when the code has to be duplicated for inlining and also to prevent errors
@@ -826,7 +821,7 @@ JavaScriptCompiler.prototype = {
setupHelper: function(paramSize, name, missingParams) {
var params = [],
- paramsInit = this.setupParams(paramSize, params, missingParams);
+ paramsInit = this.setupParams(name, paramSize, params, missingParams);
var foundHelper = this.nameLookup('helpers', name, 'helper');
return {
@@ -838,9 +833,10 @@ JavaScriptCompiler.prototype = {
};
},
- setupOptions: function(paramSize, params) {
+ setupOptions: function(helper, paramSize, params) {
var options = [], contexts = [], types = [], param, inverse, program;
+ options.push("name:" + this.quotedString(helper));
options.push("hash:" + this.popStack());
if (this.stringParams) {
@@ -892,8 +888,8 @@ JavaScriptCompiler.prototype = {
// the params and contexts arguments are passed in arrays
// to fill in
- setupParams: function(paramSize, params, useRegister) {
- var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
+ setupParams: function(helperName, paramSize, params, useRegister) {
+ var options = '{' + this.setupOptions(helperName, paramSize, params).join(',') + '}';
if (useRegister) {
this.useRegister('options');