Fix iteration over undefined values

Allow for iteration on undefined values, but special case undefined and null to prevent rendering errors when not running in strict mode.

Fixes #1093
This commit is contained in:
kpdecker
2015-09-23 21:17:57 -05:00
parent 08781798f5
commit fffb5a985f
3 changed files with 24 additions and 9 deletions
@@ -984,13 +984,14 @@ JavaScriptCompiler.prototype = {
setupHelper: function(paramSize, name, blockHelper) {
let params = [],
paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
let foundHelper = this.nameLookup('helpers', name, 'helper');
let foundHelper = this.nameLookup('helpers', name, 'helper'),
callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : {}`);
return {
params: params,
paramsInit: paramsInit,
name: foundHelper,
callParams: [this.contextName(0)].concat(params)
callParams: [callContext].concat(params)
};
},
+3 -7
View File
@@ -25,12 +25,6 @@ export default function(instance) {
}
function execIteration(field, index, last) {
// Don't iterate over undefined values since we can't execute blocks against them
// in non-strict (js) mode.
if (context[field] == null) {
return;
}
if (data) {
data.key = field;
data.index = index;
@@ -51,7 +45,9 @@ export default function(instance) {
if (context && typeof context === 'object') {
if (isArray(context)) {
for (let j = context.length; i < j; i++) {
execIteration(i, i, i === context.length - 1);
if (i in context) {
execIteration(i, i, i === context.length - 1);
}
}
} else {
let priorKey;
+18
View File
@@ -204,6 +204,24 @@ describe('Regressions', function() {
shouldCompileTo('{{#each array}}{{@index}}{{.}}{{/each}}', {array: array}, '1foo3bar');
});
it('GH-1093: Undefined helper context', function() {
var obj = {foo: undefined, bar: 'bat'};
var helpers = {
helper: function() {
// It's valid to execute a block against an undefined context, but
// helpers can not do so, so we expect to have an empty object here;
for (var name in this) {
if (this.hasOwnProperty(name)) {
return 'found';
}
}
return 'not';
}
};
shouldCompileTo('{{#each obj}}{{{helper}}}{{.}}{{/each}}', [{obj: obj}, helpers], 'notfoundbat');
});
it('should support multiple levels of inline partials', function() {
var string = '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}';
var partials = {