From 88e70033311d7bd2244006a0dc7a0e0db082a38e Mon Sep 17 00:00:00 2001 From: tomhuda Date: Fri, 11 Feb 2011 17:02:26 -0800 Subject: [PATCH] * Added a few public API methods to JavaScriptCompiler.prototype, so it can be subclassed. * made it possible to define an alternate name lookup scheme (so that {{foo}} does not have to be context.foo, but can instead be something like context.get('foo')) * made it possible to substitute an alternate buffer instead of the default empty String and override how the compiled template appends to the buffer * Added the concept of template-local data. In order to enable template-local data, pass true as the second parameter to the template compiler. Then, pass in the data as the fourth parameter (context, helpers, partials, data). These signatures may change before the 1.0 release. --- lib/handlebars/base.js | 3 +- lib/handlebars/vm.js | 89 ++++++++++++++++++++++++++---------------- spec/qunit_spec.js | 69 +++++++++++++++++++++++++++++++- spec/spec_helper.rb | 2 +- 4 files changed, 125 insertions(+), 38 deletions(-) diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js index 583f88c2..63aa1d60 100644 --- a/lib/handlebars/base.js +++ b/lib/handlebars/base.js @@ -106,10 +106,11 @@ Handlebars.logger = { // override in the host environment log: function(level, str) {} -} +}; Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); }; // END(BROWSER) module.exports = Handlebars; + diff --git a/lib/handlebars/vm.js b/lib/handlebars/vm.js index 5013b7ae..fee59534 100644 --- a/lib/handlebars/vm.js +++ b/lib/handlebars/vm.js @@ -246,8 +246,28 @@ Handlebars.JavaScriptCompiler = function() {}; }; JavaScriptCompiler.prototype = { - compile: function(environment) { + // PUBLIC API: You can override these methods in a subclass to provide + // alternative compiled forms for name lookup and buffering semantics + nameLookup: function(parent, name, type) { + if(JavaScriptCompiler.RESERVED_WORDS[name]) { + return parent + "['" + name + "']"; + } else { + return parent + "." + name; + } + }, + + appendToBuffer: function(string) { + return "buffer = buffer + " + string + ";"; + }, + + initializeBuffer: function() { + return this.quotedString(""); + }, + // END PUBLIC API + + compile: function(environment, data) { this.environment = environment; + this.data = data; this.preamble(); @@ -255,7 +275,7 @@ Handlebars.JavaScriptCompiler = function() {}; this.stackVars = []; this.registers = {list: []}; - this.compileChildren(environment); + this.compileChildren(environment, data); Handlebars.log(Handlebars.logger.DEBUG, environment.disassemble() + "\n\n"); @@ -306,7 +326,7 @@ Handlebars.JavaScriptCompiler = function() {}; preamble: function() { var out = []; - out.push("var buffer = '', currentContext = context"); + out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context"); var copies = "helpers = helpers || Handlebars.helpers;"; if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; } @@ -323,9 +343,11 @@ Handlebars.JavaScriptCompiler = function() {}; escapeExpression: Handlebars.Utils.escapeExpression, invokePartial: Handlebars.VM.invokePartial, programs: [], - program: function(i, helpers, partials) { + program: function(i, helpers, partials, data) { var programWrapper = this.programs[i]; - if(programWrapper) { + if(data) { + return Handlebars.VM.program(this.children[i], helpers, partials, data); + } else if(programWrapper) { return programWrapper; } else { programWrapper = this.programs[i] = Handlebars.VM.program(this.children[i], helpers, partials); @@ -347,11 +369,14 @@ Handlebars.JavaScriptCompiler = function() {}; var params = ["Handlebars", "context", "helpers", "partials"]; + if(this.data) { params.push("data"); } + for(var i=0, l=this.environment.depths.list.length; i