glass-easel 0.1.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 (237) hide show
  1. package/README.md +40 -0
  2. package/dist/glass_easel.all.d.ts +1 -0
  3. package/dist/glass_easel.all.js +2 -0
  4. package/dist/glass_easel.all.js.map +1 -0
  5. package/dist/glass_easel.domlike.global.d.ts +1 -0
  6. package/dist/glass_easel.domlike.global.js +2 -0
  7. package/dist/glass_easel.domlike.global.js.map +1 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +1 -0
  10. package/dist/types/src/backend/backend_protocol.d.ts +119 -0
  11. package/dist/types/src/backend/backend_protocol.d.ts.map +1 -0
  12. package/dist/types/src/backend/composed_backend_protocol.d.ts +90 -0
  13. package/dist/types/src/backend/composed_backend_protocol.d.ts.map +1 -0
  14. package/dist/types/src/backend/domlike_backend_protocol.d.ts +76 -0
  15. package/dist/types/src/backend/domlike_backend_protocol.d.ts.map +1 -0
  16. package/dist/types/src/backend/mode.d.ts +46 -0
  17. package/dist/types/src/backend/mode.d.ts.map +1 -0
  18. package/dist/types/src/backend/suggested_backend_protocol.d.ts +30 -0
  19. package/dist/types/src/backend/suggested_backend_protocol.d.ts.map +1 -0
  20. package/dist/types/src/behavior.d.ts +428 -0
  21. package/dist/types/src/behavior.d.ts.map +1 -0
  22. package/dist/types/src/class_list.d.ts +79 -0
  23. package/dist/types/src/class_list.d.ts.map +1 -0
  24. package/dist/types/src/component.d.ts +291 -0
  25. package/dist/types/src/component.d.ts.map +1 -0
  26. package/dist/types/src/component_params.d.ts +239 -0
  27. package/dist/types/src/component_params.d.ts.map +1 -0
  28. package/dist/types/src/component_space.d.ts +164 -0
  29. package/dist/types/src/component_space.d.ts.map +1 -0
  30. package/dist/types/src/data_path.d.ts +5 -0
  31. package/dist/types/src/data_path.d.ts.map +1 -0
  32. package/dist/types/src/data_proxy.d.ts +107 -0
  33. package/dist/types/src/data_proxy.d.ts.map +1 -0
  34. package/dist/types/src/data_utils.d.ts +3 -0
  35. package/dist/types/src/data_utils.d.ts.map +1 -0
  36. package/dist/types/src/element.d.ts +275 -0
  37. package/dist/types/src/element.d.ts.map +1 -0
  38. package/dist/types/src/element_iterator.d.ts +43 -0
  39. package/dist/types/src/element_iterator.d.ts.map +1 -0
  40. package/dist/types/src/event.d.ts +104 -0
  41. package/dist/types/src/event.d.ts.map +1 -0
  42. package/dist/types/src/external_shadow_tree.d.ts +20 -0
  43. package/dist/types/src/external_shadow_tree.d.ts.map +1 -0
  44. package/dist/types/src/func_arr.d.ts +39 -0
  45. package/dist/types/src/func_arr.d.ts.map +1 -0
  46. package/dist/types/src/global_options.d.ts +111 -0
  47. package/dist/types/src/global_options.d.ts.map +1 -0
  48. package/dist/types/src/index.d.ts +43 -0
  49. package/dist/types/src/index.d.ts.map +1 -0
  50. package/dist/types/src/mutation_observer.d.ts +79 -0
  51. package/dist/types/src/mutation_observer.d.ts.map +1 -0
  52. package/dist/types/src/native_node.d.ts +8 -0
  53. package/dist/types/src/native_node.d.ts.map +1 -0
  54. package/dist/types/src/node.d.ts +49 -0
  55. package/dist/types/src/node.d.ts.map +1 -0
  56. package/dist/types/src/relation.d.ts +47 -0
  57. package/dist/types/src/relation.d.ts.map +1 -0
  58. package/dist/types/src/render.d.ts +3 -0
  59. package/dist/types/src/render.d.ts.map +1 -0
  60. package/dist/types/src/selector.d.ts +32 -0
  61. package/dist/types/src/selector.d.ts.map +1 -0
  62. package/dist/types/src/shadow_root.d.ts +136 -0
  63. package/dist/types/src/shadow_root.d.ts.map +1 -0
  64. package/dist/types/src/template_engine.d.ts +18 -0
  65. package/dist/types/src/template_engine.d.ts.map +1 -0
  66. package/dist/types/src/text_node.d.ts +32 -0
  67. package/dist/types/src/text_node.d.ts.map +1 -0
  68. package/dist/types/src/tmpl/index.d.ts +18 -0
  69. package/dist/types/src/tmpl/index.d.ts.map +1 -0
  70. package/dist/types/src/tmpl/native_rendering.d.ts +45 -0
  71. package/dist/types/src/tmpl/native_rendering.d.ts.map +1 -0
  72. package/dist/types/src/tmpl/proc_gen_wrapper.d.ts +80 -0
  73. package/dist/types/src/tmpl/proc_gen_wrapper.d.ts.map +1 -0
  74. package/dist/types/src/tmpl/proc_gen_wrapper_dom.d.ts +50 -0
  75. package/dist/types/src/tmpl/proc_gen_wrapper_dom.d.ts.map +1 -0
  76. package/dist/types/src/tmpl/range_list_diff.d.ts +19 -0
  77. package/dist/types/src/tmpl/range_list_diff.d.ts.map +1 -0
  78. package/dist/types/src/trait_behaviors.d.ts +38 -0
  79. package/dist/types/src/trait_behaviors.d.ts.map +1 -0
  80. package/dist/types/src/virtual_node.d.ts +10 -0
  81. package/dist/types/src/virtual_node.d.ts.map +1 -0
  82. package/dist/types/tests/backend/domlike.test.d.ts +2 -0
  83. package/dist/types/tests/backend/domlike.test.d.ts.map +1 -0
  84. package/dist/types/tests/base/env.d.ts +29 -0
  85. package/dist/types/tests/base/env.d.ts.map +1 -0
  86. package/dist/types/tests/base/match.d.ts +9 -0
  87. package/dist/types/tests/base/match.d.ts.map +1 -0
  88. package/dist/types/tests/core/backend.test.d.ts +2 -0
  89. package/dist/types/tests/core/backend.test.d.ts.map +1 -0
  90. package/dist/types/tests/core/behavior.test.d.ts +2 -0
  91. package/dist/types/tests/core/behavior.test.d.ts.map +1 -0
  92. package/dist/types/tests/core/component_space.test.d.ts +2 -0
  93. package/dist/types/tests/core/component_space.test.d.ts.map +1 -0
  94. package/dist/types/tests/core/data_update.test.d.ts +2 -0
  95. package/dist/types/tests/core/data_update.test.d.ts.map +1 -0
  96. package/dist/types/tests/core/misc.test.d.ts +2 -0
  97. package/dist/types/tests/core/misc.test.d.ts.map +1 -0
  98. package/dist/types/tests/core/placeholder.test.d.ts +2 -0
  99. package/dist/types/tests/core/placeholder.test.d.ts.map +1 -0
  100. package/dist/types/tests/core/slot.test.d.ts +2 -0
  101. package/dist/types/tests/core/slot.test.d.ts.map +1 -0
  102. package/dist/types/tests/core/trait_behaviors.test.d.ts +2 -0
  103. package/dist/types/tests/core/trait_behaviors.test.d.ts.map +1 -0
  104. package/dist/types/tests/tmpl/binding_map.test.d.ts +2 -0
  105. package/dist/types/tests/tmpl/binding_map.test.d.ts.map +1 -0
  106. package/dist/types/tests/tmpl/event.test.d.ts +2 -0
  107. package/dist/types/tests/tmpl/event.test.d.ts.map +1 -0
  108. package/dist/types/tests/tmpl/expression.test.d.ts +2 -0
  109. package/dist/types/tests/tmpl/expression.test.d.ts.map +1 -0
  110. package/dist/types/tests/tmpl/lvalue.test.d.ts +2 -0
  111. package/dist/types/tests/tmpl/lvalue.test.d.ts.map +1 -0
  112. package/dist/types/tests/tmpl/native_rendering.test.d.ts +2 -0
  113. package/dist/types/tests/tmpl/native_rendering.test.d.ts.map +1 -0
  114. package/dist/types/tests/tmpl/structure.test.d.ts +2 -0
  115. package/dist/types/tests/tmpl/structure.test.d.ts.map +1 -0
  116. package/dist/types/tests/types/chaining.test.d.ts +2 -0
  117. package/dist/types/tests/types/chaining.test.d.ts.map +1 -0
  118. package/dist/types/tests/types/createElement.test.d.ts +2 -0
  119. package/dist/types/tests/types/createElement.test.d.ts.map +1 -0
  120. package/dist/types/tests/types/definition.test.d.ts +2 -0
  121. package/dist/types/tests/types/definition.test.d.ts.map +1 -0
  122. package/guide/zh_CN/advanced/binding_map_update.md +32 -0
  123. package/guide/zh_CN/advanced/build_args.md +28 -0
  124. package/guide/zh_CN/advanced/component_filter.md +70 -0
  125. package/guide/zh_CN/advanced/component_space.md +124 -0
  126. package/guide/zh_CN/advanced/custom_backend.md +53 -0
  127. package/guide/zh_CN/advanced/error_listener.md +32 -0
  128. package/guide/zh_CN/advanced/external_component.md +73 -0
  129. package/guide/zh_CN/advanced/template_engine.md +61 -0
  130. package/guide/zh_CN/appendix/backend_protocol.md +501 -0
  131. package/guide/zh_CN/appendix/list_diff_algorithm.md +406 -0
  132. package/guide/zh_CN/basic/beginning.md +94 -0
  133. package/guide/zh_CN/basic/component.md +156 -0
  134. package/guide/zh_CN/basic/event.md +169 -0
  135. package/guide/zh_CN/basic/lifetime.md +66 -0
  136. package/guide/zh_CN/basic/method.md +62 -0
  137. package/guide/zh_CN/basic/template.md +135 -0
  138. package/guide/zh_CN/data_management/advanced_update.md +170 -0
  139. package/guide/zh_CN/data_management/data_deep_copy.md +157 -0
  140. package/guide/zh_CN/data_management/data_observer.md +154 -0
  141. package/guide/zh_CN/data_management/property_early_init.md +31 -0
  142. package/guide/zh_CN/data_management/pure_data_pattern.md +21 -0
  143. package/guide/zh_CN/index.md +93 -0
  144. package/guide/zh_CN/interaction/behavior.md +52 -0
  145. package/guide/zh_CN/interaction/component_path.md +37 -0
  146. package/guide/zh_CN/interaction/generic.md +73 -0
  147. package/guide/zh_CN/interaction/placeholder.md +40 -0
  148. package/guide/zh_CN/interaction/relation.md +151 -0
  149. package/guide/zh_CN/interaction/slot.md +137 -0
  150. package/guide/zh_CN/interaction/template_import.md +94 -0
  151. package/guide/zh_CN/interaction/trait_behavior.md +117 -0
  152. package/guide/zh_CN/styling/external_class.md +46 -0
  153. package/guide/zh_CN/styling/style_isolation.md +54 -0
  154. package/guide/zh_CN/styling/virtual_host.md +52 -0
  155. package/guide/zh_CN/tree/element_iterator.md +54 -0
  156. package/guide/zh_CN/tree/mutation_observer.md +52 -0
  157. package/guide/zh_CN/tree/node_tree.md +142 -0
  158. package/guide/zh_CN/tree/node_tree_modification.md +78 -0
  159. package/guide/zh_CN/tree/selector.md +66 -0
  160. package/jest.config.js +6 -0
  161. package/jest.dts.config.js +9 -0
  162. package/jest.unit.config.js +14 -0
  163. package/package.json +28 -0
  164. package/src/backend/backend_protocol.ts +313 -0
  165. package/src/backend/composed_backend_protocol.ts +252 -0
  166. package/src/backend/domlike_backend_protocol.ts +370 -0
  167. package/src/backend/mode.ts +51 -0
  168. package/src/backend/suggested_backend_protocol.ts +83 -0
  169. package/src/behavior.ts +1655 -0
  170. package/src/bootstrap_dom_dev.js +22 -0
  171. package/src/class_list.ts +376 -0
  172. package/src/component.ts +1309 -0
  173. package/src/component_params.ts +461 -0
  174. package/src/component_space.ts +547 -0
  175. package/src/data_path.ts +225 -0
  176. package/src/data_proxy.ts +670 -0
  177. package/src/data_utils.ts +50 -0
  178. package/src/element.ts +1966 -0
  179. package/src/element_iterator.ts +158 -0
  180. package/src/event.ts +401 -0
  181. package/src/external_shadow_tree.ts +27 -0
  182. package/src/func_arr.ts +198 -0
  183. package/src/global_options.ts +242 -0
  184. package/src/index.ts +187 -0
  185. package/src/mutation_observer.ts +252 -0
  186. package/src/native_node.ts +74 -0
  187. package/src/node.ts +174 -0
  188. package/src/relation.ts +380 -0
  189. package/src/render.ts +25 -0
  190. package/src/selector.ts +218 -0
  191. package/src/shadow_root.ts +766 -0
  192. package/src/template_engine.ts +45 -0
  193. package/src/text_node.ts +149 -0
  194. package/src/tmpl/index.ts +199 -0
  195. package/src/tmpl/native_rendering.ts +175 -0
  196. package/src/tmpl/proc_gen_wrapper.ts +954 -0
  197. package/src/tmpl/proc_gen_wrapper_dom.ts +230 -0
  198. package/src/tmpl/range_list_diff.ts +443 -0
  199. package/src/trait_behaviors.ts +51 -0
  200. package/src/virtual_node.ts +51 -0
  201. package/tests/backend/domlike.test.ts +254 -0
  202. package/tests/base/env.ts +78 -0
  203. package/tests/base/match.ts +185 -0
  204. package/tests/core/backend.test.ts +144 -0
  205. package/tests/core/behavior.test.ts +546 -0
  206. package/tests/core/component_space.test.ts +212 -0
  207. package/tests/core/data_update.test.ts +461 -0
  208. package/tests/core/misc.test.ts +339 -0
  209. package/tests/core/placeholder.test.ts +180 -0
  210. package/tests/core/slot.test.ts +1495 -0
  211. package/tests/core/trait_behaviors.test.ts +153 -0
  212. package/tests/legacy/README.md +3 -0
  213. package/tests/legacy/behavior.test.js +293 -0
  214. package/tests/legacy/component.test.js +1247 -0
  215. package/tests/legacy/data_path.test.js +149 -0
  216. package/tests/legacy/data_proxy.test.js +759 -0
  217. package/tests/legacy/element_iterator.test.js +148 -0
  218. package/tests/legacy/event.test.js +849 -0
  219. package/tests/legacy/external.test.js +510 -0
  220. package/tests/legacy/extra_info.test.js +109 -0
  221. package/tests/legacy/generics.test.js +176 -0
  222. package/tests/legacy/mutation_observer.test.js +210 -0
  223. package/tests/legacy/relation.test.js +517 -0
  224. package/tests/legacy/selector.test.js +263 -0
  225. package/tests/legacy/slot.test.js +915 -0
  226. package/tests/legacy/virtual.test.js +394 -0
  227. package/tests/tmpl/binding_map.test.ts +208 -0
  228. package/tests/tmpl/event.test.ts +206 -0
  229. package/tests/tmpl/expression.test.ts +429 -0
  230. package/tests/tmpl/lvalue.test.ts +160 -0
  231. package/tests/tmpl/native_rendering.test.ts +155 -0
  232. package/tests/tmpl/structure.test.ts +998 -0
  233. package/tests/types/chaining.test.ts +614 -0
  234. package/tests/types/createElement.test.ts +82 -0
  235. package/tests/types/definition.test.ts +442 -0
  236. package/tsconfig.json +11 -0
  237. package/webpack.config.js +270 -0
@@ -0,0 +1,160 @@
1
+ import { tmpl, domBackend } from '../base/env'
2
+ import * as glassEasel from '../../src'
3
+
4
+ const domHtml = (elem: glassEasel.Element): string => {
5
+ const domElem = elem.getBackendElement() as unknown as Element
6
+ return domElem.innerHTML
7
+ }
8
+
9
+ describe('model value binding', () => {
10
+ test('model value binding on single data path', () => {
11
+ let updateCount = 0
12
+ const subComp = glassEasel.registerElement({
13
+ template: tmpl(`
14
+ <div id="a" data-a="{{ propA }}">
15
+ <slot />
16
+ </div>
17
+ `),
18
+ properties: {
19
+ propA: Number,
20
+ },
21
+ observers: {
22
+ propA() {
23
+ updateCount += 1
24
+ },
25
+ },
26
+ })
27
+ const def = glassEasel.registerElement({
28
+ using: {
29
+ comp: subComp.general(),
30
+ },
31
+ template: tmpl(`
32
+ <comp id="comp" model:prop-a="{{ a.b[c] }}">{{a.b[c]}}</comp>
33
+ `),
34
+ data: {
35
+ a: {
36
+ b: [10, 100],
37
+ },
38
+ c: 0,
39
+ },
40
+ })
41
+ const elem = glassEasel.Component.createWithContext('root', def, domBackend)
42
+ const comp = elem.getShadowRoot()!.getElementById('comp')! as glassEasel.GeneralComponent
43
+ expect(domHtml(elem)).toBe('<comp><div>10</div></comp>')
44
+ expect(updateCount).toBe(1)
45
+ expect(comp.getShadowRoot()!.getElementById('a')!.dataset!.a).toBe(10)
46
+ comp.setData({ propA: 20 })
47
+ expect(domHtml(elem)).toBe('<comp><div>20</div></comp>')
48
+ expect(updateCount).toBe(3)
49
+ expect(comp.getShadowRoot()!.getElementById('a')!.dataset!.a).toBe(20)
50
+ expect(elem.data.a).toEqual({ b: [20, 100] })
51
+ elem.setData({ 'a.b[0]': 30 })
52
+ expect(domHtml(elem)).toBe('<comp><div>30</div></comp>')
53
+ expect(updateCount).toBe(4)
54
+ expect(comp.getShadowRoot()!.getElementById('a')!.dataset!.a).toBe(30)
55
+ elem.setData({ 'a.b[1]': 200 })
56
+ expect(updateCount).toBe(4)
57
+ elem.setData({ c: 1 })
58
+ expect(domHtml(elem)).toBe('<comp><div>200</div></comp>')
59
+ expect(updateCount).toBe(5)
60
+ expect(comp.getShadowRoot()!.getElementById('a')!.dataset!.a).toBe(200)
61
+ comp.setData({ propA: 300 })
62
+ expect(domHtml(elem)).toBe('<comp><div>300</div></comp>')
63
+ expect(updateCount).toBe(7)
64
+ expect(comp.getShadowRoot()!.getElementById('a')!.dataset!.a).toBe(300)
65
+ expect(elem.data.a).toEqual({ b: [30, 300] })
66
+ })
67
+
68
+ test('model value binding on for items', () => {
69
+ const subComp = glassEasel.registerElement({
70
+ template: tmpl('{{propB}}:{{propA}}'),
71
+ properties: {
72
+ propA: String,
73
+ propB: Number,
74
+ },
75
+ })
76
+ const def = glassEasel.registerElement({
77
+ using: {
78
+ comp: subComp.general(),
79
+ },
80
+ template: tmpl(`
81
+ <block wx:for="{{list}}">
82
+ <comp id="comp{{index}}" model:prop-a="{{ item.a }}" model:prop-b="{{ list[index + 1 - 1].b }}"></comp>
83
+ </block>
84
+ `),
85
+ data: {
86
+ list: [{
87
+ a: 'X',
88
+ b: 123,
89
+ }, {
90
+ a: 'Y',
91
+ b: 456,
92
+ }],
93
+ },
94
+ })
95
+ const elem = glassEasel.Component.createWithContext('root', def, domBackend)
96
+ const comp0 = elem.getShadowRoot()!.getElementById('comp0')! as glassEasel.GeneralComponent
97
+ const comp1 = elem.getShadowRoot()!.getElementById('comp1')! as glassEasel.GeneralComponent
98
+ expect(domHtml(elem)).toBe('<comp>123:X</comp><comp>456:Y</comp>')
99
+ comp0.setData({ propA: 'X0', propB: 1230 })
100
+ expect(domHtml(elem)).toBe('<comp>1230:X0</comp><comp>456:Y</comp>')
101
+ expect(elem.data.list).toEqual([{ a: 'X0', b: 1230 }, { a: 'Y', b: 456 }])
102
+ comp1.setData({ propA: 'Y0', propB: 4560 })
103
+ expect(domHtml(elem)).toBe('<comp>1230:X0</comp><comp>4560:Y0</comp>')
104
+ expect(elem.data.list).toEqual([{ a: 'X0', b: 1230 }, { a: 'Y0', b: 4560 }])
105
+ elem.setData({ list: [{ a: 'Z', b: 789 }] })
106
+ expect(domHtml(elem)).toBe('<comp>789:Z</comp>')
107
+ })
108
+
109
+ test('nested model value bindings', () => {
110
+ const subCompA = glassEasel.registerElement({
111
+ template: tmpl(`
112
+ <div>{{propA}}</div>
113
+ `),
114
+ properties: {
115
+ propA: Number,
116
+ },
117
+ })
118
+ const subCompB = glassEasel.registerElement({
119
+ using: {
120
+ comp: subCompA.general(),
121
+ },
122
+ template: tmpl(`
123
+ <comp id="comp" model:prop-a="{{ propB }}"></comp>
124
+ `),
125
+ properties: {
126
+ propB: Number,
127
+ },
128
+ })
129
+ const def = glassEasel.registerElement({
130
+ using: {
131
+ comp: subCompB.general(),
132
+ },
133
+ template: tmpl(`
134
+ <comp id="comp" model:prop-b="{{ b }}"></comp>
135
+ `),
136
+ data: {
137
+ b: 123,
138
+ },
139
+ })
140
+ const elem = glassEasel.Component.createWithContext('root', def, domBackend)
141
+ const compB = elem.getShadowRoot()!.getElementById('comp')!.asInstanceOf(subCompB)!
142
+ const compA = compB.getShadowRoot()!.getElementById('comp')!.asInstanceOf(subCompA)!
143
+ expect(domHtml(elem)).toBe('<comp><comp><div>123</div></comp></comp>')
144
+ compA.setData({ propA: 45 })
145
+ expect(domHtml(elem)).toBe('<comp><comp><div>45</div></comp></comp>')
146
+ expect(elem.data.b).toBe(45)
147
+ expect(compB.data.propB).toBe(45)
148
+ expect(compA.data.propA).toBe(45)
149
+ compB.setData({ propB: 67 })
150
+ expect(domHtml(elem)).toBe('<comp><comp><div>67</div></comp></comp>')
151
+ expect(elem.data.b).toBe(67)
152
+ expect(compB.data.propB).toBe(67)
153
+ expect(compA.data.propA).toBe(67)
154
+ elem.setData({ b: 89 })
155
+ expect(domHtml(elem)).toBe('<comp><comp><div>89</div></comp></comp>')
156
+ expect(elem.data.b).toBe(89)
157
+ expect(compB.data.propB).toBe(89)
158
+ expect(compA.data.propA).toBe(89)
159
+ })
160
+ })
@@ -0,0 +1,155 @@
1
+ import { tmpl, domBackend } from '../base/env'
2
+ import * as glassEasel from '../../src'
3
+
4
+ const domHtml = (elem: glassEasel.Element): string => {
5
+ const domElem = elem.getBackendElement() as unknown as Element
6
+ return domElem.innerHTML
7
+ }
8
+
9
+ describe('native rendering mode', () => {
10
+ test('basic tree building', () => {
11
+ const def = glassEasel.registerElement({
12
+ options: { externalComponent: true },
13
+ template: tmpl(`
14
+ <div class="{{a}}" hidden="{{hidden}}" custom-attr="{{b}}">
15
+ <span style="color: red" custom-attr="v"> {{a}} </span>
16
+ </div>
17
+ `),
18
+ data: {
19
+ a: 'A',
20
+ b: false,
21
+ hidden: true,
22
+ },
23
+ })
24
+ const elem = glassEasel.Component.createWithContext('root', def.general(), domBackend)
25
+ expect(elem.$$).toBeInstanceOf(Element)
26
+ expect(domHtml(elem)).toBe('<div class="A" hidden=""><span style="color: red" custom-attr="v"> A </span></div><virtual></virtual>')
27
+ elem.setData({
28
+ a: 'BB',
29
+ b: true,
30
+ hidden: false,
31
+ })
32
+ expect(domHtml(elem)).toBe('<div class="BB" custom-attr=""><span style="color: red" custom-attr="v"> BB </span></div><virtual></virtual>')
33
+ })
34
+
35
+ test('slot shrinking', () => {
36
+ const subComp = glassEasel.registerElement({
37
+ options: { externalComponent: true },
38
+ template: tmpl(`
39
+ <div>{{a}}<span><slot /></span></div>
40
+ `),
41
+ properties: {
42
+ a: Number,
43
+ },
44
+ })
45
+ const def = glassEasel.registerElement({
46
+ using: {
47
+ comp: subComp.general(),
48
+ },
49
+ template: tmpl(`
50
+ <comp id="comp" a="{{c + 1}}">{{c}}</comp>
51
+ `),
52
+ data: {
53
+ c: 1,
54
+ },
55
+ })
56
+ const elem = glassEasel.Component.createWithContext('root', def.general(), domBackend)
57
+ expect(domHtml(elem)).toBe('<comp><div>2<span>1</span></div></comp>')
58
+ elem.setData({
59
+ c: 10,
60
+ })
61
+ expect(domHtml(elem)).toBe('<comp><div>11<span>10</span></div></comp>')
62
+ })
63
+
64
+ test('slot appending', () => {
65
+ const subComp = glassEasel.registerElement({
66
+ options: { externalComponent: true },
67
+ template: tmpl(`
68
+ <div>{{a}}<span></span></div>
69
+ `),
70
+ properties: {
71
+ a: String,
72
+ },
73
+ })
74
+ const def = glassEasel.registerElement({
75
+ using: {
76
+ comp: subComp.general(),
77
+ },
78
+ template: tmpl(`
79
+ <comp a="c{{c}}">{{c}}</comp>
80
+ `),
81
+ data: {
82
+ c: 'A',
83
+ },
84
+ })
85
+ const elem = glassEasel.Component.createWithContext('root', def.general(), domBackend)
86
+ expect(domHtml(elem)).toBe('<comp><div>cA<span></span></div><virtual>A</virtual></comp>')
87
+ elem.setData({
88
+ c: 'B',
89
+ })
90
+ expect(domHtml(elem)).toBe('<comp><div>cB<span></span></div><virtual>B</virtual></comp>')
91
+ })
92
+
93
+ test('default template', () => {
94
+ const subComp = glassEasel.registerElement({
95
+ options: { externalComponent: true },
96
+ })
97
+ const def = glassEasel.registerElement({
98
+ using: {
99
+ comp: subComp,
100
+ },
101
+ template: tmpl(`
102
+ <comp>{{c}}</comp>
103
+ `),
104
+ data: {
105
+ c: 123,
106
+ },
107
+ })
108
+ const elem = glassEasel.Component.createWithContext('root', def.general(), domBackend)
109
+ expect(domHtml(elem)).toBe('<comp>123</comp>')
110
+ elem.setData({
111
+ c: 'ABC',
112
+ })
113
+ expect(domHtml(elem)).toBe('<comp>ABC</comp>')
114
+ })
115
+
116
+ test('event handling', () => {
117
+ const ops: number[] = []
118
+ const def = glassEasel.registerElement({
119
+ options: {
120
+ externalComponent: true,
121
+ },
122
+ template: tmpl(`
123
+ <div id="outer" bind:touchstart="outerStart" bind:touchend="outerEnd">
124
+ <span id="inner" bind:touchstart="innerStart" bind:touchend="innerEnd">
125
+ <slot />
126
+ </span>
127
+ </div>
128
+ `),
129
+ methods: {
130
+ outerStart() {
131
+ ops.push(1)
132
+ },
133
+ innerStart() {
134
+ ops.push(2)
135
+ },
136
+ outerEnd() {
137
+ throw new Error('unreachable')
138
+ },
139
+ innerEnd() {
140
+ ops.push(3)
141
+ return false
142
+ },
143
+ },
144
+ })
145
+ const elem = glassEasel.Component.createWithContext('root', def.general(), domBackend)
146
+ expect(domHtml(elem)).toBe('<div><span></span></div>')
147
+ const evOps = {
148
+ bubbles: true,
149
+ composed: true,
150
+ }
151
+ glassEasel.triggerExternalEvent(elem, elem.$.inner as glassEasel.GeneralBackendElement, 'touchstart', {}, evOps)
152
+ glassEasel.triggerExternalEvent(elem, elem.$.inner as glassEasel.GeneralBackendElement, 'touchend', {}, evOps)
153
+ expect(ops).toStrictEqual([2, 1, 3])
154
+ })
155
+ })