template_spec.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. var templateParser = require('src/parsers/template')
  2. var parse = templateParser.parseTemplate
  3. var testString = '<div>hello</div><p class="test">world</p>'
  4. describe('Template Parser', function () {
  5. it('should return same if argument is already a fragment', function () {
  6. var frag = document.createDocumentFragment()
  7. var res = parse(frag)
  8. expect(res).toBe(frag)
  9. })
  10. it('should parse if argument is a template string', function () {
  11. var res = parse(testString)
  12. expect(res.nodeType).toBe(11)
  13. expect(res.childNodes.length).toBe(2)
  14. expect(res.querySelector('.test').textContent).toBe('world')
  15. })
  16. it('should work if the template string doesn\'t contain tags', function () {
  17. var res = parse('hello!')
  18. expect(res.nodeType).toBe(11)
  19. expect(res.childNodes.length).toBe(1)
  20. expect(res.firstChild.nodeType).toBe(3) // Text node
  21. })
  22. it('should work if the template string doesn\'t contain tags but contains comments', function () {
  23. var res = parse('<!-- yo -->hello<!-- yo -->')
  24. expect(res.childNodes.length).toBe(1)
  25. expect(res.firstChild.nodeType).toBe(3) // text node
  26. expect(res.firstChild.nodeValue).toBe('hello')
  27. })
  28. it('should handle string that contains html entities', function () {
  29. var res = parse('foo&lt;bar')
  30. expect(res.nodeType).toBe(11)
  31. expect(res.childNodes.length).toBe(1)
  32. expect(res.firstChild.nodeValue).toBe('foo<bar')
  33. // #1330
  34. res = parse('hello &#x2F; hello')
  35. expect(res.nodeType).toBe(11)
  36. expect(res.childNodes.length).toBe(1)
  37. expect(res.firstChild.nodeValue).toBe('hello / hello')
  38. // #2021
  39. res = parse('&#xe604;')
  40. expect(res.nodeType).toBe(11)
  41. expect(res.childNodes.length).toBe(1)
  42. expect(res.firstChild.nodeValue).toBe('')
  43. })
  44. it('should parse innerHTML if argument is a template node', function () {
  45. var templateNode = document.createElement('template')
  46. templateNode.innerHTML = testString
  47. var res = parse(templateNode)
  48. expect(res.nodeType).toBe(11)
  49. expect(res.childNodes.length).toBe(2)
  50. expect(res.querySelector('.test').textContent).toBe('world')
  51. })
  52. it('should parse textContent if argument is a script node', function () {
  53. var node = document.createElement('script')
  54. node.textContent = testString
  55. var res = parse(node)
  56. expect(res.nodeType).toBe(11)
  57. expect(res.childNodes.length).toBe(2)
  58. expect(res.querySelector('.test').textContent).toBe('world')
  59. })
  60. it('should parse innerHTML if argument is a normal node', function () {
  61. var node = document.createElement('div')
  62. node.innerHTML = testString
  63. var res = parse(node)
  64. expect(res.nodeType).toBe(11)
  65. expect(res.childNodes.length).toBe(2)
  66. expect(res.querySelector('.test').textContent).toBe('world')
  67. })
  68. it('should retrieve and parse if argument is an id selector', function () {
  69. var node = document.createElement('script')
  70. node.setAttribute('id', 'template-test')
  71. node.setAttribute('type', 'x/template')
  72. node.textContent = testString
  73. document.head.appendChild(node)
  74. var res = parse('#template-test')
  75. expect(res.nodeType).toBe(11)
  76. expect(res.childNodes.length).toBe(2)
  77. expect(res.querySelector('.test').textContent).toBe('world')
  78. document.head.removeChild(node)
  79. })
  80. it('should work for table elements', function () {
  81. var res = parse('<td>hello</td>')
  82. expect(res.nodeType).toBe(11)
  83. expect(res.childNodes.length).toBe(1)
  84. expect(res.firstChild.tagName).toBe('TD')
  85. expect(res.firstChild.textContent).toBe('hello')
  86. })
  87. it('should work for option elements', function () {
  88. var res = parse('<option>hello</option>')
  89. expect(res.nodeType).toBe(11)
  90. expect(res.childNodes.length).toBe(1)
  91. expect(res.firstChild.tagName).toBe('OPTION')
  92. expect(res.firstChild.textContent).toBe('hello')
  93. })
  94. it('should work for svg elements', function () {
  95. var res = parse('<circle></circle>')
  96. expect(res.nodeType).toBe(11)
  97. expect(res.childNodes.length).toBe(1)
  98. // SVG tagNames should be lowercase because they are XML nodes not HTML
  99. expect(res.firstChild.tagName).toBe('circle')
  100. expect(res.firstChild.namespaceURI).toBe('http://www.w3.org/2000/svg')
  101. })
  102. it('should cache template strings', function () {
  103. var res1 = parse(testString)
  104. var res2 = parse(testString)
  105. expect(res1).toBe(res2)
  106. })
  107. it('should clone', function () {
  108. var res1 = parse(testString, true)
  109. var res2 = parse(testString, true)
  110. expect(res1).not.toBe(res2)
  111. })
  112. it('should cache id selectors', function () {
  113. var node = document.createElement('script')
  114. node.setAttribute('id', 'template-test')
  115. node.setAttribute('type', 'x/template')
  116. node.textContent = '<div>never seen before content</div>'
  117. document.head.appendChild(node)
  118. var res1 = parse('#template-test')
  119. var res2 = parse('#template-test')
  120. expect(res1).toBe(res2)
  121. document.head.removeChild(node)
  122. })
  123. it('should be able to not use id selectors', function () {
  124. var res = parse('#hi', false, true)
  125. expect(res.nodeType).toBe(11)
  126. expect(res.firstChild.nodeValue).toBe('#hi')
  127. })
  128. it('should deal with Safari template clone bug', function () {
  129. var a = document.createElement('div')
  130. a.innerHTML = '<template>1</template>'
  131. var c = templateParser.cloneNode(a)
  132. expect(c.firstChild.innerHTML).toBe('1')
  133. })
  134. it('should deal with Safari template clone bug even when nested', function () {
  135. var a = document.createElement('div')
  136. a.innerHTML = '<template><div>1</div><template>2</template></template>'
  137. var c = templateParser.cloneNode(a)
  138. expect(c.firstChild.innerHTML).toBe('<div>1</div><template>2</template>')
  139. })
  140. it('should deal with IE textarea clone bug', function () {
  141. var t = document.createElement('textarea')
  142. t.placeholder = 't'
  143. var c = templateParser.cloneNode(t)
  144. expect(c.value).toBe('')
  145. })
  146. it('should trim empty text nodes and comments', function () {
  147. // string
  148. var res = parse(' <p>test</p> ')
  149. expect(res.childNodes.length).toBe(1)
  150. expect(res.firstChild.tagName).toBe('P')
  151. // nodes
  152. var el = document.createElement('div')
  153. el.innerHTML = '<template> <p>test</p> </template>'
  154. res = parse(el.children[0])
  155. expect(res.childNodes.length).toBe(1)
  156. expect(res.firstChild.tagName).toBe('P')
  157. // comments
  158. res = parse(' <!-- yo --> <p>test</p> <!-- yo --> ')
  159. expect(res.childNodes.length).toBe(1)
  160. expect(res.firstChild.tagName).toBe('P')
  161. })
  162. it('should reuse fragment from cache for the same string template', function () {
  163. var stringTemplate = ' <p>test</p> '
  164. // When parsing a template, adds the created fragment to a cache
  165. var res = parse(stringTemplate)
  166. var newRes = parse(stringTemplate)
  167. expect(newRes).toBe(res)
  168. })
  169. })