1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- module.exports = class Compiler {
- constructor(tree, context) {
- this.tree = tree
- this.context = context
- this.result = ''
- }
-
- compile() {
- const selfClosingTags = [
- 'area',
- 'base',
- 'br',
- 'col',
- 'command',
- 'embed',
- 'hr',
- 'img',
- 'input',
- 'keygen',
- 'link',
- 'menuitem',
- 'meta',
- 'param',
- 'source',
- 'track',
- 'wbr',
- ]
-
- this.tree.forEach(node => {
- if (node.type === 'functionCall') {
- const attributes = node.args.map(
- arg =>
- `${arg.attributeName}="${this.compileAttribute(
- arg.attributeValue,
- )}"`,
- )
- const compiler = new Compiler(node.subtree, this.context)
- const content = compiler.compile()
- this.result += `<${node.functionName}${
- attributes.length ? ' ' : ''
- }${attributes.join(' ')}>`
-
- if (content) {
- this.result += content
- }
-
- if (!selfClosingTags.includes(node.functionName)) {
- this.result += `</${node.functionName}>`
- }
- } else if (node.type === 'string') {
- this.result += node.content
- } else if (node.type === 'identifier') {
- this.result += this.lookup(node.name)
- } else if (node.type === 'each') {
- const symbol = node.symbol.value
- const subject = this.lookup(node.subject.name)
- subject.forEach(item => {
- let context = {}
- context[symbol] = item
- const compiler = new Compiler([node.body], context)
- this.result += compiler.compile()
- })
- }
- })
-
- return this.result.trim()
- }
-
- compileAttribute(attribute) {
- if (attribute.type === 'string') {
- return attribute.content
- } else if (attribute.type === 'identifier') {
- return this.lookup(attribute.name)
- }
- }
-
- lookup(name) {
- return this.context[name]
- }
- }
|