summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-08-13 20:46:07 -0500
committerkpdecker <kpdecker@gmail.com>2014-08-13 20:46:42 -0500
commitc98613b711a70a82a960c20c00d8d92d5eed1024 (patch)
tree364862d90bc601284d35f5c19e8fed1abad7e4f4 /lib/handlebars/compiler
parent625b00e1dafccc8653bf4cb4dc3dac55f6b3b020 (diff)
downloadhandlebars.js-c98613b711a70a82a960c20c00d8d92d5eed1024.zip
handlebars.js-c98613b711a70a82a960c20c00d8d92d5eed1024.tar.gz
handlebars.js-c98613b711a70a82a960c20c00d8d92d5eed1024.tar.bz2
Implement recursive field lookup in compat mode
Provides the mustache behavior of recursive lookup without the use of depthed paths. Note that this does incur a fairly dramatic performance penalty for depthed queries.
Diffstat (limited to 'lib/handlebars/compiler')
-rw-r--r--lib/handlebars/compiler/compiler.js8
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js24
2 files changed, 24 insertions, 8 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index 48575d4..ffddec4 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -308,7 +308,7 @@ Compiler.prototype = {
// Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
this.opcode('pushContext');
} else {
- this.opcode('lookupOnContext', id.parts, id.falsy);
+ this.opcode('lookupOnContext', id.parts, id.falsy, id.isScoped);
}
},
@@ -424,6 +424,9 @@ export function precompile(input, options, env) {
if (!('data' in options)) {
options.data = true;
}
+ if (options.compat) {
+ options.useDepths = true;
+ }
var ast = env.parse(input);
var environment = new env.Compiler().compile(ast, options);
@@ -440,6 +443,9 @@ export function compile(input, options, env) {
if (!('data' in options)) {
options.data = true;
}
+ if (options.compat) {
+ options.useDepths = true;
+ }
var compiled;
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index f1b6d36..b9b858d 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -17,6 +17,11 @@ JavaScriptCompiler.prototype = {
return parent + "['" + name + "']";
}
},
+ depthedLookup: function(name) {
+ this.aliases.lookup = 'this.lookup';
+
+ return 'lookup(depths, "' + name + '")';
+ },
compilerInfo: function() {
var revision = COMPILER_REVISION,
@@ -69,7 +74,7 @@ JavaScriptCompiler.prototype = {
this.compileChildren(environment, options);
- this.useDepths = this.useDepths || environment.depths.list.length;
+ this.useDepths = this.useDepths || environment.depths.list.length || this.options.compat;
var opcodes = environment.opcodes,
opcode,
@@ -356,15 +361,20 @@ JavaScriptCompiler.prototype = {
//
// Looks up the value of `name` on the current context and pushes
// it onto the stack.
- lookupOnContext: function(parts, falsy) {
+ lookupOnContext: function(parts, falsy, scoped) {
/*jshint -W083 */
- this.pushContext();
- if (!parts) {
- return;
+ var i = 0,
+ len = parts.length;
+
+ if (!scoped && this.isChild && this.options.compat && !this.lastContext) {
+ // The depthed query is expected to handle the undefined logic for the root level that
+ // is implemented below, so we evaluate that directly in compat mode
+ this.pushStackLiteral(this.depthedLookup(parts[i++]));
+ } else {
+ this.pushContext();
}
- var len = parts.length;
- for (var i = 0; i < len; i++) {
+ for (; i < len; i++) {
this.replaceStack(function(current) {
var lookup = this.nameLookup(current, parts[i], 'context');
// We want to ensure that zero and false are handled properly for the first element