nodeOps.spec.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { defineComponent, h, nextTick, ref } from 'vue'
  2. import { mathmlNS, nodeOps, svgNS } from '../src/nodeOps'
  3. import { render } from '@vue/runtime-dom'
  4. describe('runtime-dom: node-ops', () => {
  5. test("the <select>'s multiple attr should be set in createElement", () => {
  6. const el = nodeOps.createElement('select', undefined, undefined, {
  7. multiple: '',
  8. }) as HTMLSelectElement
  9. const option1 = nodeOps.createElement('option') as HTMLOptionElement
  10. const option2 = nodeOps.createElement('option') as HTMLOptionElement
  11. option1.selected = true
  12. option2.selected = true
  13. nodeOps.insert(option1, el)
  14. nodeOps.insert(option2, el)
  15. expect(el.multiple).toBe(true)
  16. expect(option1.selected).toBe(true)
  17. expect(option2.selected).toBe(true)
  18. })
  19. describe('insertStaticContent', () => {
  20. test('fresh insertion', () => {
  21. const content = `<div>one</div><div>two</div>three`
  22. const parent = document.createElement('div')
  23. const nodes = nodeOps.insertStaticContent!(
  24. content,
  25. parent,
  26. null,
  27. undefined,
  28. )
  29. expect(parent.innerHTML).toBe(content)
  30. expect(nodes[0]).toBe(parent.firstChild)
  31. expect(nodes[1]).toBe(parent.lastChild)
  32. })
  33. test('fresh insertion with anchor', () => {
  34. const content = `<div>one</div><div>two</div>three`
  35. const existing = `<div>existing</div>`
  36. const parent = document.createElement('div')
  37. parent.innerHTML = existing
  38. const anchor = parent.firstChild
  39. const nodes = nodeOps.insertStaticContent!(
  40. content,
  41. parent,
  42. anchor,
  43. undefined,
  44. )
  45. expect(parent.innerHTML).toBe(content + existing)
  46. expect(nodes[0]).toBe(parent.firstChild)
  47. expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
  48. })
  49. test('fresh insertion as svg', () => {
  50. const content = `<text>hello</text><circle cx="100" cy="100" r="80"></circle>`
  51. const parent = document.createElementNS(svgNS, 'svg')
  52. const [first, last] = nodeOps.insertStaticContent!(
  53. content,
  54. parent,
  55. null,
  56. 'svg',
  57. )
  58. expect(parent.innerHTML).toBe(content)
  59. expect(first).toBe(parent.firstChild)
  60. expect(last).toBe(parent.lastChild)
  61. expect((first as Element).namespaceURI).toMatch('svg')
  62. expect((last as Element).namespaceURI).toMatch('svg')
  63. })
  64. test('fresh insertion as svg, with anchor', () => {
  65. const content = `<text>hello</text><circle cx="100" cy="100" r="80"></circle>`
  66. const existing = `<path></path>`
  67. const parent = document.createElementNS(svgNS, 'svg')
  68. parent.innerHTML = existing
  69. const anchor = parent.firstChild
  70. const [first, last] = nodeOps.insertStaticContent!(
  71. content,
  72. parent,
  73. anchor,
  74. 'svg',
  75. )
  76. expect(parent.innerHTML).toBe(content + existing)
  77. expect(first).toBe(parent.firstChild)
  78. expect(last).toBe(parent.childNodes[parent.childNodes.length - 2])
  79. expect((first as Element).namespaceURI).toMatch('svg')
  80. expect((last as Element).namespaceURI).toMatch('svg')
  81. })
  82. test('cached insertion', () => {
  83. const content = `<div>one</div><div>two</div>three`
  84. const existing = `<div>existing</div>`
  85. const parent = document.createElement('div')
  86. parent.innerHTML = existing
  87. const anchor = parent.firstChild
  88. const cached = document.createElement('div')
  89. cached.innerHTML = content
  90. const nodes = nodeOps.insertStaticContent!(
  91. content,
  92. parent,
  93. anchor,
  94. undefined,
  95. cached.firstChild,
  96. cached.lastChild,
  97. )
  98. expect(parent.innerHTML).toBe(content + existing)
  99. expect(nodes[0]).toBe(parent.firstChild)
  100. expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
  101. })
  102. test('The math elements should keep their MathML namespace', async () => {
  103. let root = document.createElement('div') as any
  104. let countRef: any
  105. const component = defineComponent({
  106. data() {
  107. return { value: 0 }
  108. },
  109. setup() {
  110. const count = ref(0)
  111. countRef = count
  112. return {
  113. count,
  114. }
  115. },
  116. template: `
  117. <div>
  118. <math>
  119. <mrow class="bar" v-if="count % 2">Bar</mrow>
  120. <msup class="foo" v-else>Foo</msup>
  121. </math>
  122. </div>
  123. `,
  124. })
  125. render(h(component), root)
  126. const foo = root.querySelector('.foo')
  127. expect(foo.namespaceURI).toBe(mathmlNS)
  128. countRef.value++
  129. await nextTick()
  130. const bar = root.querySelector('.bar')
  131. expect(bar.namespaceURI).toBe(mathmlNS)
  132. })
  133. })
  134. })