Current File : //usr/lib/node_modules/bower/lib/node_modules/handlebars/lib/handlebars/helpers/each.js |
import {appendContextPath, blockParams, createFrame, isArray, isFunction} from '../utils';
import Exception from '../exception';
export default function(instance) {
instance.registerHelper('each', function(context, options) {
if (!options) {
throw new Exception('Must pass iterator to #each');
}
let fn = options.fn,
inverse = options.inverse,
i = 0,
ret = '',
data,
contextPath;
if (options.data && options.ids) {
contextPath = appendContextPath(options.data.contextPath, options.ids[0]) + '.';
}
if (isFunction(context)) { context = context.call(this); }
if (options.data) {
data = createFrame(options.data);
}
function execIteration(field, index, last) {
if (data) {
data.key = field;
data.index = index;
data.first = index === 0;
data.last = !!last;
if (contextPath) {
data.contextPath = contextPath + field;
}
}
ret = ret + fn(context[field], {
data: data,
blockParams: blockParams([context[field], field], [contextPath + field, null])
});
}
if (context && typeof context === 'object') {
if (isArray(context)) {
for (let j = context.length; i < j; i++) {
if (i in context) {
execIteration(i, i, i === context.length - 1);
}
}
} else if (global.Symbol && context[global.Symbol.iterator]) {
const newContext = [];
const iterator = context[global.Symbol.iterator]();
for (let it = iterator.next(); !it.done; it = iterator.next()) {
newContext.push(it.value);
}
context = newContext;
for (let j = context.length; i < j; i++) {
execIteration(i, i, i === context.length - 1);
}
} else {
let priorKey;
Object.keys(context).forEach(key => {
// We're running the iterations one step out of sync so we can detect
// the last iteration without have to scan the object twice and create
// an itermediate keys array.
if (priorKey !== undefined) {
execIteration(priorKey, i - 1);
}
priorKey = key;
i++;
});
if (priorKey !== undefined) {
execIteration(priorKey, i - 1, true);
}
}
}
if (i === 0) {
ret = inverse(this);
}
return ret;
});
}