attrs.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import {
  2. includeBooleanAttr,
  3. isSpecialBooleanAttr,
  4. makeMap,
  5. NOOP
  6. } from '@vue/shared'
  7. import {
  8. compatUtils,
  9. ComponentInternalInstance,
  10. DeprecationTypes
  11. } from '@vue/runtime-core'
  12. export const xlinkNS = 'http://www.w3.org/1999/xlink'
  13. export function patchAttr(
  14. el: Element,
  15. key: string,
  16. value: any,
  17. isSVG: boolean,
  18. instance?: ComponentInternalInstance | null
  19. ) {
  20. if (isSVG && key.startsWith('xlink:')) {
  21. if (value == null) {
  22. el.removeAttributeNS(xlinkNS, key.slice(6, key.length))
  23. } else {
  24. el.setAttributeNS(xlinkNS, key, value)
  25. }
  26. } else {
  27. if (__COMPAT__ && compatCoerceAttr(el, key, value, instance)) {
  28. return
  29. }
  30. // note we are only checking boolean attributes that don't have a
  31. // corresponding dom prop of the same name here.
  32. const isBoolean = isSpecialBooleanAttr(key)
  33. if (value == null || (isBoolean && !includeBooleanAttr(value))) {
  34. el.removeAttribute(key)
  35. } else {
  36. el.setAttribute(key, isBoolean ? '' : value)
  37. }
  38. }
  39. }
  40. // 2.x compat
  41. const isEnumeratedAttr = __COMPAT__
  42. ? /*#__PURE__*/ makeMap('contenteditable,draggable,spellcheck')
  43. : NOOP
  44. export function compatCoerceAttr(
  45. el: Element,
  46. key: string,
  47. value: unknown,
  48. instance: ComponentInternalInstance | null = null
  49. ): boolean {
  50. if (isEnumeratedAttr(key)) {
  51. const v2CocercedValue =
  52. value === null
  53. ? 'false'
  54. : typeof value !== 'boolean' && value !== undefined
  55. ? 'true'
  56. : null
  57. if (
  58. v2CocercedValue &&
  59. compatUtils.softAssertCompatEnabled(
  60. DeprecationTypes.ATTR_ENUMERATED_COERCION,
  61. instance,
  62. key,
  63. value,
  64. v2CocercedValue
  65. )
  66. ) {
  67. el.setAttribute(key, v2CocercedValue)
  68. return true
  69. }
  70. } else if (
  71. value === false &&
  72. !isSpecialBooleanAttr(key) &&
  73. compatUtils.softAssertCompatEnabled(
  74. DeprecationTypes.ATTR_FALSE_VALUE,
  75. instance,
  76. key
  77. )
  78. ) {
  79. el.removeAttribute(key)
  80. return true
  81. }
  82. return false
  83. }