119 lines
3.5 KiB
JavaScript
119 lines
3.5 KiB
JavaScript
const {AST} = require('handlebars');
|
|
|
|
function getPartialName(node) {
|
|
return node.name.original;
|
|
}
|
|
|
|
function getNodeName(node) {
|
|
switch (node.type) {
|
|
case 'SubExpression':
|
|
case 'MustacheStatement':
|
|
case 'BlockStatement':
|
|
return `${node.path.data ? '@' : ''}${node.path.parts.join('.')}`;
|
|
|
|
case 'Program':
|
|
return;
|
|
|
|
case 'PathExpression':
|
|
default:
|
|
if (node.data){
|
|
return `@${node.parts.join('.')}`;
|
|
}
|
|
if (node.parts) {
|
|
return node.parts[0];
|
|
}
|
|
if (node.name.parts) {
|
|
return node.name.parts[0];
|
|
}
|
|
|
|
if (node.name.original) {
|
|
return node.name.original;
|
|
}
|
|
}
|
|
}
|
|
|
|
function _blockPrefixChar(node) {
|
|
return node.inverse && !node.program ? '^' : '#';
|
|
}
|
|
|
|
function logNode(node) {
|
|
const prefix = (node.inverse || node.program) ? _blockPrefixChar(node) : '';
|
|
|
|
return `{{${prefix}${getNodeName(node)}}}`;
|
|
}
|
|
|
|
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L429
|
|
function blockParamIndex(name, options) {
|
|
for (
|
|
let depth = 0, len = options.blockParams.length;
|
|
depth < len;
|
|
depth++
|
|
) {
|
|
let blockParams = options.blockParams[depth],
|
|
param = blockParams && blockParams.indexOf(name);
|
|
if (blockParams && param >= 0) {
|
|
return [depth, param];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L368
|
|
function classifyNode(sexpr, options = {knownHelpers: [], knownHelpersOnly: false, blockParams: []}) {
|
|
let isSimple = AST.helpers.simpleId(sexpr.path);
|
|
|
|
let isBlockParam = isSimple && !!blockParamIndex(sexpr.path.parts[0], options);
|
|
|
|
// a mustache is an eligible helper if:
|
|
// * its id is simple (a single part, not `this` or `..`)
|
|
let isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr);
|
|
|
|
// if a mustache is an eligible helper but not a definite
|
|
// helper, it is ambiguous, and will be resolved in a later
|
|
// pass or at runtime.
|
|
let isEligible = !isBlockParam && (isHelper || isSimple);
|
|
|
|
// if ambiguous, we can possibly resolve the ambiguity now
|
|
// An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
|
|
if (isEligible && !isHelper) {
|
|
let name = sexpr.path.parts[0];
|
|
if (options.knownHelpers.includes(name)) {
|
|
isHelper = true;
|
|
} else if (options.knownHelpersOnly) {
|
|
isEligible = false;
|
|
}
|
|
}
|
|
|
|
if (isHelper) {
|
|
return 'helper';
|
|
} else if (isEligible) {
|
|
return 'ambiguous';
|
|
} else {
|
|
return 'simple';
|
|
}
|
|
}
|
|
|
|
// Extracted from https://github.com/handlebars-lang/handlebars.js/blob/6790c080c641ef2b44e663800e1794fae180977a/lib/handlebars/compiler/compiler.js#L522
|
|
function transformLiteralToPath(sexpr) {
|
|
if (!sexpr.path.parts) {
|
|
let literal = sexpr.path;
|
|
// Casting to string here to make false and 0 literal values play nicely with the rest
|
|
// of the system.
|
|
sexpr.path = {
|
|
type: 'PathExpression',
|
|
data: false,
|
|
depth: 0,
|
|
parts: [literal.original + ''],
|
|
original: literal.original + '',
|
|
loc: literal.loc
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
getNodeName,
|
|
getPartialName,
|
|
logNode,
|
|
classifyNode,
|
|
transformLiteralToPath
|
|
};
|