Made progress on inverted sections. Functions almost work now, and expressions aren't far behind.

This commit is contained in:
Alan Johnson
2010-08-17 00:46:04 -04:00
parent 8f76f99663
commit 2a112fe07f
2 changed files with 48 additions and 3 deletions
+2
View File
@@ -6,3 +6,5 @@
* data-binding for iteration-style block helpers
* README
* Rationale (how it's different from mustache, and why)
* Refactor blocks/inverted sections so shared code isn't copied and pasted
+46 -3
View File
@@ -107,6 +107,18 @@ Handlebars = {
}
return [depth, dig];
},
isEmpty: function(value) {
if (typeof object === "undefined") {
return true;
} else if (!object) {
return true;
} else if(toString.call(object) === "[object Array]" && object.length == 0) {
return true;
} else {
return false;
}
}
}
@@ -120,6 +132,7 @@ Handlebars.Compiler = function(string) {
this.comment = false;
this.escaped = true;
this.partial = false;
this.inverted = false;
};
Handlebars.Exception = function(message) {
@@ -204,6 +217,23 @@ Handlebars.Compiler.prototype = {
this.fn += "else if(typeof " + expr + "!== 'undefined') out = out + " + escapeCall + expr + ");";
},
addInvertedSection: function(mustache) {
var result = this.compileToEndOfBlock(mustache);
// each function made internally needs a unique IDs. These are locals, so they
// don't need to be globally unique, just per compiler
var fnId = "fn" + this.pointer.toString();
this.fn += "var proxy = Handlebars.buildContext(context, stack);";
this.fn += "var " + fnId + " = function(context) {" + result + "}; ";
this.fn += "lookup = " + this.lookupFor(mustache) + "; ";
this.fn += "if(Handlebars.isFunction(lookup) && Handlebars.isEmpty(lookup())) out = out + " + fnId + "(proxy);";
console.log(this.fn);
this.openBlock = false;
this.inverted = false;
},
lookupFor: function(param) {
var parsed = Handlebars.parsePath(param);
var depth = parsed[0];
@@ -221,9 +251,7 @@ Handlebars.Compiler.prototype = {
}
},
addBlock: function(mustache, param, parts) {
// set up the stack before the new compiler starts
this.fn += "stack.push(context);";
compileToEndOfBlock: function(mustache) {
var compiler = new Handlebars.Compiler(this.string.slice(this.pointer + 1, -1));
// sub-compile with a custom EOF instruction
@@ -237,6 +265,14 @@ Handlebars.Compiler.prototype = {
// move the pointer forward the amount of characters handled by the sub-compiler
this.pointer += compiler.pointer + 1;
return result;
},
addBlock: function(mustache, param, parts) {
// set up the stack before the new compiler starts
this.fn += "stack.push(context);";
var result = this.compileToEndOfBlock(mustache);
// each function made internally needs a unique IDs. These are locals, so they
// don't need to be globally unique, just per compiler
var fnId = "fn" + this.pointer.toString();
@@ -271,6 +307,10 @@ Handlebars.Compiler.prototype = {
} else if (next === ">") {
this.partial = true;
this.getChar();
} else if (next === "^") {
this.inverted = true;
this.openBlock = true;
this.getChar();
} else if(next === "{" || next === "&") {
this.escaped = false;
this.getChar();
@@ -301,6 +341,9 @@ Handlebars.Compiler.prototype = {
} else if (this.partial) {
this.addPartial(mustache, param)
return;
} else if (this.inverted) {
this.addInvertedSection(mustache);
return;
} else if(this.openBlock) {
this.addBlock(mustache, param, parts)
return;