95255dc148a18524db5d40bed6fb54552c6f4d05818c3a8ae6aaa925ae83015451ee088f581c411b2107c242b90d37b013d1f96ebc3751d47131a0ce44cc5c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* @flow */
  2. import {
  3. RAW,
  4. // INTERPOLATION,
  5. EXPRESSION
  6. } from './codegen'
  7. import {
  8. propsToAttrMap,
  9. isRenderableAttr
  10. } from 'web/server/util'
  11. import {
  12. isBooleanAttr,
  13. isEnumeratedAttr
  14. } from 'web/util/attrs'
  15. import type { StringSegment } from './codegen'
  16. import type { CodegenState } from 'compiler/codegen/index'
  17. const plainStringRE = /^"(?:[^"\\]|\\.)*"$|^'(?:[^'\\]|\\.)*'$/
  18. // let the model AST transform translate v-model into appropriate
  19. // props bindings
  20. export function applyModelTransform (el: ASTElement, state: CodegenState) {
  21. if (el.directives) {
  22. for (let i = 0; i < el.directives.length; i++) {
  23. const dir = el.directives[i]
  24. if (dir.name === 'model') {
  25. state.directives.model(el, dir, state.warn)
  26. // remove value for textarea as its converted to text
  27. if (el.tag === 'textarea' && el.props) {
  28. el.props = el.props.filter(p => p.name !== 'value')
  29. }
  30. break
  31. }
  32. }
  33. }
  34. }
  35. export function genAttrSegments (
  36. attrs: Array<ASTAttr>
  37. ): Array<StringSegment> {
  38. return attrs.map(({ name, value }) => genAttrSegment(name, value))
  39. }
  40. export function genDOMPropSegments (
  41. props: Array<ASTAttr>,
  42. attrs: ?Array<ASTAttr>
  43. ): Array<StringSegment> {
  44. const segments = []
  45. props.forEach(({ name, value }) => {
  46. name = propsToAttrMap[name] || name.toLowerCase()
  47. if (isRenderableAttr(name) &&
  48. !(attrs && attrs.some(a => a.name === name))
  49. ) {
  50. segments.push(genAttrSegment(name, value))
  51. }
  52. })
  53. return segments
  54. }
  55. function genAttrSegment (name: string, value: string): StringSegment {
  56. if (plainStringRE.test(value)) {
  57. // force double quote
  58. value = value.replace(/^'|'$/g, '"')
  59. // force enumerated attr to "true"
  60. if (isEnumeratedAttr(name) && value !== `"false"`) {
  61. value = `"true"`
  62. }
  63. return {
  64. type: RAW,
  65. value: isBooleanAttr(name)
  66. ? ` ${name}="${name}"`
  67. : value === '""'
  68. ? ` ${name}`
  69. : ` ${name}="${JSON.parse(value)}"`
  70. }
  71. } else {
  72. return {
  73. type: EXPRESSION,
  74. value: `_ssrAttr(${JSON.stringify(name)},${value})`
  75. }
  76. }
  77. }
  78. export function genClassSegments (
  79. staticClass: ?string,
  80. classBinding: ?string
  81. ): Array<StringSegment> {
  82. if (staticClass && !classBinding) {
  83. return [{ type: RAW, value: ` class="${JSON.parse(staticClass)}"` }]
  84. } else {
  85. return [{
  86. type: EXPRESSION,
  87. value: `_ssrClass(${staticClass || 'null'},${classBinding || 'null'})`
  88. }]
  89. }
  90. }
  91. export function genStyleSegments (
  92. staticStyle: ?string,
  93. parsedStaticStyle: ?string,
  94. styleBinding: ?string,
  95. vShowExpression: ?string
  96. ): Array<StringSegment> {
  97. if (staticStyle && !styleBinding && !vShowExpression) {
  98. return [{ type: RAW, value: ` style=${JSON.stringify(staticStyle)}` }]
  99. } else {
  100. return [{
  101. type: EXPRESSION,
  102. value: `_ssrStyle(${
  103. parsedStaticStyle || 'null'
  104. },${
  105. styleBinding || 'null'
  106. }, ${
  107. vShowExpression
  108. ? `{ display: (${vShowExpression}) ? '' : 'none' }`
  109. : 'null'
  110. })`
  111. }]
  112. }
  113. }