From 38d2be4cc0d7ba800da53b7e3709dd0b1dc58d72 Mon Sep 17 00:00:00 2001 From: Alan Johnson Date: Sat, 20 Nov 2010 15:26:20 -0500 Subject: [PATCH] Working on getting context object working. --- lib/handlebars.js | 71 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/lib/handlebars.js b/lib/handlebars.js index d85336d9..34cae06a 100644 --- a/lib/handlebars.js +++ b/lib/handlebars.js @@ -4,6 +4,7 @@ var Handlebars = { compile: function(string) { if (Handlebars.compilerCache[string] == null) { var fnBody = Handlebars.compileFunctionBody(string); + console.log(fnBody); var fn = new Function("context", "fallback", "stack", "Handlebars", fnBody); Handlebars.compilerCache[string] = function(context, fallback, stack) { return fn(context, fallback, stack, Handlebars); }; @@ -21,7 +22,7 @@ var Handlebars = { var compiler = new Handlebars.Compiler(string); compiler.compile(); - return "fallback = fallback || {}; var stack = stack || [];" + compiler.fn; + return "context = new Handlebars.Context(context, fallback); var stack = stack || [];" + compiler.fn; }, isFunction: function(fn) { @@ -79,6 +80,7 @@ var Handlebars = { return compiled; }, + // TODO: Delete me, since I'm in Handlebars.Context now! evalExpression: function(path, context, stack, fallback) { fallback = fallback || {}; @@ -197,7 +199,7 @@ var Handlebars = { } } else { - if (!Handlebars.isEmpty(lookup)) { + if (!Handlebars.isEmpty(lookup.data)) { // TODO: which case is this, and what does it mean for multiple args out = out + Handlebars.helperMissing.call(arg[0], lookup, fn); } @@ -210,29 +212,78 @@ var Handlebars = { return out; }, + // lookup: The evaluated mustache, either function or value. A Handlebars.Context + // context: The wrapped context object + // args: The evaluated arguments to the mustache + // isEscaped: Is it escaped? handleExpression: function(lookup, context, args, isEscaped) { var out = ""; - if (Handlebars.isFunction(lookup)) { - out = out + Handlebars.filterOutput(lookup.apply(context, args), isEscaped); - } else if(!Handlebars.isEmpty(lookup)) { - out = out + Handlebars.filterOutput(lookup, isEscaped); + if (Handlebars.isFunction(lookup.data)) { + out = out + Handlebars.filterOutput(lookup.data.apply(context, args), isEscaped); + } else if(!Handlebars.isEmpty(lookup.data)) { + out = out + Handlebars.filterOutput(lookup.data, isEscaped); } return out; }, - + + // lookup: The evaluated mustache, either function or value. A Handlebars.Context + // context: The context where this item occurred + // fn: The compiled body of this inverted section handleInvertedSection: function(lookup, context, fn) { var out = ""; - if(Handlebars.isFunction(lookup) && Handlebars.isEmpty(lookup())) { + if(Handlebars.isFunction(lookup.data) && Handlebars.isEmpty(lookup.data())) { out = out + fn(context); - } else if (Handlebars.isEmpty(lookup)) { + } else if (Handlebars.isEmpty(lookup.data)) { out = out + fn(context); } return out; } } +Handlebars.Context = function(context, fallback, path) { + if (context instanceof Handlebars.Context) { + this.data = context.data; + this.fallback = context.fallback; + this.path = context.path; + } else { + this.data = Handlebars.isEmpty(context) ? {} : context; + this.fallback = fallback || {}; + this.path = path || ""; + } +}; +Handlebars.Context.prototype = { + // path: The path to evaluate + // stack: The stack to work with + evalExpression: function(path, stack) { + newContext = new Handlebars.Context(this); + console.log("--- New context:") + console.log(newContext); + + var parsedPath = Handlebars.parsePath(path); + var depth = parsedPath[0]; + var parts = parsedPath[1]; + if (depth > stack.length) { + newContext.data = null; + } else if (depth > 0) { + newContext.data = stack[stack.length - depth]; + } + + for (var i = 0; i < parts.length && typeof this.data !== "undefined" && this.data != null ; i++) { + newContext.data = newContext.data[parts[i]]; + } + + if (parts.length == 1 && typeof newContext.data === "undefined") { + newContext.data = newContext.fallback[parts[0]]; + } + + console.log("Evaluated expression '" + path + "' to:"); + console.log(newContext); + return newContext; + } +}; + Handlebars.Compiler = function(string) { this.string = string; this.pointer = -1; @@ -368,7 +419,7 @@ Handlebars.Compiler.prototype = { return "context"; } else { - return "(Handlebars.evalExpression('" + param + "', context, stack, fallback))"; + return "(context.evalExpression('" + param + "', stack))"; } },