diff options
Diffstat (limited to 'lib/handlebars/runtime.js')
-rw-r--r-- | lib/handlebars/runtime.js | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index b9fc77d..0780fbf 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -23,26 +23,43 @@ export function checkRevision(compilerInfo) { // TODO: Remove this line and break up compilePartial export function template(templateSpec, env) { + /* istanbul ignore next */ if (!env) { throw new Exception("No environment passed to template"); } + if (!templateSpec || !templateSpec.main) { + throw new Exception('Unknown template object: ' + typeof templateSpec); + } // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as psuedo-supported APIs. env.VM.checkRevision(templateSpec.compiler); - var invokePartialWrapper = function(partial, name, context, hash, helpers, partials, data) { + var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) { if (hash) { context = Utils.extend({}, context, hash); } - var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data); - if (result != null) { return result; } + var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths); - if (env.compile) { - var options = { helpers: helpers, partials: partials, data: data }; - partials[name] = env.compile(partial, { data: data !== undefined }, env); - return partials[name](context, options); + if (result == null && env.compile) { + var options = { helpers: helpers, partials: partials, data: data, depths: depths }; + partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env); + result = partials[name](context, options); + } + if (result != null) { + if (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]; + } + result = lines.join('\n'); + } + return result; } else { throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); } @@ -50,6 +67,14 @@ export function template(templateSpec, env) { // Just add water var container = { + lookup: function(depths, name) { + var len = depths.length; + for (var i = 0; i < len; i++) { + if (depths[i] && depths[i][name] != null) { + return depths[i][name]; + } + } + }, lambda: function(current, context) { return typeof current === 'function' ? current.call(context) : current; }, @@ -62,17 +87,16 @@ export function template(templateSpec, env) { }, programs: [], - program: function(i, data) { + program: function(i, data, depths) { var programWrapper = this.programs[i], fn = this.fn(i); - if(data) { - programWrapper = program(this, i, fn, data); + if (data || depths) { + programWrapper = program(this, i, fn, data, depths); } else if (!programWrapper) { programWrapper = this.programs[i] = program(this, i, fn); } return programWrapper; }, - programWithDepth: env.VM.programWithDepth, data: function(data, depth) { while (data && depth--) { @@ -104,7 +128,12 @@ export function template(templateSpec, env) { if (!options.partial && templateSpec.useData) { data = initData(context, data); } - return templateSpec.main.call(container, context, container.helpers, container.partials, data); + var depths; + if (templateSpec.useDepths) { + depths = options.depths ? [context].concat(options.depths) : [context]; + } + + return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths); }; ret._setup = function(options) { @@ -121,40 +150,29 @@ export function template(templateSpec, env) { }; ret._child = function(i) { + if (templateSpec.depth) { + throw new Exception('_child can not be used with depthed methods'); + } + + // TODO : Fix this return container.programWithDepth(i); }; return ret; } -export function programWithDepth(i, data /*, $depth */) { - /*jshint -W040 */ - var args = Array.prototype.slice.call(arguments, 2), - container = this, - fn = container.fn(i); - - var prog = function(context, options) { - options = options || {}; - - return fn.apply(container, [context, container.helpers, container.partials, options.data || data].concat(args)); - }; - prog.program = i; - prog.depth = args.length; - return prog; -} - -export function program(container, i, fn, data) { +export function program(container, i, fn, data, depths) { var prog = function(context, options) { options = options || {}; - return fn.call(container, context, container.helpers, container.partials, options.data || data); + return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths)); }; prog.program = i; - prog.depth = 0; + prog.depth = depths ? depths.length : 0; return prog; } -export function invokePartial(partial, name, context, helpers, partials, data) { - var options = { partial: true, helpers: helpers, partials: partials, data: data }; +export function invokePartial(partial, name, context, helpers, partials, data, depths) { + var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths }; if(partial === undefined) { throw new Exception("The partial " + name + " could not be found"); |