diff options
Diffstat (limited to 'lib/handlebars/compiler/compiler.js')
-rw-r--r-- | lib/handlebars/compiler/compiler.js | 95 |
1 files changed, 43 insertions, 52 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index 3a48c16..4a60c05 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -315,12 +315,14 @@ Handlebars.JavaScriptCompiler = function() {}; }, // END PUBLIC API - compile: function(environment, options, asObject) { + compile: function(environment, options, context, asObject) { this.environment = environment; this.options = options || {}; - this.context = { - aliases: {}, + this.name = this.environment.name; + this.isChild = !!context; + this.context = context || { + programs: [], aliases: { self: 'this' }, registers: {list: []} }; @@ -330,7 +332,7 @@ Handlebars.JavaScriptCompiler = function() {}; this.stackSlot = 0; this.stackVars = []; - this.compileChildren(environment, options, asObject); + this.compileChildren(environment, options); var opcodes = environment.opcodes, opcode, name, declareName, declareVal; @@ -380,9 +382,13 @@ Handlebars.JavaScriptCompiler = function() {}; preamble: function() { var out = []; - var copies = "helpers = helpers || Handlebars.helpers;"; - if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; } - out.push(copies); + if (!this.isChild) { + var copies = "helpers = helpers || Handlebars.helpers;"; + if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; } + out.push(copies); + } else { + out.push(''); + } out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context"); @@ -393,25 +399,33 @@ Handlebars.JavaScriptCompiler = function() {}; }, createFunctionContext: function(asObject) { - var locals = this.stackVars.concat(this.context.registers.list); + var locals = this.stackVars; + if (!this.isChild) { + locals = locals.concat(this.context.registers.list); + } if(locals.length > 0) { this.source[1] = this.source[1] + ", " + locals.join(", "); } // Generate minimizer alias mappings - var aliases = [] - for (var alias in this.context.aliases) { - this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; + if (!this.isChild) { + var aliases = [] + for (var alias in this.context.aliases) { + this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; + } } this.source[1] = this.source[1] + ";"; - this.source.push("return buffer;"); + // Merge children + if (!this.isChild) { + this.source[1] += '\n' + this.context.programs.join('\n') + '\n'; + } - var params = ["Handlebars", "context", "helpers", "partials"]; + this.source.push("return buffer;"); - if(this.options.data) { params.push("data"); } + var params = this.isChild ? ["context", "data"] : ["Handlebars", "context", "helpers", "partials", "data"]; for(var i=0, l=this.environment.depths.list.length; i<l; i++) { params.push("depth" + this.environment.depths.list[i]); @@ -422,24 +436,11 @@ Handlebars.JavaScriptCompiler = function() {}; if (asObject) { params.push(this.source.join("\n ")); - return { - fn: Function.apply(this, params), - children: this.environment.children - }; + return Function.apply(this, params); } else { - var functionSource = 'function(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}'; - + var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}'; Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n"); - - var script = ['{\n fn: ', functionSource, ',\n children: [\n '], - children = this.environment.children; - for (var i = 0, len = children.length; i < len; i++) { - script.push(children[i]); - if (i < len-1) { script.push(',\n'); } - } - script.push('\n ]\n}'); - - return script.join(''); + return functionSource; } }, @@ -582,7 +583,7 @@ Handlebars.JavaScriptCompiler = function() {}; }, invokePartial: function(context) { - this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);"); + this.pushStack("self.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);"); }, assignToHash: function(key) { @@ -596,29 +597,27 @@ Handlebars.JavaScriptCompiler = function() {}; compiler: JavaScriptCompiler, - compileChildren: function(environment, options, asObject) { + compileChildren: function(environment, options) { var children = environment.children, child, compiler; - var compiled = []; for(var i=0, l=children.length; i<l; i++) { child = children[i]; compiler = new this.compiler(); - compiled[i] = compiler.compile(child, options, asObject); + this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children + var index = this.context.programs.length; + child.index = index; + child.name = 'program' + index; + this.context.programs[index] = compiler.compile(child, options, this.context); } - - environment.rawChildren = children; - environment.children = compiled; }, programExpression: function(guid) { - - var programParams = [guid, "helpers", "partials"]; if(guid == null) { return "self.noop"; } - var depths = this.environment.rawChildren[guid].depths.list; - - if(this.options.data) { programParams.push("data"); } + var child = this.environment.children[guid], + depths = child.depths.list; + var programParams = [child.index, child.name, "data"]; for(var i=0, l = depths.length; i<l; i++) { depth = depths[i]; @@ -627,18 +626,10 @@ Handlebars.JavaScriptCompiler = function() {}; else { programParams.push("depth" + (depth - 1)); } } - if(!this.environment.usePartial) { - if(programParams[3]) { - programParams[2] = "null"; - } else { - programParams.pop(); - } - } - if(depths.length === 0) { return "self.program(" + programParams.join(", ") + ")"; } else { - programParams[0] = "this.children[" + guid + "]"; + programParams.shift(); return "self.programWithDepth(" + programParams.join(", ") + ")"; } }, @@ -704,7 +695,7 @@ Handlebars.precompile = function(string, options) { Handlebars.compile = function(string, options) { var ast = Handlebars.parse(string); var environment = new Handlebars.Compiler().compile(ast, options); - var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, true); + var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true); return Handlebars.template(templateSpec); }; |