template.ts 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import type { CodegenContext } from '../generate'
  2. import { DynamicFlag, type IRDynamicInfo } from '../ir'
  3. import { genDirectivesForElement } from './directive'
  4. import { type CodeFragment, NEWLINE, buildCodeFragment, genCall } from './utils'
  5. export function genTemplates(
  6. templates: string[],
  7. { vaporHelper }: CodegenContext,
  8. ) {
  9. return templates
  10. .map(
  11. (template, i) =>
  12. `const t${i} = ${vaporHelper('template')}(${JSON.stringify(template)})\n`,
  13. )
  14. .join('')
  15. }
  16. export function genChildren(
  17. dynamic: IRDynamicInfo,
  18. context: CodegenContext,
  19. from: number,
  20. paths: number[] = [],
  21. ): CodeFragment[] {
  22. const { vaporHelper } = context
  23. const [frag, push] = buildCodeFragment()
  24. let offset = 0
  25. const { children, id, template } = dynamic
  26. if (id !== undefined && template !== undefined) {
  27. push(NEWLINE, `const n${id} = t${template}()`)
  28. push(...genDirectivesForElement(id, context))
  29. }
  30. let prev: [id: number, elementIndex: number] | undefined
  31. for (const [index, child] of children.entries()) {
  32. if (child.flags & DynamicFlag.NON_TEMPLATE) {
  33. offset--
  34. }
  35. const id =
  36. child.flags & DynamicFlag.REFERENCED
  37. ? child.flags & DynamicFlag.INSERT
  38. ? child.anchor
  39. : child.id
  40. : undefined
  41. const elementIndex = Number(index) + offset
  42. const newPaths = [...paths, elementIndex]
  43. if (id === undefined) {
  44. push(...genChildren(child, context, from, newPaths))
  45. continue
  46. }
  47. push(NEWLINE, `const n${id} = `)
  48. if (prev) {
  49. const offset = elementIndex - prev[1]
  50. if (offset === 1) {
  51. push(`n${prev[0]}.nextSibling`)
  52. } else {
  53. push(...genCall(vaporHelper('next'), `n${prev[0]}`, String(offset)))
  54. }
  55. } else {
  56. if (newPaths.length === 1 && newPaths[0] === 0) {
  57. push(`n${from}.firstChild`)
  58. } else {
  59. push(
  60. ...genCall(
  61. vaporHelper('children'),
  62. `n${from}`,
  63. ...newPaths.map(String),
  64. ),
  65. )
  66. }
  67. }
  68. push(...genDirectivesForElement(id, context))
  69. prev = [id, elementIndex]
  70. push(...genChildren(child, context, id, []))
  71. }
  72. return frag
  73. }