Merge pull request #491 from wycats/data-depth

For nested helpers: get the @ variables of the outer helper from the inner one
This commit is contained in:
Kevin Decker
2014-02-09 19:16:47 -06:00
6 changed files with 39 additions and 24 deletions
+3 -1
View File
@@ -223,5 +223,7 @@ export var logger = {
export function log(level, obj) { logger.log(level, obj); }
export var createFrame = function(object) {
return Utils.extend({}, object);
var frame = Utils.extend({}, object);
frame._parent = object;
return frame;
};
+1 -5
View File
@@ -310,11 +310,7 @@ Compiler.prototype = {
DATA: function(data) {
this.options.data = true;
if (data.id.isScoped || data.id.depth) {
throw new Exception('Scoped data references are not supported: ' + data.original, data);
}
this.opcode('lookupData');
this.opcode('lookupData', data.id.depth);
var parts = data.id.parts;
for(var i=0, l=parts.length; i<l; i++) {
this.opcode('lookup', parts[i]);
@@ -403,8 +403,12 @@ JavaScriptCompiler.prototype = {
// On stack, after: data, ...
//
// Push the data lookup operator
lookupData: function() {
this.pushStackLiteral('data');
lookupData: function(depth) {
if (!depth) {
this.pushStackLiteral('data');
} else {
this.pushStackLiteral('this.data(data, ' + depth + ')');
}
},
// [pushStringParam]
+6
View File
@@ -77,6 +77,12 @@ export function template(templateSpec, env) {
}
return data;
},
data: function(data, depth) {
while (data && depth--) {
data = data._parent;
}
return data;
},
merge: function(param, common) {
var ret = param || common;
+19 -16
View File
@@ -85,22 +85,6 @@ describe('data', function() {
equals("Hello undefined", result, "@foo as a parameter retrieves template data");
});
it("parameter data throws when using this scope references", function() {
var string = "{{#goodbyes}}{{text}} cruel {{@./name}}! {{/goodbyes}}";
shouldThrow(function() {
CompilerContext.compile(string);
}, Error);
});
it("parameter data throws when using parent scope references", function() {
var string = "{{#goodbyes}}{{text}} cruel {{@../name}}! {{/goodbyes}}";
shouldThrow(function() {
CompilerContext.compile(string);
}, Error);
});
it("parameter data throws when using complex scope references", function() {
var string = "{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}";
@@ -251,4 +235,23 @@ describe('data', function() {
equals('hello', result);
});
});
describe('nesting', function() {
it('the root context can be looked up via @root', function() {
var template = CompilerContext.compile('{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}');
var result = template({foo: 'hello'}, {
helpers: {
helper: function(options) {
var frame = Handlebars.createFrame(options.data);
frame.depth = options.data.depth + 1;
return options.fn(this, {data: frame});
}
},
data: {
depth: 0
}
});
equals('2 1 0', result);
});
});
});
+4
View File
@@ -21,6 +21,10 @@ describe('parser', function() {
equals(ast_for("{{@foo}}"), "{{ @ID:foo [] }}\n");
});
it('parses simple mustaches with data paths', function() {
equals(ast_for("{{@../foo}}"), "{{ @ID:foo [] }}\n");
});
it('parses mustaches with paths', function() {
equals(ast_for("{{foo/bar}}"), "{{ PATH:foo/bar [] }}\n");
});