patchAttrs.spec.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { patchProp } from '../src/patchProp'
  2. import { xlinkNS } from '../src/modules/attrs'
  3. describe('runtime-dom: attrs patching', () => {
  4. test('xlink attributes', () => {
  5. const el = document.createElementNS('http://www.w3.org/2000/svg', 'use')
  6. patchProp(el, 'xlink:href', null, 'a', 'svg')
  7. expect(el.getAttributeNS(xlinkNS, 'href')).toBe('a')
  8. patchProp(el, 'xlink:href', 'a', null, 'svg')
  9. expect(el.getAttributeNS(xlinkNS, 'href')).toBe(null)
  10. })
  11. test('textContent attributes /w svg', () => {
  12. const el = document.createElementNS('http://www.w3.org/2000/svg', 'use')
  13. patchProp(el, 'textContent', null, 'foo', 'svg')
  14. expect(el.attributes.length).toBe(0)
  15. expect(el.innerHTML).toBe('foo')
  16. })
  17. test('boolean attributes', () => {
  18. const el = document.createElement('input')
  19. patchProp(el, 'readonly', null, true)
  20. expect(el.getAttribute('readonly')).toBe('')
  21. patchProp(el, 'readonly', true, false)
  22. expect(el.getAttribute('readonly')).toBe(null)
  23. patchProp(el, 'readonly', false, '')
  24. expect(el.getAttribute('readonly')).toBe('')
  25. patchProp(el, 'readonly', '', 0)
  26. expect(el.getAttribute('readonly')).toBe(null)
  27. patchProp(el, 'readonly', 0, '0')
  28. expect(el.getAttribute('readonly')).toBe('')
  29. patchProp(el, 'readonly', '0', false)
  30. expect(el.getAttribute('readonly')).toBe(null)
  31. patchProp(el, 'readonly', false, 1)
  32. expect(el.getAttribute('readonly')).toBe('')
  33. patchProp(el, 'readonly', 1, undefined)
  34. expect(el.getAttribute('readonly')).toBe(null)
  35. })
  36. test('attributes', () => {
  37. const el = document.createElement('div')
  38. patchProp(el, 'foo', null, 'a')
  39. expect(el.getAttribute('foo')).toBe('a')
  40. patchProp(el, 'foo', 'a', null)
  41. expect(el.getAttribute('foo')).toBe(null)
  42. })
  43. // #949
  44. test('onxxx but non-listener attributes', () => {
  45. const el = document.createElement('div')
  46. patchProp(el, 'onwards', null, 'a')
  47. expect(el.getAttribute('onwards')).toBe('a')
  48. patchProp(el, 'onwards', 'a', null)
  49. expect(el.getAttribute('onwards')).toBe(null)
  50. })
  51. // #10597
  52. test('should allow setting attribute to symbol', () => {
  53. const el = document.createElement('div')
  54. const symbol = Symbol('foo')
  55. patchProp(el, 'foo', null, symbol)
  56. expect(el.getAttribute('foo')).toBe(symbol.toString())
  57. })
  58. // #10598
  59. test('should allow setting value to symbol', () => {
  60. const el = document.createElement('input')
  61. const symbol = Symbol('foo')
  62. patchProp(el, 'value', null, symbol)
  63. expect(el.value).toBe(symbol.toString())
  64. })
  65. // #11177
  66. test('should allow setting value to object, leaving stringification to the element/browser', () => {
  67. // normal behavior
  68. const el = document.createElement('div')
  69. const obj = { toString: () => 'foo' }
  70. patchProp(el, 'data-test', null, obj)
  71. expect(el.dataset.test).toBe('foo')
  72. const el2 = document.createElement('div')
  73. let testvalue: null | typeof obj = null
  74. // simulating a web component that implements its own setAttribute handler
  75. el2.setAttribute = (name, value) => {
  76. testvalue = value
  77. }
  78. patchProp(el2, 'data-test', null, obj)
  79. expect(el2.dataset.test).toBe(undefined)
  80. expect(testvalue).toBe(obj)
  81. })
  82. // #13946
  83. test('sandbox should be handled as attribute even if property exists', () => {
  84. const iframe = document.createElement('iframe') as any
  85. let propSetCount = 0
  86. // simulate sandbox property in jsdom environment
  87. Object.defineProperty(iframe, 'sandbox', {
  88. configurable: true,
  89. enumerable: true,
  90. get() {
  91. return this._sandbox
  92. },
  93. set(v) {
  94. propSetCount++
  95. this._sandbox = v
  96. },
  97. })
  98. patchProp(iframe, 'sandbox', null, 'allow-scripts')
  99. expect(iframe.getAttribute('sandbox')).toBe('allow-scripts')
  100. expect(propSetCount).toBe(0)
  101. patchProp(iframe, 'sandbox', 'allow-scripts', null)
  102. expect(iframe.hasAttribute('sandbox')).toBe(false)
  103. expect(iframe.getAttribute('sandbox')).toBe(null)
  104. expect(propSetCount).toBe(0)
  105. patchProp(iframe, 'sandbox', null, '')
  106. expect(iframe.getAttribute('sandbox')).toBe('')
  107. expect(iframe.hasAttribute('sandbox')).toBe(true)
  108. expect(propSetCount).toBe(0)
  109. delete iframe.sandbox
  110. })
  111. })