index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import { genDirectives, genHandlers } from './directives/index'
  2. import { isReservedTag } from '../../runtime/util/dom'
  3. export function generate (ast) {
  4. const code = ast ? genElement(ast) : '__h__("div")'
  5. return `with (this) { return ${code}}`
  6. }
  7. function genElement (el) {
  8. if (el.for) {
  9. return genFor(el)
  10. } else if (el.if) {
  11. return genIf(el)
  12. } else if (el.tag === 'template' && !el.attrsMap.slot) {
  13. return genChildren(el)
  14. } else if (el.tag === 'render') {
  15. return genRender(el)
  16. } else if (el.tag === 'slot') {
  17. return genSlot(el)
  18. } else if (el.tag === 'component') {
  19. return genComponent(el)
  20. } else {
  21. // if the element is potentially a component,
  22. // wrap its children as a thunk.
  23. const children = genChildren(el, !isReservedTag(el.tag))
  24. return `__h__('${el.tag}', ${genData(el)}, ${children})`
  25. }
  26. }
  27. function genIf (el) {
  28. const exp = el.if
  29. el.if = false // avoid recursion
  30. return `(${exp}) ? ${genElement(el)} : ${genElse(el)}`
  31. }
  32. function genElse (el) {
  33. return el.elseBlock
  34. ? genElement(el.elseBlock)
  35. : 'null'
  36. }
  37. function genFor (el) {
  38. const exp = el.for
  39. const alias = el.alias
  40. const iterator = el.iterator
  41. el.for = false // avoid recursion
  42. return `(${exp})&&__renderList__((${exp}), ` +
  43. `function(${alias},$index${iterator ? `,${iterator}` : ''}){` +
  44. `return ${genElement(el)}` +
  45. '})'
  46. }
  47. function genData (el) {
  48. if (el.plain) {
  49. return el.svg ? '{svg:true}' : '{}'
  50. }
  51. let data = '{'
  52. // directives first.
  53. // directives may mutate the el's other properties before they are generated.
  54. if (el.directives) {
  55. let dirs = genDirectives(el)
  56. if (dirs) data += dirs + ','
  57. }
  58. // svg
  59. if (el.svg) {
  60. data += 'svg:true,'
  61. }
  62. // pre
  63. if (el.pre) {
  64. data += 'pre:true,'
  65. }
  66. // key
  67. if (el.key) {
  68. data += `key:${el.key},`
  69. }
  70. // slot names
  71. if (el.attrsMap.slot) {
  72. data += `slot:"${el.attrsMap.slot}",`
  73. }
  74. // class
  75. if (el.staticClass) {
  76. data += `staticClass:${el.staticClass},`
  77. }
  78. if (el.classBinding) {
  79. data += `class:${el.classBinding},`
  80. }
  81. // style
  82. if (el.styleBinding) {
  83. data += `style:${el.styleBinding},`
  84. }
  85. // props
  86. if (el.props) {
  87. data += `props:{${genProps(el.props)}},`
  88. }
  89. // attributes
  90. if (el.attrs) {
  91. data += `attrs:{${genProps(el.attrs)}},`
  92. }
  93. // hooks
  94. if (el.hooks) {
  95. data += `hook:{${genHooks(el.hooks)}},`
  96. }
  97. // event handlers
  98. if (el.events) {
  99. data += genHandlers(el.events)
  100. }
  101. return data.replace(/,$/, '') + '}'
  102. }
  103. function genChildren (el, asThunk) {
  104. if (!el.children.length) {
  105. return 'undefined'
  106. }
  107. const code = '[' + el.children.map(genNode).join(',') + ']'
  108. return asThunk
  109. ? `function(){return ${code}}`
  110. : code
  111. }
  112. function genNode (node) {
  113. if (node.tag) {
  114. return genElement(node)
  115. } else {
  116. return genText(node)
  117. }
  118. }
  119. function genText (text) {
  120. return text.expression
  121. ? `(${text.expression})`
  122. : JSON.stringify(text.text)
  123. }
  124. function genRender (el) {
  125. return `${el.renderMethod}(${el.renderArgs || 'null'},${genChildren(el)})`
  126. }
  127. function genSlot (el) {
  128. const name = el.slotName || '"default"'
  129. return `($slots[${name}] || ${genChildren(el)})`
  130. }
  131. function genComponent (el) {
  132. return `__h__(${el.component}, ${genData(el)}, ${genChildren(el, true)})`
  133. }
  134. function genProps (props) {
  135. let res = ''
  136. for (let i = 0; i < props.length; i++) {
  137. let prop = props[i]
  138. res += `"${prop.name}":${prop.value},`
  139. }
  140. return res.slice(0, -1)
  141. }
  142. function genHooks (hooks) {
  143. let res = ''
  144. for (let key in hooks) {
  145. res += `"${key}":function(n1,n2){${hooks[key].join(';')}},`
  146. }
  147. return res.slice(0, -1)
  148. }