diff options
author | kpdecker <kpdecker@gmail.com> | 2014-11-27 09:11:03 -0600 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2014-11-27 09:11:03 -0600 |
commit | f990cf006422fbcbbae7d8a8a866831e58300ea4 (patch) | |
tree | 5511ccfde2f01f1018f6a73576ef393590cf5d5a | |
parent | 1124908d2a0d36493912eb2ce062545b1b5e5445 (diff) | |
download | handlebars.js-f990cf006422fbcbbae7d8a8a866831e58300ea4.zip handlebars.js-f990cf006422fbcbbae7d8a8a866831e58300ea4.tar.gz handlebars.js-f990cf006422fbcbbae7d8a8a866831e58300ea4.tar.bz2 |
Treat partial exec in a manner closer to helpers
This helps unify the code handling and will also be needed to support string/id tracking on partials.
-rw-r--r-- | lib/handlebars/compiler/code-gen.js | 5 | ||||
-rw-r--r-- | lib/handlebars/compiler/compiler.js | 25 | ||||
-rw-r--r-- | lib/handlebars/compiler/javascript-compiler.js | 41 | ||||
-rw-r--r-- | lib/handlebars/runtime.js | 27 |
4 files changed, 50 insertions, 48 deletions
diff --git a/lib/handlebars/compiler/code-gen.js b/lib/handlebars/compiler/code-gen.js index a7c1659..0fddb7c 100644 --- a/lib/handlebars/compiler/code-gen.js +++ b/lib/handlebars/compiler/code-gen.js @@ -113,7 +113,10 @@ CodeGen.prototype = { for (var key in obj) { if (obj.hasOwnProperty(key)) { - pairs.push([this.quotedString(key), ':', castChunk(obj[key], this)]); + var value = castChunk(obj[key], this); + if (value !== 'undefined') { + pairs.push([this.quotedString(key), ':', value]); + } } } diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index e73ce37..df5a10f 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -166,24 +166,15 @@ Compiler.prototype = { var partialName = partial.sexpr.path.original; this.usePartial = true; - if (partial.sexpr.hash) { - this.accept(partial.sexpr.hash); - } else { - this.opcode('pushLiteral', partial, 'undefined'); - } - var params = partial.sexpr.params; - if (params.length) { - if (params.length > 1) { - throw new Exception('Unsupported number of partial arguments: ' + params.length, partial); - } - - this.pushParam(params[0]); - } else { - this.opcode('getContext', partial, 0); - this.opcode('pushContext', partial); + if (params.length > 1) { + throw new Exception('Unsupported number of partial arguments: ' + params.length, partial); + } else if (!params.length) { + params.push({type: 'PathExpression', parts: [], depth: 0}); } + this.setupFullMustacheParams(partial.sexpr, undefined, undefined, true); + var indent = partial.indent || ''; if (this.options.preventIndent && indent) { this.opcode('appendContent', partial, indent); @@ -391,7 +382,7 @@ Compiler.prototype = { } }, - setupFullMustacheParams: function(sexpr, program, inverse) { + setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) { var params = sexpr.params; this.pushParams(params); @@ -401,7 +392,7 @@ Compiler.prototype = { if (sexpr.hash) { this.accept(sexpr.hash); } else { - this.opcode('emptyHash', sexpr); + this.opcode('emptyHash', sexpr, omitEmpty); } return params; diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index cde2ab5..db19778 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -275,7 +275,7 @@ JavaScriptCompiler.prototype = { blockValue: function(name) { var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'), params = [this.contextName(0)]; - this.setupParams(name, 0, params); + this.setupHelperArgs(name, 0, params); var blockName = this.popStack(); params.splice(1, 0, blockName); @@ -293,7 +293,7 @@ JavaScriptCompiler.prototype = { // We're being a bit cheeky and reusing the options value from the prior exec var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'), params = [this.contextName(0)]; - this.setupParams('', 0, params, true); + this.setupHelperArgs('', 0, params, true); this.flushInline(); @@ -469,9 +469,7 @@ JavaScriptCompiler.prototype = { } }, - emptyHash: function() { - this.pushStackLiteral('{}'); - + emptyHash: function(omitEmpty) { if (this.trackIds) { this.push('{}'); // hashIds } @@ -479,6 +477,7 @@ JavaScriptCompiler.prototype = { this.push('{}'); // hashContexts this.push('{}'); // hashTypes } + this.pushStackLiteral(omitEmpty ? 'undefined' : '{}'); }, pushHash: function() { if (this.hash) { @@ -611,16 +610,22 @@ JavaScriptCompiler.prototype = { // This operation pops off a context, invokes a partial with that context, // and pushes the result of the invocation back. invokePartial: function(name, indent) { - var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"]; + var params = [], + options = this.setupParams(name, 1, params, false); - if (this.options.data) { - params.push("data"); - } else if (this.options.compat) { - params.push('undefined'); + if (indent) { + options.indent = JSON.stringify(indent); } + options.helpers = 'helpers'; + options.partials = 'partials'; + + params.unshift(this.nameLookup('partials', name, 'partial')); + if (this.options.compat) { - params.push('depths'); + options.depths = 'depths'; } + options = this.objectLiteral(options); + params.push(options); this.push(this.source.functionCall('this.invokePartial', '', params)); }, @@ -881,7 +886,7 @@ JavaScriptCompiler.prototype = { setupHelper: function(paramSize, name, blockHelper) { var params = [], - paramsInit = this.setupParams(name, paramSize, params, blockHelper); + paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); var foundHelper = this.nameLookup('helpers', name, 'helper'); return { @@ -892,8 +897,8 @@ JavaScriptCompiler.prototype = { }; }, - setupParams: function(helper, paramSize, params, useRegister) { - var options = {}, contexts = [], types = [], ids = [], param, inverse, program; + setupParams: function(helper, paramSize, params) { + var options = {}, contexts = [], types = [], ids = [], param; options.name = this.quotedString(helper); options.hash = this.popStack(); @@ -906,8 +911,8 @@ JavaScriptCompiler.prototype = { options.hashContexts = this.popStack(); } - inverse = this.popStack(); - program = this.popStack(); + var inverse = this.popStack(), + program = this.popStack(); // Avoid setting fn and inverse if neither are set. This allows // helpers to do a check for `if (options.fn)` @@ -943,7 +948,11 @@ JavaScriptCompiler.prototype = { if (this.options.data) { options.data = "data"; } + return options; + }, + setupHelperArgs: function(helper, paramSize, params, useRegister) { + var options = this.setupParams(helper, paramSize, params, true); options = this.objectLiteral(options); if (useRegister) { this.useRegister('options'); diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index 05759cb..455dd33 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -35,36 +35,35 @@ export function template(templateSpec, env) { // for external users to override these as psuedo-supported APIs. env.VM.checkRevision(templateSpec.compiler); - var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) { - if (hash) { - context = Utils.extend({}, context, hash); + var invokePartialWrapper = function(partial, context, options) { + if (options.hash) { + context = Utils.extend({}, context, options.hash); } if (!partial) { - partial = partials[name]; + partial = options.partials[options.name]; } - var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths); + var result = env.VM.invokePartial.call(this, partial, context, options); if (result == null && env.compile) { - var options = { helpers: helpers, partials: partials, data: data, depths: depths }; - partials[name] = env.compile(partial, templateSpec.compilerOptions, env); - result = partials[name](context, options); + options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env); + result = options.partials[options.name](context, options); } if (result != null) { - if (indent) { + if (options.indent) { var lines = result.split('\n'); for (var i = 0, l = lines.length; i < l; i++) { if (!lines[i] && i + 1 === l) { break; } - lines[i] = indent + lines[i]; + lines[i] = options.indent + lines[i]; } result = lines.join('\n'); } return result; } else { - throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); + throw new Exception("The partial " + options.name + " could not be compiled when running in runtime-only mode"); } }; @@ -172,11 +171,11 @@ export function program(container, i, fn, data, depths) { return prog; } -export function invokePartial(partial, name, context, helpers, partials, data, depths) { - var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths }; +export function invokePartial(partial, context, options) { + options.partial = true; if(partial === undefined) { - throw new Exception("The partial " + name + " could not be found"); + throw new Exception("The partial " + options.name + " could not be found"); } else if(partial instanceof Function) { return partial(context, options); } |