@@ -77,10 +77,12 @@ JavaScriptCompiler.prototype = {
|
||||
this.hashes = [];
|
||||
this.compileStack = [];
|
||||
this.inlineStack = [];
|
||||
this.blockParams = [];
|
||||
|
||||
this.compileChildren(environment, options);
|
||||
|
||||
this.useDepths = this.useDepths || environment.useDepths || this.options.compat;
|
||||
this.useBlockParams = this.useBlockParams || environment.useBlockParams;
|
||||
|
||||
var opcodes = environment.opcodes,
|
||||
opcode,
|
||||
@@ -127,6 +129,9 @@ JavaScriptCompiler.prototype = {
|
||||
if (this.useDepths) {
|
||||
ret.useDepths = true;
|
||||
}
|
||||
if (this.useBlockParams) {
|
||||
ret.useBlockParams = true;
|
||||
}
|
||||
if (this.options.compat) {
|
||||
ret.compat = true;
|
||||
}
|
||||
@@ -186,6 +191,9 @@ JavaScriptCompiler.prototype = {
|
||||
|
||||
var params = ["depth0", "helpers", "partials", "data"];
|
||||
|
||||
if (this.useBlockParams || this.useDepths) {
|
||||
params.push('blockParams');
|
||||
}
|
||||
if (this.useDepths) {
|
||||
params.push('depths');
|
||||
}
|
||||
@@ -385,9 +393,7 @@ JavaScriptCompiler.prototype = {
|
||||
// Looks up the value of `name` on the current context and pushes
|
||||
// it onto the stack.
|
||||
lookupOnContext: function(parts, falsy, scoped) {
|
||||
/*jshint -W083 */
|
||||
var i = 0,
|
||||
len = parts.length;
|
||||
var i = 0;
|
||||
|
||||
if (!scoped && this.options.compat && !this.lastContext) {
|
||||
// The depthed query is expected to handle the undefined logic for the root level that
|
||||
@@ -397,19 +403,21 @@ JavaScriptCompiler.prototype = {
|
||||
this.pushContext();
|
||||
}
|
||||
|
||||
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 if the context (falsy flag)
|
||||
// needs to have the special handling for these values.
|
||||
if (!falsy) {
|
||||
return [' != null ? ', lookup, ' : ', current];
|
||||
} else {
|
||||
// Otherwise we can use generic falsy handling
|
||||
return [' && ', lookup];
|
||||
}
|
||||
});
|
||||
}
|
||||
this.resolvePath('context', parts, i, falsy);
|
||||
},
|
||||
|
||||
// [lookupBlockParam]
|
||||
//
|
||||
// On stack, before: ...
|
||||
// On stack, after: blockParam[name], ...
|
||||
//
|
||||
// Looks up the value of `parts` on the given block param and pushes
|
||||
// it onto the stack.
|
||||
lookupBlockParam: function(blockParamId, parts) {
|
||||
this.useBlockParams = true;
|
||||
|
||||
this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
|
||||
this.resolvePath('context', parts, 1);
|
||||
},
|
||||
|
||||
// [lookupData]
|
||||
@@ -426,9 +434,23 @@ JavaScriptCompiler.prototype = {
|
||||
this.pushStackLiteral('this.data(data, ' + depth + ')');
|
||||
}
|
||||
|
||||
for (var i = 0, len = parts.length; i < len; i++) {
|
||||
this.resolvePath('data', parts, 0, true);
|
||||
},
|
||||
|
||||
resolvePath: function(type, parts, i, falsy) {
|
||||
/*jshint -W083 */
|
||||
var len = parts.length;
|
||||
for (; i < len; i++) {
|
||||
this.replaceStack(function(current) {
|
||||
return [' && ', this.nameLookup(current, parts[i], 'data')];
|
||||
var lookup = this.nameLookup(current, parts[i], type);
|
||||
// We want to ensure that zero and false are handled properly if the context (falsy flag)
|
||||
// needs to have the special handling for these values.
|
||||
if (!falsy) {
|
||||
return [' != null ? ', lookup, ' : ', current];
|
||||
} else {
|
||||
// Otherwise we can use generic falsy handling
|
||||
return [' && ', lookup];
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -661,8 +683,12 @@ JavaScriptCompiler.prototype = {
|
||||
hash.values[key] = value;
|
||||
},
|
||||
|
||||
pushId: function(type, name) {
|
||||
if (type === 'PathExpression') {
|
||||
pushId: function(type, name, child) {
|
||||
if (type === 'BlockParam') {
|
||||
this.pushStackLiteral(
|
||||
'blockParams[' + name[0] + '].path[' + name[1] + ']'
|
||||
+ (child ? ' + ' + JSON.stringify('.' + child) : ''));
|
||||
} else if (type === 'PathExpression') {
|
||||
this.pushString(name);
|
||||
} else if (type === 'SubExpression') {
|
||||
this.pushStackLiteral('true');
|
||||
@@ -693,11 +719,13 @@ JavaScriptCompiler.prototype = {
|
||||
this.context.environments[index] = child;
|
||||
|
||||
this.useDepths = this.useDepths || compiler.useDepths;
|
||||
this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
|
||||
} else {
|
||||
child.index = index;
|
||||
child.name = 'program' + index;
|
||||
|
||||
this.useDepths = this.useDepths || child.useDepths;
|
||||
this.useBlockParams = this.useBlockParams || child.useBlockParams;
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -712,11 +740,12 @@ JavaScriptCompiler.prototype = {
|
||||
|
||||
programExpression: function(guid) {
|
||||
var child = this.environment.children[guid],
|
||||
useDepths = this.useDepths;
|
||||
programParams = [child.index, 'data', child.blockParams];
|
||||
|
||||
var programParams = [child.index, 'data'];
|
||||
|
||||
if (useDepths) {
|
||||
if (this.useBlockParams || this.useDepths) {
|
||||
programParams.push('blockParams');
|
||||
}
|
||||
if (this.useDepths) {
|
||||
programParams.push('depths');
|
||||
}
|
||||
|
||||
@@ -943,7 +972,10 @@ JavaScriptCompiler.prototype = {
|
||||
}
|
||||
|
||||
if (this.options.data) {
|
||||
options.data = "data";
|
||||
options.data = 'data';
|
||||
}
|
||||
if (this.useBlockParams) {
|
||||
options.blockParams = 'blockParams';
|
||||
}
|
||||
return options;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user