Made path parser reusable so that we can use it inside of __get__.

This commit is contained in:
Alan Johnson
2010-08-04 22:18:40 -04:00
parent 54838cd90c
commit 4950beea1c
2 changed files with 52 additions and 24 deletions
+42 -24
View File
@@ -24,6 +24,40 @@ Handlebars.ParseError = function(message) {
this.message = message;
}
// Returns a two element array containing the numbers of contexts to back up the stack and
// the properties to dig into on the current context
Handlebars.parsePath = function(path) {
if (path == null) {
return [0, []];
}
var parts = path.split("/");
var readDepth = false;
var depth = 0;
var dig = [];
for (var i = 0; i < parts.length; i++) {
switch(parts[i]) {
case "..":
if (readDepth) {
throw new Handlebars.ParseError("Cannot jump out of context after moving into a context.");
} else {
depth += 1;
}
break;
case ".":
// do nothing - using .'s is pretty dumb, but it's also basically free for us to support
case "this":
// if we do nothing you'll end up sticking in the same context
break;
default:
readDepth = true;
dig.push(parts[i]);
}
}
return [depth, dig];
}
Handlebars.helperMissing = function(object, fn) {
var ret = "";
@@ -88,37 +122,21 @@ Handlebars.Compiler.prototype = {
},
lookupFor: function(param) {
if (!param) {
return "context";
}
var parsed = Handlebars.parsePath(param);
var depth = parsed[0];
var parts = parsed[1];
console.log(depth)
var parts = param.split("/");
var readDepth = false;
var depth = 0;
var paramExpr = "";
for (var i = 0; i < parts.length; i++) {
switch(parts[i]) {
case "..":
if (readDepth) {
throw new Handlebars.ParseError("Cannot jump out of context after moving into a context.");
} else {
depth += 1;
}
break;
case ".":
// do nothing - using .'s is pretty dumb, but it's also basically free for us to support
case "this":
// if we do nothing you'll end up sticking in the same context
break;
default:
readDepth = true;
paramExpr += "['" + parts[i] + "']";
}
for(var i = 0; i < parts.length; i++) {
paramExpr += "['" + parts[i] + "']";
}
if (depth > 0) {
console.log(depth + ", " + paramExpr);
return "( stack[stack.length - " + depth + "]" + paramExpr + ")";
} else {
console.log(paramExpr);
return "( context" + paramExpr + " || fallback " + paramExpr + " )";
}
},
+10
View File
@@ -83,6 +83,16 @@ test("block with complex lookup", function() {
"Templates can access variables in contexts up the stack with relative path syntax");
});
test("helper with complex lookup", function() {
var string = "{{#goodbyes}}{{link}}{{/goodbyes}}"
var hash = {prefix: "/root", goodbyes: [{text: "Goodbye", link: "goodbye"}]};
var fallback = {link: function() {
return "<a href='" + this.__get__("../prefix") + "/" + this.link + "'>" + this.text + "</a>"
}};
shouldCompileTo(string, [hash, fallback], "<a href='/root/goodbye'>Goodbye</a>")
});
test("block with deep nested complex lookup", function() {
var string = "{{#outer}}Goodbye {{#inner}}cruel {{../../omg}}{{/inner}}{{/outer}}";
var hash = {omg: "OMG!", outer: [{ inner: [{ text: "goodbye" }] }] };