knownHandlers and knownHandlersOnly compile options.
This commit is contained in:
@@ -94,7 +94,24 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
compile: function(program, options) {
|
||||
this.children = [];
|
||||
this.depths = {list: []};
|
||||
this.options = options || {};
|
||||
this.options = options;
|
||||
|
||||
// These changes will propagate to the other compiler components
|
||||
var knownHelpers = this.options.knownHelpers;
|
||||
this.options.knownHelpers = {
|
||||
'helperMissing': true,
|
||||
'blockHelperMissing': true,
|
||||
'each': true,
|
||||
'if': true,
|
||||
'unless': true,
|
||||
'with': true
|
||||
};
|
||||
if (knownHelpers) {
|
||||
for (var name in knownHelpers) {
|
||||
this.options.knownHelpers[name] = knownHelpers[name];
|
||||
}
|
||||
}
|
||||
|
||||
return this.program(program);
|
||||
},
|
||||
|
||||
@@ -475,9 +492,13 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
if(name) {
|
||||
var topStack = this.nextStack();
|
||||
|
||||
var toPush;
|
||||
this.usingKnownHelper = false;
|
||||
|
||||
if (isScoped) {
|
||||
var toPush;
|
||||
if (!isScoped && this.options.knownHelpers[name]) {
|
||||
toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
|
||||
this.usingKnownHelper = true;
|
||||
} else if (isScoped || this.options.knownHelpersOnly) {
|
||||
toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||
} else {
|
||||
toPush = topStack + " = "
|
||||
@@ -512,10 +533,12 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
|
||||
invokeMustache: function(paramSize, original) {
|
||||
this.populateParams(paramSize, this.quotedString(original), "{}", null, function(nextStack, helperMissingString, id) {
|
||||
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||
this.context.aliases.undef = 'void 0';
|
||||
this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
|
||||
this.source.push("else { " + nextStack + " = " + id + "; }");
|
||||
if (!this.usingKnownHelper) {
|
||||
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||
this.context.aliases.undef = 'void 0';
|
||||
this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
|
||||
this.source.push("else { " + nextStack + " = " + id + "; }");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -524,8 +547,10 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
var mainProgram = this.programExpression(guid);
|
||||
|
||||
this.populateParams(paramSize, null, mainProgram, inverse, function(nextStack, helperMissingString, id) {
|
||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||
this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
|
||||
if (!this.usingKnownHelper) {
|
||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||
this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -571,9 +596,14 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
|
||||
var nextStack = this.nextStack();
|
||||
|
||||
this.context.aliases.functionType = '"function"';
|
||||
this.source.push("if(typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
|
||||
if (this.usingKnownHelper) {
|
||||
this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
|
||||
} else {
|
||||
this.context.aliases.functionType = '"function"';
|
||||
this.source.push("if(typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
|
||||
}
|
||||
fn.call(this, nextStack, helperMissingString, id);
|
||||
this.usingKnownHelper = false;
|
||||
},
|
||||
|
||||
invokePartial: function(context) {
|
||||
@@ -681,12 +711,16 @@ Handlebars.JavaScriptCompiler = function() {};
|
||||
})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
|
||||
|
||||
Handlebars.precompile = function(string, options) {
|
||||
options = options || {};
|
||||
|
||||
var ast = Handlebars.parse(string);
|
||||
var environment = new Handlebars.Compiler().compile(ast, options);
|
||||
return new Handlebars.JavaScriptCompiler().compile(environment, options);
|
||||
};
|
||||
|
||||
Handlebars.compile = function(string, options) {
|
||||
options = options || {};
|
||||
|
||||
var ast = Handlebars.parse(string);
|
||||
var environment = new Handlebars.Compiler().compile(ast, options);
|
||||
var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||
|
||||
@@ -519,6 +519,46 @@ test("if a context is not found, helperMissing is used", function() {
|
||||
shouldCompileTo(string, context, "Hello <a>world</a>")
|
||||
});
|
||||
|
||||
module("knownHelpers");
|
||||
|
||||
test("Known helper should render helper", function() {
|
||||
var template = CompilerContext.compile("{{hello}}", {knownHelpers: {"hello" : true}})
|
||||
|
||||
var result = template({}, {helpers: {hello: function() { return "foo"; }}});
|
||||
equal(result, "foo", "'foo' should === '" + result);
|
||||
});
|
||||
|
||||
test("Unknown helper in knownHelpers only mode should be passed as undefined", function() {
|
||||
var template = CompilerContext.compile("{{typeof hello}}", {knownHelpers: {'typeof': true}, knownHelpersOnly: true})
|
||||
|
||||
var result = template({}, {helpers: {'typeof': function(arg) { return typeof arg; }, hello: function() { return "foo"; }}});
|
||||
equal(result, "undefined", "'undefined' should === '" + result);
|
||||
});
|
||||
test("Builtin helpers available in knownHelpers only mode", function() {
|
||||
var template = CompilerContext.compile("{{#unless foo}}bar{{/unless}}", {knownHelpersOnly: true})
|
||||
|
||||
var result = template({});
|
||||
equal(result, "bar", "'bar' should === '" + result);
|
||||
});
|
||||
test("Field lookup works in knownHelpers only mode", function() {
|
||||
var template = CompilerContext.compile("{{foo}}", {knownHelpersOnly: true})
|
||||
|
||||
var result = template({foo: 'bar'});
|
||||
equal(result, "bar", "'bar' should === '" + result);
|
||||
});
|
||||
test("Conditional blocks work in knownHelpers only mode", function() {
|
||||
var template = CompilerContext.compile("{{#foo}}bar{{/foo}}", {knownHelpersOnly: true})
|
||||
|
||||
var result = template({foo: 'baz'});
|
||||
equal(result, "bar", "'bar' should === '" + result);
|
||||
});
|
||||
test("Invert blocks work in knownHelpers only mode", function() {
|
||||
var template = CompilerContext.compile("{{^foo}}bar{{/foo}}", {knownHelpersOnly: true})
|
||||
|
||||
var result = template({foo: false});
|
||||
equal(result, "bar", "'bar' should === '" + result);
|
||||
});
|
||||
|
||||
module("built-in helpers");
|
||||
|
||||
test("with", function() {
|
||||
|
||||
Reference in New Issue
Block a user