Add support for depthed resolution of data fields
This commit is contained in:
@@ -223,5 +223,7 @@ export var logger = {
|
|||||||
export function log(level, obj) { logger.log(level, obj); }
|
export function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
export var createFrame = function(object) {
|
export var createFrame = function(object) {
|
||||||
return Utils.extend({}, object);
|
var frame = Utils.extend({}, object);
|
||||||
|
frame._parent = object;
|
||||||
|
return frame;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -310,11 +310,7 @@ Compiler.prototype = {
|
|||||||
|
|
||||||
DATA: function(data) {
|
DATA: function(data) {
|
||||||
this.options.data = true;
|
this.options.data = true;
|
||||||
if (data.id.isScoped || data.id.depth) {
|
this.opcode('lookupData', data.id.depth);
|
||||||
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.opcode('lookupData');
|
|
||||||
var parts = data.id.parts;
|
var parts = data.id.parts;
|
||||||
for(var i=0, l=parts.length; i<l; i++) {
|
for(var i=0, l=parts.length; i<l; i++) {
|
||||||
this.opcode('lookup', parts[i]);
|
this.opcode('lookup', parts[i]);
|
||||||
|
|||||||
@@ -403,8 +403,12 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after: data, ...
|
// On stack, after: data, ...
|
||||||
//
|
//
|
||||||
// Push the data lookup operator
|
// Push the data lookup operator
|
||||||
lookupData: function() {
|
lookupData: function(depth) {
|
||||||
this.pushStackLiteral('data');
|
if (!depth) {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral('this.data(data, ' + depth + ')');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// [pushStringParam]
|
// [pushStringParam]
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ export function template(templateSpec, env) {
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
data: function(data, depth) {
|
||||||
|
while (data && depth--) {
|
||||||
|
data = data._parent;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
merge: function(param, common) {
|
merge: function(param, common) {
|
||||||
var ret = param || common;
|
var ret = param || common;
|
||||||
|
|
||||||
|
|||||||
+19
-16
@@ -85,22 +85,6 @@ describe('data', function() {
|
|||||||
equals("Hello undefined", result, "@foo as a parameter retrieves template data");
|
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() {
|
it("parameter data throws when using complex scope references", function() {
|
||||||
var string = "{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}";
|
var string = "{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}";
|
||||||
|
|
||||||
@@ -251,4 +235,23 @@ describe('data', function() {
|
|||||||
equals('hello', result);
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ describe('parser', function() {
|
|||||||
equals(ast_for("{{@foo}}"), "{{ @ID:foo [] }}\n");
|
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() {
|
it('parses mustaches with paths', function() {
|
||||||
equals(ast_for("{{foo/bar}}"), "{{ PATH:foo/bar [] }}\n");
|
equals(ast_for("{{foo/bar}}"), "{{ PATH:foo/bar [] }}\n");
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user