Merge branch 'master' of http://github.com/wycats/handlebars.js
This commit is contained in:
+13
-12
@@ -4,9 +4,9 @@ var Handlebars = {
|
||||
compile: function(string) {
|
||||
if (Handlebars.compilerCache[string] == null) {
|
||||
var fnBody = Handlebars.compileFunctionBody(string);
|
||||
var fn = new Function("context", "fallback", "Handlebars", fnBody);
|
||||
var fn = new Function("context", "fallback", "stack", "Handlebars", fnBody);
|
||||
Handlebars.compilerCache[string] =
|
||||
function(context, fallback) { return fn(context, fallback, Handlebars); };
|
||||
function(context, fallback, stack) { return fn(context, fallback, stack, Handlebars); };
|
||||
}
|
||||
|
||||
return Handlebars.compilerCache[string];
|
||||
@@ -14,14 +14,14 @@ var Handlebars = {
|
||||
|
||||
compileToString: function(string) {
|
||||
var fnBody = Handlebars.compileFunctionBody(string);
|
||||
return "function(context, fallback) { " + fnBody + "}";
|
||||
return "function(context, fallback, stack) { " + fnBody + "}";
|
||||
},
|
||||
|
||||
compileFunctionBody: function(string) {
|
||||
var compiler = new Handlebars.Compiler(string);
|
||||
compiler.compile();
|
||||
|
||||
return "fallback = fallback || {}; var stack = [];" + compiler.fn;
|
||||
return "fallback = fallback || {}; var stack = stack || [];" + compiler.fn;
|
||||
},
|
||||
|
||||
isFunction: function(fn) {
|
||||
@@ -85,7 +85,7 @@ var Handlebars = {
|
||||
context = stack[stack.length - depth];
|
||||
}
|
||||
|
||||
for (var i = 0; i < parts.length && typeof context !== "undefined"; i++) {
|
||||
for (var i = 0; i < parts.length && typeof context !== "undefined" && context != null ; i++) {
|
||||
context = context[parts[i]];
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ var Handlebars = {
|
||||
parsePath: function(path) {
|
||||
if (path == null) {
|
||||
return [0, []];
|
||||
} else if (Handlebars.pathPatterns[path] != null) {
|
||||
return Handlebars.pathPatterns[path];
|
||||
} else if (Handlebars.pathPatterns["hbs-" + path] != null) {
|
||||
return Handlebars.pathPatterns["hbs-" + path];
|
||||
}
|
||||
|
||||
var parts = path.split("/");
|
||||
@@ -147,7 +147,7 @@ var Handlebars = {
|
||||
}
|
||||
|
||||
var ret = [depth, dig];
|
||||
Handlebars.pathPatterns[path] = ret;
|
||||
Handlebars.pathPatterns["hbs" + path] = ret;
|
||||
return ret;
|
||||
},
|
||||
|
||||
@@ -387,10 +387,11 @@ Handlebars.Compiler.prototype = {
|
||||
// don't need to be globally unique, just per compiler
|
||||
var fnId = "fn" + this.pointer.toString();
|
||||
this.fn += "var wrappedContext = Handlebars.buildContext(context, stack);";
|
||||
this.fn += "stack.push(context);";
|
||||
this.fn += "var " + fnId + " = function(context) {" + result + "}; ";
|
||||
this.fn += "lookup = " + this.lookupFor(mustache) + "; ";
|
||||
|
||||
this.fn += "arg = " + param + ";";
|
||||
this.fn += "stack.push(context);";
|
||||
|
||||
if (compiler.continueInverted) {
|
||||
var invertedCompiler = this.compileToEndOfBlock(mustache);
|
||||
this.fn += " var " + fnId + "Not = function(context) { " + invertedCompiler.fn + " };";
|
||||
@@ -398,7 +399,7 @@ Handlebars.Compiler.prototype = {
|
||||
else {
|
||||
this.fn += " var " + fnId + "Not = null;";
|
||||
}
|
||||
this.fn += "out = out + Handlebars.handleBlock(lookup, wrappedContext, " + param + ", " + fnId + ", " + fnId + "Not);"
|
||||
this.fn += "out = out + Handlebars.handleBlock(lookup, wrappedContext, arg, " + fnId + ", " + fnId + "Not);"
|
||||
|
||||
this.fn += "stack.pop();";
|
||||
this.openBlock = false;
|
||||
@@ -407,7 +408,7 @@ Handlebars.Compiler.prototype = {
|
||||
addPartial: function(mustache, param) {
|
||||
// either used a cached copy of the partial or compile a new one
|
||||
this.fn += "if (typeof fallback['partials'] === 'undefined' || typeof fallback['partials']['" + mustache + "'] === 'undefined') throw new Handlebars.Exception('Attempted to render undefined partial: " + mustache + "');";
|
||||
this.fn += "out = out + Handlebars.compilePartial(fallback['partials']['" + mustache + "'])(" + param + ", fallback);";
|
||||
this.fn += "out = out + Handlebars.compilePartial(fallback['partials']['" + mustache + "'])(" + param + ", fallback, stack);";
|
||||
},
|
||||
|
||||
parseMustache: function() {
|
||||
|
||||
+25
-4
@@ -209,6 +209,20 @@ test("helper with complex lookup", function() {
|
||||
shouldCompileTo(string, [hash, fallback], "<a href='/root/goodbye'>Goodbye</a>")
|
||||
});
|
||||
|
||||
test("helper block with complex lookup expression", function() {
|
||||
var string = "{{#goodbyes}}{{../name}}{{/goodbyes}}"
|
||||
var hash = {name: "Alan"};
|
||||
var fallback = {goodbyes: function(context, fn) {
|
||||
var out = "";
|
||||
var byes = ["Goodbye", "goodbye", "GOODBYE"];
|
||||
for (var i = 0,j = byes.length; i < j; i++) {
|
||||
out += byes[i] + " " + fn(context) + "! ";
|
||||
}
|
||||
return out;
|
||||
}};
|
||||
shouldCompileTo(string, [hash, fallback], "Goodbye Alan! goodbye Alan! GOODBYE Alan! ");
|
||||
});
|
||||
|
||||
test("helper with complex lookup and nested template", function() {
|
||||
var string = "{{#goodbyes}}{{#link}}{{text}}{{/link}}{{/goodbyes}}";
|
||||
var hash = {prefix: '/root', goodbyes: [{text: "Goodbye", url: "goodbye"}]};
|
||||
@@ -360,10 +374,17 @@ test("rendering undefined partial throws an exception", function() {
|
||||
});
|
||||
|
||||
test("GH-14: a partial preceding a selector", function() {
|
||||
var string = "Dudes: {{>dude}} {{another_dude}}";
|
||||
var dude = "{{name}}";
|
||||
var hash = {name:"Jeepers", another_dude:"Creepers"};
|
||||
shouldCompileTo(string, [hash, {partials: {dude:dude}}], "Dudes: Jeepers Creepers", "Regular selectors can follow a partial");
|
||||
var string = "Dudes: {{>dude}} {{another_dude}}";
|
||||
var dude = "{{name}}";
|
||||
var hash = {name:"Jeepers", another_dude:"Creepers"};
|
||||
shouldCompileTo(string, [hash, {partials: {dude:dude}}], "Dudes: Jeepers Creepers", "Regular selectors can follow a partial");
|
||||
});
|
||||
|
||||
test("Partial containing complex expression", function() {
|
||||
var template = "Dudes: {{#dudes}}{{> dude}} {{/dudes}}";
|
||||
var dude = "{{../salutation}} {{name}}";
|
||||
var hash = {salutation: "Mr.", dudes: [{name: "Yehuda"}, {name: "Alan"}]};
|
||||
shouldCompileTo(template, [hash, {partials: {dude: dude}}], "Dudes: Mr. Yehuda Mr. Alan ");
|
||||
});
|
||||
|
||||
module("safestring");
|
||||
|
||||
Executable → Regular
Reference in New Issue
Block a user