marko/compiler/ast/TemplateRoot.js

171 lines
5.0 KiB
JavaScript

'use strict';
var Node = require('./Node');
function createVarsArray(vars) {
return Object.keys(vars).map(function(varName) {
var varInit = vars[varName];
return {
id: varName,
init: varInit
};
});
}
function _buildVersionComment(builder, context) {
const version = context.compilerVersion;
const compilerType = context.compilerType;
return builder.comment(`Compiled using ${compilerType}@${version} - DO NOT EDIT`);
}
class TemplateRoot extends Node {
constructor(def) {
super('TemplateRoot');
this.body = this.makeContainer(def.body);
this.extraRenderParams = null;
this.generateAssignRenderCode = null;
}
addRenderFunctionParam(id) {
if (!this.extraRenderParams) {
this.extraRenderParams = [];
}
this.extraRenderParams.push(id);
}
generateCode(codegen) {
var context = codegen.context;
this.body = codegen.generateCode(this.body);
context.optimize(this);
var body = this.body;
var builder = codegen.builder;
let renderStatements = [
builder.var('data', builder.identifier('input'))
];
var vars = createVarsArray(context.getVars());
if (vars.length) {
renderStatements.push(builder.vars(vars));
}
renderStatements = renderStatements.concat(body);
if (context.inline) {
var createInlineMarkoTemplateVar = context.helper('createInlineTemplate');
return builder.functionCall(
createInlineMarkoTemplateVar,
[
builder.identifier('__filename'),
builder.functionDeclaration(
null,
[
builder.identifier('input'),
builder.identifierOut()
],
renderStatements)
]);
} else {
var isBrowser = context.options.browser;
var createArgs = isBrowser ?
[] :
[ builder.identifier('__filename') ];
let templateDeclaration = builder.variableDeclarator('marko_template',
builder.assignment(
builder.moduleExports(),
builder.functionCall(
builder.memberExpression(
builder.require(
builder.literal(context.getModuleRuntimeTarget())
),
builder.identifier('t')
),
createArgs
)
)
);
let body = [];
if (context.writeVersionComment) {
body.push(_buildVersionComment(builder, context));
}
body.push(builder.literal('use strict'));
let staticNodes = context.getStaticNodes([templateDeclaration]);
if (staticNodes.length) {
body = body.concat(staticNodes);
}
var renderParams = [builder.identifier('input'), builder.identifierOut()];
if (this.extraRenderParams) {
renderParams = renderParams.concat(this.extraRenderParams);
}
let renderFunction = builder.functionDeclaration(
'render',
renderParams,
renderStatements);
body = body.concat([
renderFunction,
]);
var assignRenderCode;
let templateVar = builder.identifier('marko_template');
let renderFunctionVar = builder.identifier('render');
let templateRendererMember = builder.memberExpression(
builder.identifier('marko_template'),
builder.identifier('_'));
if (this.generateAssignRenderCode) {
var eventArgs = {
context,
templateVar,
templateRendererMember,
renderFunctionVar
};
assignRenderCode = this.generateAssignRenderCode(eventArgs);
} else {
assignRenderCode = builder.assignment(
templateRendererMember,
renderFunctionVar);
}
if (assignRenderCode) {
body = body.concat(assignRenderCode);
}
if (context.useMeta && context.meta) {
body.push(builder.assignment(
builder.memberExpression(builder.identifier('marko_template'), builder.identifier('meta')),
builder.literal(context.meta)));
}
return builder.program(body);
}
}
toJSON(prettyPrinter) {
return {
type: this.type,
body: this.body
};
}
walk(walker) {
this.body = walker.walk(this.body);
}
}
module.exports = TemplateRoot;