eeb2173822d07bfa081669f74535398fb4a978b32b2eeac60b5d8fee1e831f8b55a867061de4517958a5b64e09dfac456f0a400ab306ce6ab79c7251bebcd1 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /* @flow */
  2. import { escape } from '../util'
  3. import {
  4. isDef,
  5. isUndef,
  6. extend
  7. } from 'shared/util'
  8. import {
  9. isBooleanAttr,
  10. isEnumeratedAttr,
  11. isFalsyAttrValue,
  12. convertEnumeratedValue
  13. } from 'web/util/attrs'
  14. import { isSSRUnsafeAttr } from 'web/server/util'
  15. export default function renderAttrs (node: VNodeWithData): string {
  16. let attrs = node.data.attrs
  17. let res = ''
  18. const opts = node.parent && node.parent.componentOptions
  19. if (isUndef(opts) || opts.Ctor.options.inheritAttrs !== false) {
  20. let parent = node.parent
  21. while (isDef(parent)) {
  22. if (isDef(parent.data) && isDef(parent.data.attrs)) {
  23. attrs = extend(extend({}, attrs), parent.data.attrs)
  24. }
  25. parent = parent.parent
  26. }
  27. }
  28. if (isUndef(attrs)) {
  29. return res
  30. }
  31. for (const key in attrs) {
  32. if (isSSRUnsafeAttr(key)) {
  33. continue
  34. }
  35. if (key === 'style') {
  36. // leave it to the style module
  37. continue
  38. }
  39. res += renderAttr(key, attrs[key])
  40. }
  41. return res
  42. }
  43. export function renderAttr (key: string, value: string): string {
  44. if (isBooleanAttr(key)) {
  45. if (!isFalsyAttrValue(value)) {
  46. return ` ${key}="${key}"`
  47. }
  48. } else if (isEnumeratedAttr(key)) {
  49. return ` ${key}="${escape(convertEnumeratedValue(key, value))}"`
  50. } else if (!isFalsyAttrValue(value)) {
  51. return ` ${key}="${escape(String(value))}"`
  52. }
  53. return ''
  54. }