glass-easel 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/.eslintignore +4 -0
  2. package/dist/glass_easel.all.js +2 -2
  3. package/dist/glass_easel.all.js.map +1 -1
  4. package/dist/glass_easel.d.ts +2546 -0
  5. package/dist/glass_easel.domlike.global.js +2 -2
  6. package/dist/glass_easel.domlike.global.js.map +1 -1
  7. package/guide/zh_CN/appendix/backend_protocol.md +164 -74
  8. package/jest.unit.config.js +7 -4
  9. package/package.json +7 -5
  10. package/rollup.config.ts +101 -0
  11. package/src/backend/backend_protocol.ts +26 -345
  12. package/src/backend/composed_backend_protocol.ts +10 -264
  13. package/src/backend/current_window_backend_context.ts +478 -0
  14. package/src/backend/domlike_backend_protocol.ts +9 -498
  15. package/src/backend/empty_backend.ts +265 -0
  16. package/src/backend/empty_composed_backend.ts +245 -0
  17. package/src/backend/index.ts +18 -0
  18. package/src/backend/suggested_backend_protocol.ts +62 -11
  19. package/src/behavior.ts +131 -442
  20. package/src/class_list.ts +328 -222
  21. package/src/component.ts +349 -184
  22. package/src/component_params.ts +54 -25
  23. package/src/component_space.ts +36 -15
  24. package/src/data_path.ts +22 -34
  25. package/src/data_proxy.ts +334 -27
  26. package/src/devtool.ts +89 -0
  27. package/src/element.ts +667 -285
  28. package/src/element_iterator.ts +9 -4
  29. package/src/event.ts +39 -20
  30. package/src/external_shadow_tree.ts +2 -2
  31. package/src/func_arr.ts +55 -101
  32. package/src/global_options.ts +18 -42
  33. package/src/index.ts +72 -73
  34. package/src/mutation_observer.ts +10 -7
  35. package/src/native_node.ts +79 -35
  36. package/src/node.ts +23 -30
  37. package/src/relation.ts +101 -12
  38. package/src/render.ts +5 -3
  39. package/src/selector.ts +9 -7
  40. package/src/shadow_root.ts +96 -240
  41. package/src/template_engine.ts +10 -7
  42. package/src/text_node.ts +43 -19
  43. package/src/tmpl/index.ts +38 -30
  44. package/src/tmpl/native_rendering.ts +14 -21
  45. package/src/tmpl/proc_gen_wrapper.ts +189 -151
  46. package/src/tmpl/proc_gen_wrapper_dom.ts +10 -8
  47. package/src/tmpl/range_list_diff.ts +30 -9
  48. package/src/trait_behaviors.ts +1 -1
  49. package/src/type_symbol.ts +36 -0
  50. package/src/virtual_node.ts +26 -13
  51. package/src/warning.ts +119 -0
  52. package/tests/base/composed_backend.ts +143 -142
  53. package/tests/base/env.ts +76 -3
  54. package/tests/base/match.ts +24 -22
  55. package/tests/base/shadow_backend.ts +917 -0
  56. package/tests/core/backend.test.ts +53 -1
  57. package/tests/core/behavior.test.ts +1 -1
  58. package/tests/core/data_update.test.ts +135 -0
  59. package/tests/core/misc.test.ts +91 -21
  60. package/tests/core/placeholder.test.ts +66 -25
  61. package/tests/core/slot.test.ts +161 -23
  62. package/tests/legacy/component.test.js +152 -78
  63. package/tests/legacy/data_path.test.js +19 -19
  64. package/tests/legacy/data_proxy.test.js +14 -7
  65. package/tests/legacy/external.test.js +8 -8
  66. package/tests/legacy/mutation_observer.test.js +7 -5
  67. package/tests/legacy/slot.test.js +2 -3
  68. package/tests/legacy/virtual.test.js +258 -25
  69. package/tests/tmpl/binding_map.test.ts +201 -195
  70. package/tests/tmpl/event.test.ts +138 -23
  71. package/tests/tmpl/expression.test.ts +15 -15
  72. package/tests/tmpl/lvalue.test.ts +101 -0
  73. package/tests/tmpl/structure.test.ts +486 -43
  74. package/tests/types/chaining.test.ts +27 -30
  75. package/tests/types/createElement.test.ts +5 -4
  76. package/tests/types/definition.test.ts +11 -14
  77. package/tsconfig.json +1 -3
  78. package/dist/glass_easel.all.d.ts +0 -1
  79. package/dist/glass_easel.domlike.global.d.ts +0 -1
  80. package/dist/index.d.ts +0 -1
  81. package/dist/index.js +0 -1
  82. package/dist/types/src/backend/backend_protocol.d.ts +0 -141
  83. package/dist/types/src/backend/backend_protocol.d.ts.map +0 -1
  84. package/dist/types/src/backend/composed_backend_protocol.d.ts +0 -102
  85. package/dist/types/src/backend/composed_backend_protocol.d.ts.map +0 -1
  86. package/dist/types/src/backend/domlike_backend_protocol.d.ts +0 -100
  87. package/dist/types/src/backend/domlike_backend_protocol.d.ts.map +0 -1
  88. package/dist/types/src/backend/mode.d.ts +0 -65
  89. package/dist/types/src/backend/mode.d.ts.map +0 -1
  90. package/dist/types/src/backend/suggested_backend_protocol.d.ts +0 -30
  91. package/dist/types/src/backend/suggested_backend_protocol.d.ts.map +0 -1
  92. package/dist/types/src/behavior.d.ts +0 -434
  93. package/dist/types/src/behavior.d.ts.map +0 -1
  94. package/dist/types/src/class_list.d.ts +0 -83
  95. package/dist/types/src/class_list.d.ts.map +0 -1
  96. package/dist/types/src/component.d.ts +0 -325
  97. package/dist/types/src/component.d.ts.map +0 -1
  98. package/dist/types/src/component_params.d.ts +0 -236
  99. package/dist/types/src/component_params.d.ts.map +0 -1
  100. package/dist/types/src/component_space.d.ts +0 -211
  101. package/dist/types/src/component_space.d.ts.map +0 -1
  102. package/dist/types/src/data_path.d.ts +0 -5
  103. package/dist/types/src/data_path.d.ts.map +0 -1
  104. package/dist/types/src/data_proxy.d.ts +0 -107
  105. package/dist/types/src/data_proxy.d.ts.map +0 -1
  106. package/dist/types/src/data_utils.d.ts +0 -3
  107. package/dist/types/src/data_utils.d.ts.map +0 -1
  108. package/dist/types/src/element.d.ts +0 -365
  109. package/dist/types/src/element.d.ts.map +0 -1
  110. package/dist/types/src/element_iterator.d.ts +0 -43
  111. package/dist/types/src/element_iterator.d.ts.map +0 -1
  112. package/dist/types/src/event.d.ts +0 -105
  113. package/dist/types/src/event.d.ts.map +0 -1
  114. package/dist/types/src/external_shadow_tree.d.ts +0 -20
  115. package/dist/types/src/external_shadow_tree.d.ts.map +0 -1
  116. package/dist/types/src/func_arr.d.ts +0 -39
  117. package/dist/types/src/func_arr.d.ts.map +0 -1
  118. package/dist/types/src/global_options.d.ts +0 -120
  119. package/dist/types/src/global_options.d.ts.map +0 -1
  120. package/dist/types/src/index.d.ts +0 -43
  121. package/dist/types/src/index.d.ts.map +0 -1
  122. package/dist/types/src/mutation_observer.d.ts +0 -79
  123. package/dist/types/src/mutation_observer.d.ts.map +0 -1
  124. package/dist/types/src/native_node.d.ts +0 -11
  125. package/dist/types/src/native_node.d.ts.map +0 -1
  126. package/dist/types/src/node.d.ts +0 -48
  127. package/dist/types/src/node.d.ts.map +0 -1
  128. package/dist/types/src/relation.d.ts +0 -46
  129. package/dist/types/src/relation.d.ts.map +0 -1
  130. package/dist/types/src/render.d.ts +0 -3
  131. package/dist/types/src/render.d.ts.map +0 -1
  132. package/dist/types/src/selector.d.ts +0 -32
  133. package/dist/types/src/selector.d.ts.map +0 -1
  134. package/dist/types/src/shadow_root.d.ts +0 -174
  135. package/dist/types/src/shadow_root.d.ts.map +0 -1
  136. package/dist/types/src/template_engine.d.ts +0 -56
  137. package/dist/types/src/template_engine.d.ts.map +0 -1
  138. package/dist/types/src/text_node.d.ts +0 -44
  139. package/dist/types/src/text_node.d.ts.map +0 -1
  140. package/dist/types/src/tmpl/index.d.ts +0 -19
  141. package/dist/types/src/tmpl/index.d.ts.map +0 -1
  142. package/dist/types/src/tmpl/native_rendering.d.ts +0 -45
  143. package/dist/types/src/tmpl/native_rendering.d.ts.map +0 -1
  144. package/dist/types/src/tmpl/proc_gen_wrapper.d.ts +0 -89
  145. package/dist/types/src/tmpl/proc_gen_wrapper.d.ts.map +0 -1
  146. package/dist/types/src/tmpl/proc_gen_wrapper_dom.d.ts +0 -50
  147. package/dist/types/src/tmpl/proc_gen_wrapper_dom.d.ts.map +0 -1
  148. package/dist/types/src/tmpl/range_list_diff.d.ts +0 -19
  149. package/dist/types/src/tmpl/range_list_diff.d.ts.map +0 -1
  150. package/dist/types/src/trait_behaviors.d.ts +0 -38
  151. package/dist/types/src/trait_behaviors.d.ts.map +0 -1
  152. package/dist/types/src/virtual_node.d.ts +0 -10
  153. package/dist/types/src/virtual_node.d.ts.map +0 -1
  154. package/dist/types/tests/backend/domlike.test.d.ts +0 -2
  155. package/dist/types/tests/backend/domlike.test.d.ts.map +0 -1
  156. package/dist/types/tests/base/composed_backend.d.ts +0 -123
  157. package/dist/types/tests/base/composed_backend.d.ts.map +0 -1
  158. package/dist/types/tests/base/env.d.ts +0 -30
  159. package/dist/types/tests/base/env.d.ts.map +0 -1
  160. package/dist/types/tests/base/match.d.ts +0 -9
  161. package/dist/types/tests/base/match.d.ts.map +0 -1
  162. package/dist/types/tests/core/backend.test.d.ts +0 -2
  163. package/dist/types/tests/core/backend.test.d.ts.map +0 -1
  164. package/dist/types/tests/core/behavior.test.d.ts +0 -2
  165. package/dist/types/tests/core/behavior.test.d.ts.map +0 -1
  166. package/dist/types/tests/core/component_space.test.d.ts +0 -2
  167. package/dist/types/tests/core/component_space.test.d.ts.map +0 -1
  168. package/dist/types/tests/core/data_update.test.d.ts +0 -2
  169. package/dist/types/tests/core/data_update.test.d.ts.map +0 -1
  170. package/dist/types/tests/core/misc.test.d.ts +0 -2
  171. package/dist/types/tests/core/misc.test.d.ts.map +0 -1
  172. package/dist/types/tests/core/placeholder.test.d.ts +0 -2
  173. package/dist/types/tests/core/placeholder.test.d.ts.map +0 -1
  174. package/dist/types/tests/core/slot.test.d.ts +0 -2
  175. package/dist/types/tests/core/slot.test.d.ts.map +0 -1
  176. package/dist/types/tests/core/trait_behaviors.test.d.ts +0 -2
  177. package/dist/types/tests/core/trait_behaviors.test.d.ts.map +0 -1
  178. package/dist/types/tests/tmpl/binding_map.test.d.ts +0 -2
  179. package/dist/types/tests/tmpl/binding_map.test.d.ts.map +0 -1
  180. package/dist/types/tests/tmpl/event.test.d.ts +0 -2
  181. package/dist/types/tests/tmpl/event.test.d.ts.map +0 -1
  182. package/dist/types/tests/tmpl/expression.test.d.ts +0 -2
  183. package/dist/types/tests/tmpl/expression.test.d.ts.map +0 -1
  184. package/dist/types/tests/tmpl/lvalue.test.d.ts +0 -2
  185. package/dist/types/tests/tmpl/lvalue.test.d.ts.map +0 -1
  186. package/dist/types/tests/tmpl/native_rendering.test.d.ts +0 -2
  187. package/dist/types/tests/tmpl/native_rendering.test.d.ts.map +0 -1
  188. package/dist/types/tests/tmpl/structure.test.d.ts +0 -2
  189. package/dist/types/tests/tmpl/structure.test.d.ts.map +0 -1
  190. package/dist/types/tests/types/chaining.test.d.ts +0 -2
  191. package/dist/types/tests/types/chaining.test.d.ts.map +0 -1
  192. package/dist/types/tests/types/createElement.test.d.ts +0 -2
  193. package/dist/types/tests/types/createElement.test.d.ts.map +0 -1
  194. package/dist/types/tests/types/definition.test.d.ts +0 -2
  195. package/dist/types/tests/types/definition.test.d.ts.map +0 -1
  196. package/webpack.config.js +0 -275
  197. /package/src/backend/{mode.ts → shared.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
 
3
- const { execWithWarn } = require('../base/env')
3
+ const { execWithWarn, execWithError } = require('../base/env')
4
4
  const glassEasel = require('../../src')
5
5
 
6
6
  describe('DataPath', function () {
@@ -30,17 +30,17 @@ describe('DataPath', function () {
30
30
  })
31
31
 
32
32
  it('fails at illegal integers', function () {
33
- execWithWarn(1, function () {
33
+ execWithError(function () {
34
34
  var str = 'a[b]'
35
35
  expect(glassEasel.dataPath.parseSinglePath(str)).toStrictEqual(null)
36
- })
36
+ }, 'data path descriptor "a[b]" is illegal at char 2 (illegal index)')
37
37
  })
38
38
 
39
39
  it('fails at illegal integer suffixes', function () {
40
- execWithWarn(1, function () {
40
+ execWithError(function () {
41
41
  var str = 'a[1e]'
42
42
  expect(glassEasel.dataPath.parseSinglePath(str)).toStrictEqual(null)
43
- })
43
+ }, 'data path descriptor "a[1e]" is illegal at char 3 (illegal index)')
44
44
  })
45
45
 
46
46
  it('should parse empty str', function () {
@@ -96,52 +96,52 @@ describe('DataPath', function () {
96
96
  })
97
97
 
98
98
  it('fails at illegal integers', function () {
99
- execWithWarn(1, function () {
99
+ execWithError(function () {
100
100
  var str = 'a[b]'
101
101
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
102
- })
102
+ }, 'data path descriptor "a[b]" is illegal at char 2 (illegal index)')
103
103
  })
104
104
 
105
105
  it('fails at illegal integer suffixes', function () {
106
- execWithWarn(1, function () {
106
+ execWithError(function () {
107
107
  var str = 'a[1e]'
108
108
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
109
- })
109
+ }, 'data path descriptor "a[1e]" is illegal at char 3 (illegal index)')
110
110
  })
111
111
 
112
112
  it('fails at number-started fields', function () {
113
- execWithWarn(1, function () {
113
+ execWithError(function () {
114
114
  var str = '1a'
115
115
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
116
- })
116
+ }, 'data path descriptor "1a" is illegal at char 0 (field name cannot start with digits)')
117
117
  })
118
118
 
119
119
  it('fails at number-started subfields', function () {
120
- execWithWarn(1, function () {
120
+ execWithError(function () {
121
121
  var str = 'b.1a'
122
122
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
123
- })
123
+ }, 'data path descriptor "b.1a" is illegal at char 2 (field name cannot start with digits)')
124
124
  })
125
125
 
126
126
  it('fails at empty str', function () {
127
- execWithWarn(1, function () {
127
+ execWithError(function () {
128
128
  var str = ''
129
129
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
130
- })
130
+ }, 'data path descriptor "" is illegal at char 0 (first field name illegal)')
131
131
  })
132
132
 
133
133
  it('fails at empty subfields', function () {
134
- execWithWarn(1, function () {
134
+ execWithError(function () {
135
135
  var str = 'a.'
136
136
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
137
- })
137
+ }, 'data path descriptor "a." is illegal at char 2 (field name illegal)')
138
138
  })
139
139
 
140
140
  it('fails at extra chars', function () {
141
- execWithWarn(1, function () {
141
+ execWithError(function () {
142
142
  var str = 'a.b*'
143
143
  expect(glassEasel.dataPath.parseMultiPaths(str)).toStrictEqual([])
144
- })
144
+ }, 'data path descriptor "a.b*" is illegal at char 3')
145
145
  })
146
146
  })
147
147
  })
@@ -277,18 +277,21 @@ describe('DataProxy', function () {
277
277
  },
278
278
  })
279
279
  var elem = createElem('data-proxy-prop-passing-deep-copy')
280
- expect(elem.$.c.getAttribute('prop-abc')).toBe('1')
280
+ expect(elem.$.c.getAttribute('prop-abc')).toBe(1)
281
+ expect(elem.$.c.$$.getAttribute('prop-abc')).toBe('1')
281
282
  var dataGroup = glassEasel.Component.getDataProxy(elem)
282
283
  var c = 4
283
284
  dataGroup.replaceDataOnPath(['a', 'b'], c)
284
285
  c = 5
285
286
  dataGroup.applyDataUpdates()
286
- expect(elem.$.c.getAttribute('prop-abc')).toBe('4')
287
+ expect(elem.$.c.getAttribute('prop-abc')).toBe(4)
288
+ expect(elem.$.c.$$.getAttribute('prop-abc')).toBe('4')
287
289
  d = { b: c }
288
290
  dataGroup.replaceProperty('a', d)
289
291
  d.b = 6
290
292
  dataGroup.applyDataUpdates()
291
- expect(elem.$.c.getAttribute('prop-abc')).toBe('6')
293
+ expect(elem.$.c.getAttribute('prop-abc')).toBe(6)
294
+ expect(elem.$.c.$$.getAttribute('prop-abc')).toBe('6')
292
295
  })
293
296
 
294
297
  describe('#scheduleReplace #setChanges #getChanges', function () {
@@ -530,7 +533,8 @@ describe('DataProxy', function () {
530
533
  observer: function () {
531
534
  actualOrder.push(0)
532
535
  expect(elem.data.prop1).toBe(456)
533
- expect(elem.$.a.getAttribute('prop-a')).toBe('456')
536
+ expect(elem.$.a.getAttribute('prop-a')).toBe(456)
537
+ expect(elem.$.a.$$.getAttribute('prop-a')).toBe('456')
534
538
  },
535
539
  },
536
540
  },
@@ -538,7 +542,8 @@ describe('DataProxy', function () {
538
542
  '**': function () {
539
543
  actualOrder.push(1)
540
544
  expect(elem.data.prop1).toBe(456)
541
- expect(elem.$.a.getAttribute('prop-a')).toBe('123')
545
+ expect(elem.$.a.getAttribute('prop-a')).toBe(123)
546
+ expect(elem.$.a.$$.getAttribute('prop-a')).toBe('123')
542
547
  },
543
548
  },
544
549
  })
@@ -563,8 +568,10 @@ describe('DataProxy', function () {
563
568
  actualOrder.push(1)
564
569
  expect(this.data.propA).toBe(123)
565
570
  expect(this.data.dataB).toBe(456)
566
- expect(this.$.a.getAttribute('prop-a')).toBe('123')
567
- expect(this.$.a.getAttribute('prop-b')).toBe('456')
571
+ expect(this.$.a.getAttribute('prop-a')).toBe(123)
572
+ expect(this.$.a.$$.getAttribute('prop-a')).toBe('123')
573
+ expect(this.$.a.getAttribute('prop-b')).toBe(456)
574
+ expect(this.$.a.$$.getAttribute('prop-b')).toBe('456')
568
575
  expect(elem.data.dataE).toBe(true)
569
576
  },
570
577
  },
@@ -533,21 +533,21 @@ describe('Element', function () {
533
533
  e.setNodeClass('e1 e2', 2)
534
534
  expect(e.$$.classList.value).toBe('c1 c2 e1 e2')
535
535
  e.setNodeClass('d1', 1)
536
- expect(e.$$.classList.value).toBe('c1 c2 d1 e1 e2')
536
+ expect(e.$$.classList.value).toBe('c1 c2 e1 e2 d1')
537
537
  e.setNodeClass('')
538
- expect(e.$$.classList.value).toBe('d1 e1 e2')
538
+ expect(e.$$.classList.value).toBe('e1 e2 d1')
539
539
  e.setNodeClass('c1 c2 c3')
540
- expect(e.$$.classList.value).toBe('c1 c2 c3 d1 e1 e2')
540
+ expect(e.$$.classList.value).toBe('e1 e2 d1 c1 c2 c3')
541
541
  e.setNodeClass('d1 d2', 1)
542
- expect(e.$$.classList.value).toBe('c1 c2 c3 d1 d2 e1 e2')
542
+ expect(e.$$.classList.value).toBe('e1 e2 d1 c1 c2 c3 d2')
543
543
  e.setNodeClass('', 1)
544
- expect(e.$$.classList.value).toBe('c1 c2 c3 e1 e2')
544
+ expect(e.$$.classList.value).toBe('e1 e2 c1 c2 c3')
545
545
  e.setNodeClass('e1', 2)
546
- expect(e.$$.classList.value).toBe('c1 c2 c3 e1')
546
+ expect(e.$$.classList.value).toBe('e1 c1 c2 c3')
547
547
  e.setNodeClass('d1 d2 d3', 1)
548
- expect(e.$$.classList.value).toBe('c1 c2 c3 d1 d2 d3 e1')
548
+ expect(e.$$.classList.value).toBe('e1 c1 c2 c3 d1 d2 d3')
549
549
  e.setNodeClass('e1 e2', 2)
550
- expect(e.$$.classList.value).toBe('c1 c2 c3 d1 d2 d3 e1 e2')
550
+ expect(e.$$.classList.value).toBe('e1 c1 c2 c3 d1 d2 d3 e2')
551
551
  e.setNodeClass('', 2)
552
552
  expect(e.$$.classList.value).toBe('c1 c2 c3 d1 d2 d3')
553
553
  })
@@ -98,21 +98,23 @@ describe('Observer', function () {
98
98
  it('should be able to observe core property changes', function () {
99
99
  var elem = createElem('observer-a')
100
100
  var expectPropertyNameList = ['id', 'slot', 'class', 'class', 'class', 'class', 'style']
101
+ var expectPropertyValueList = ['a', 'b', 'c', '', 'c', 'c d', 'd']
101
102
  var observer = glassEasel.MutationObserver.create(function (e) {
102
103
  expect(this).toBe(e.target)
103
104
  expect(e.type).toBe('properties')
104
105
  expect(e.target).toBe(elem)
105
106
  expect(e.attributeName).toBe(expectPropertyNameList.shift())
107
+ expect(e.target[e.attributeName]).toBe(expectPropertyValueList.shift())
106
108
  })
107
109
  observer.observe(elem, { properties: true })
108
110
  elem.id = 'a'
109
111
  elem.slot = 'b'
110
112
  elem.class = 'c'
111
- elem.classList.toggle('c')
112
- elem.classList.toggle('c')
113
- elem.classList.toggle('c', true)
114
- elem.classList.toggle('d', false)
115
- elem.classList.toggle('d', true)
113
+ elem.toggleNodeClass('c')
114
+ elem.toggleNodeClass('c')
115
+ elem.toggleNodeClass('c', true)
116
+ elem.toggleNodeClass('d', false)
117
+ elem.toggleNodeClass('d', true)
116
118
  elem.style = 'd'
117
119
  expect(expectPropertyNameList.length).toBe(0)
118
120
  })
@@ -42,9 +42,8 @@ const testCases = function (testBackend) {
42
42
  root.$$.id = 'root'
43
43
  var backendRoot = testBackend.getRootNode()
44
44
  if (testBackend === shadowBackend) {
45
- var placeholder = backendRoot.createElement('div')
46
- backendRoot.appendChild(placeholder)
47
- glassEasel.Element.replaceDocumentElement(root, backendRoot, placeholder)
45
+ backendRoot.appendChild(root.getBackendElement())
46
+ glassEasel.Element.pretendAttached(root)
48
47
  } else if (testBackend === domBackend) {
49
48
  var placeholder = testBackend.document.createElement('div')
50
49
  backendRoot.appendChild(placeholder)
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
 
3
- const { tmpl, domBackend, shadowBackend, composedBackend } = require('../base/env')
3
+ const { tmpl, domBackend, shadowBackend, composedBackend, getCustomExternalTemplateEngine } = require('../base/env')
4
4
  const glassEasel = require('../../src')
5
5
 
6
6
  const componentSpace = new glassEasel.ComponentSpace()
@@ -42,9 +42,8 @@ const testCases = function (testBackend) {
42
42
  root.$$.id = 'root'
43
43
  var backendRoot = testBackend.getRootNode()
44
44
  if (testBackend === shadowBackend) {
45
- var placeholder = backendRoot.createElement('div')
46
- backendRoot.appendChild(placeholder)
47
- glassEasel.Element.replaceDocumentElement(root, backendRoot, placeholder)
45
+ backendRoot.appendChild(root.getBackendElement())
46
+ glassEasel.Element.pretendAttached(root)
48
47
  } else if (testBackend === domBackend) {
49
48
  var placeholder = testBackend.document.createElement('div')
50
49
  backendRoot.appendChild(placeholder)
@@ -113,26 +112,48 @@ const testCases = function (testBackend) {
113
112
  matchElementWithDom(e1)
114
113
  })
115
114
 
116
- if (testBackend === domBackend)
117
- it('should work in a native-rendered root', function () {
118
- regElem({
119
- is: 'virtual-node-a',
120
- options: {
121
- externalComponent: true,
122
- },
123
- template: '<div><slot></slot></div>',
124
- })
125
- var e1 = root.shadowRoot.createComponent('virtual-node-a')
126
- var e2 = glassEasel.NativeNode.create('span', root.shadowRoot)
127
- var e3 = glassEasel.TextNode.create('text', root.shadowRoot)
128
- var v1 = glassEasel.VirtualNode.create('virtual', root.shadowRoot)
129
- var v2 = glassEasel.VirtualNode.create('virtual', root.shadowRoot)
130
- v1.appendChild(e2)
131
- v1.appendChild(e3)
132
- e2.appendChild(v2)
133
- e1.appendChild(v1)
134
- matchElementWithDom(e1, e1.shadowRoot.root)
115
+ it('should work in a native-rendered root', function () {
116
+ regElem({
117
+ is: 'virtual-node-a',
118
+ options: {
119
+ externalComponent: true,
120
+ templateEngine:
121
+ testBackend === domBackend
122
+ ? undefined
123
+ : getCustomExternalTemplateEngine(comp => {
124
+ var root = comp.getBackendElement()
125
+ var slot
126
+ if (testBackend === shadowBackend) {
127
+ var shadowRoot = root.getShadowRoot()
128
+ slot = shadowRoot.createElement('div', 'div')
129
+ slot.setSlotName('')
130
+ shadowRoot.appendChild(slot)
131
+ } else {
132
+ slot = testBackend.createElement('div', 'div')
133
+ root.appendChild(slot)
134
+ }
135
+ return {
136
+ root,
137
+ slot,
138
+ getIdMap: () => ({}),
139
+ handleEvent() {},
140
+ setListener() {},
141
+ }
142
+ }),
143
+ },
144
+ template: '<div><slot></slot></div>',
135
145
  })
146
+ var e1 = root.shadowRoot.createComponent('virtual-node-a')
147
+ var e2 = glassEasel.NativeNode.create('span', root.shadowRoot)
148
+ var e3 = glassEasel.TextNode.create('text', root.shadowRoot)
149
+ var v1 = glassEasel.VirtualNode.create('virtual', root.shadowRoot)
150
+ var v2 = glassEasel.VirtualNode.create('virtual', root.shadowRoot)
151
+ v1.appendChild(e2)
152
+ v1.appendChild(e3)
153
+ e2.appendChild(v2)
154
+ e1.appendChild(v1)
155
+ matchElementWithDom(e1, e1.shadowRoot.root)
156
+ })
136
157
  })
137
158
 
138
159
  describe('#insertBefore', function () {
@@ -238,6 +259,8 @@ const testCases = function (testBackend) {
238
259
  matchElementWithDom(e1)
239
260
  matchElementWithDom(v3)
240
261
  expect(v3.parentNode).toBe(null)
262
+ v1.replaceChild(v2, v2)
263
+ matchElementWithDom(e1)
241
264
  })
242
265
 
243
266
  it('should convert to correct DOM replaceChild (replacing indirectly at the end)', function () {
@@ -342,6 +365,7 @@ const testCases = function (testBackend) {
342
365
  var e3 = glassEasel.NativeNode.create('e3', root.shadowRoot)
343
366
  var v1 = glassEasel.VirtualNode.create('v1', root.shadowRoot)
344
367
  var v2 = glassEasel.VirtualNode.create('v2', root.shadowRoot)
368
+ var v3 = glassEasel.VirtualNode.create('v3', root.shadowRoot)
345
369
  var t1 = glassEasel.TextNode.create('t1', root.shadowRoot)
346
370
  var t2 = glassEasel.TextNode.create('t2', root.shadowRoot)
347
371
  e1.appendChild(e2)
@@ -356,11 +380,17 @@ const testCases = function (testBackend) {
356
380
  expect(e2.parentNode).toBe(null)
357
381
  expect(e2.childNodes.length).toBe(0)
358
382
 
359
- v2.selfReplaceWith(e2)
383
+ v2.selfReplaceWith(v3)
360
384
  matchElementWithDom(e1)
361
385
  matchElementWithDom(v2)
362
386
  expect(v2.parentNode).toBe(null)
363
387
  expect(v2.childNodes.length).toBe(0)
388
+
389
+ v3.selfReplaceWith(e2)
390
+ matchElementWithDom(e1)
391
+ matchElementWithDom(v3)
392
+ expect(v3.parentNode).toBe(null)
393
+ expect(v3.childNodes.length).toBe(0)
364
394
  })
365
395
 
366
396
  it('should replace component with children', function () {
@@ -405,6 +435,59 @@ const testCases = function (testBackend) {
405
435
  })
406
436
 
407
437
  it('should replace virtualHost component with children', function () {
438
+ regElem({
439
+ is: 'virtual-comp1',
440
+ options: { virtualHost: true },
441
+ template: '<div>virtual</div><slot />',
442
+ })
443
+ regElem({
444
+ is: 'comp1',
445
+ template: '<div>actual</div><slot />',
446
+ })
447
+ regElem({
448
+ is: 'virtual-comp2',
449
+ options: { multipleSlots: true, virtualHost: true },
450
+ template: '<slot name="a" /><div>virtual</div><slot name="b"/>',
451
+ })
452
+ regElem({
453
+ is: 'comp2',
454
+ options: { multipleSlots: true },
455
+ template: '<div><slot name="b"/>actual</div><slot name="a" />',
456
+ })
457
+ var e1 = glassEasel.NativeNode.create('e1', root.shadowRoot)
458
+ var e2 = glassEasel.NativeNode.create('e2', root.shadowRoot)
459
+ var e3 = glassEasel.NativeNode.create('e3', root.shadowRoot)
460
+ var e4 = glassEasel.NativeNode.create('e4', root.shadowRoot)
461
+ var v1 = glassEasel.VirtualNode.create('v1', root.shadowRoot)
462
+ var t1 = glassEasel.TextNode.create('t1', root.shadowRoot)
463
+ var c1 = root.shadowRoot.createComponent('comp1')
464
+ var vc1 = root.shadowRoot.createComponent('virtual-comp1')
465
+ var c2 = root.shadowRoot.createComponent('comp2')
466
+ var vc2 = root.shadowRoot.createComponent('virtual-comp2')
467
+ e1.appendChild(e2)
468
+ e2.appendChild(e3)
469
+ e2.appendChild(v1)
470
+ v1.appendChild(t1)
471
+ e2.appendChild(e4)
472
+ e4.slot = 'b'
473
+
474
+ e2.selfReplaceWith(vc1)
475
+ matchElementWithDom(e1)
476
+ expect(e2.parentNode).toBe(null)
477
+ expect(e2.childNodes.length).toBe(0)
478
+
479
+ vc1.selfReplaceWith(vc2)
480
+ matchElementWithDom(e1)
481
+ expect(vc1.parentNode).toBe(null)
482
+ expect(vc1.childNodes.length).toBe(0)
483
+
484
+ vc2.selfReplaceWith(c2)
485
+ matchElementWithDom(e1)
486
+ expect(vc2.parentNode).toBe(null)
487
+ expect(vc2.childNodes.length).toBe(0)
488
+ })
489
+
490
+ it('should replace nested virtualHost component with children', function () {
408
491
  regElem({
409
492
  is: 'virtual-comp1',
410
493
  options: { virtualHost: true },
@@ -460,6 +543,116 @@ const testCases = function (testBackend) {
460
543
  matchElementWithDom(e1)
461
544
  expect(vc2.parentNode).toBe(null)
462
545
  expect(vc2.childNodes.length).toBe(0)
546
+
547
+ c2.selfReplaceWith(vc2)
548
+ matchElementWithDom(e1)
549
+ expect(c2.parentNode).toBe(null)
550
+ expect(c2.childNodes.length).toBe(0)
551
+
552
+ vc2.selfReplaceWith(vc1)
553
+ matchElementWithDom(e1)
554
+ expect(vc2.parentNode).toBe(null)
555
+ expect(vc2.childNodes.length).toBe(0)
556
+
557
+ vc1.selfReplaceWith(vc2)
558
+ matchElementWithDom(e1)
559
+ expect(vc1.parentNode).toBe(null)
560
+ expect(vc1.childNodes.length).toBe(0)
561
+ })
562
+
563
+ it('should replace slot contents with children', function () {
564
+ regElem({
565
+ is: 'wrapper',
566
+ template: '<div><slot /></div>',
567
+ })
568
+ regElem({
569
+ is: 'comp1',
570
+ template: '<div><slot /></div>',
571
+ })
572
+ regElem({
573
+ is: 'comp2',
574
+ options: { multipleSlots: true },
575
+ template: '<div><slot name="b"/></div><slot name="a" />',
576
+ })
577
+ var e1 = root.shadowRoot.createComponent('wrapper')
578
+ var e2 = glassEasel.NativeNode.create('e2', root.shadowRoot)
579
+ var e3 = glassEasel.NativeNode.create('e3', root.shadowRoot)
580
+ var e4 = glassEasel.NativeNode.create('e4', root.shadowRoot)
581
+ var v1 = glassEasel.VirtualNode.create('v1', root.shadowRoot)
582
+ var t1 = glassEasel.TextNode.create('t1', root.shadowRoot)
583
+ var c1 = root.shadowRoot.createComponent('comp1')
584
+ var c2 = root.shadowRoot.createComponent('comp2')
585
+ e1.appendChild(e2)
586
+ e2.appendChild(e3)
587
+ e2.appendChild(v1)
588
+ v1.appendChild(t1)
589
+ e2.appendChild(e4)
590
+ e4.slot = 'b'
591
+
592
+ e2.selfReplaceWith(c1)
593
+ matchElementWithDom(e1)
594
+ expect(e2.parentNode).toBe(null)
595
+ expect(e2.childNodes.length).toBe(0)
596
+
597
+ c1.selfReplaceWith(c2)
598
+ matchElementWithDom(e1)
599
+ expect(c1.parentNode).toBe(null)
600
+ expect(c1.childNodes.length).toBe(0)
601
+
602
+ c2.selfReplaceWith(c1)
603
+ matchElementWithDom(e1)
604
+ expect(c2.parentNode).toBe(null)
605
+ expect(c2.childNodes.length).toBe(0)
606
+ })
607
+
608
+ it('should trigger lifetimes correctly', function () {
609
+ const lifetimeCalls = []
610
+ const createElement = name => {
611
+ const def = componentSpace.defineComponent({
612
+ is: `self-replace-with-${name}`,
613
+ lifetimes: {
614
+ attached() { lifetimeCalls.push(`${name}#attached`) },
615
+ moved() { lifetimeCalls.push(`${name}#moved`) },
616
+ detached() { lifetimeCalls.push(`${name}#detached`) },
617
+ }
618
+ })
619
+ return glassEasel.Component.createWithContext(name, def, testBackend)
620
+ }
621
+
622
+ const parent = createElement('parent')
623
+ const elem = createElement('elem')
624
+ const child1 = createElement('child1')
625
+ const child2 = createElement('child2')
626
+ const childOfChild = createElement('child-of-child')
627
+
628
+ parent.appendChild(elem)
629
+ elem.appendChild(child1)
630
+ elem.appendChild(child2)
631
+ child1.appendChild(childOfChild)
632
+
633
+ glassEasel.Element.pretendAttached(parent)
634
+
635
+ matchElementWithDom(parent)
636
+ expect(lifetimeCalls).toEqual([
637
+ 'parent#attached',
638
+ 'elem#attached',
639
+ 'child1#attached',
640
+ 'child-of-child#attached',
641
+ 'child2#attached',
642
+ ])
643
+ lifetimeCalls.length = 0
644
+
645
+ const replacer = createElement('replacer')
646
+ elem.selfReplaceWith(replacer)
647
+
648
+ matchElementWithDom(parent)
649
+ expect(lifetimeCalls).toEqual([
650
+ 'elem#detached',
651
+ 'replacer#attached',
652
+ 'child-of-child#moved',
653
+ 'child1#moved',
654
+ 'child2#moved',
655
+ ])
463
656
  })
464
657
  })
465
658
 
@@ -486,7 +679,7 @@ const testCases = function (testBackend) {
486
679
  matchElementWithDom(parent)
487
680
  })
488
681
 
489
- if (testBackend === domBackend)
682
+ if (testBackend !== shadowBackend) {
490
683
  it('should handles tree manipulations', function () {
491
684
  regElem({
492
685
  is: 'virtual-host-c',
@@ -522,6 +715,46 @@ const testCases = function (testBackend) {
522
715
  expect(elem.$$.childNodes.length).toBe(0)
523
716
  matchElementWithDom(elem)
524
717
  })
718
+ }
719
+
720
+ it('should handles wx-if update', function () {
721
+ regElem({
722
+ is: 'list-view',
723
+ options: {
724
+ virtualHost: true,
725
+ },
726
+ template: '<listview><slot /></listview>',
727
+ })
728
+ regElem({
729
+ is: 'virtual-host-b',
730
+ options: {
731
+ virtualHost: true,
732
+ },
733
+ data: {
734
+ a: false,
735
+ b: false,
736
+ },
737
+ template: '<a wx:if="{{a}}" /><b wx:if="{{b}}" />',
738
+ })
739
+ regElem({
740
+ is: 'c',
741
+ options: {},
742
+ template: '<list-view><virtual-host-b id="b" /></list-view><span />',
743
+ })
744
+ var parent = glassEasel.NativeNode.create('span', root.shadowRoot)
745
+ var elem = root.shadowRoot.createComponent('c')
746
+ parent.appendChild(elem)
747
+ matchElementWithDom(parent)
748
+
749
+ elem.$.b.setData({ a: true })
750
+ matchElementWithDom(parent)
751
+
752
+ elem.$.b.setData({ a: false, b: true })
753
+ matchElementWithDom(parent)
754
+
755
+ elem.$.b.setData({ b: false })
756
+ matchElementWithDom(parent)
757
+ })
525
758
  })
526
759
  }
527
760