123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- 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]
- }
- }
|