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,849 @@
1
+ /* eslint-disable */
2
+
3
+ const { tmpl, domBackend, shadowBackend } = require('../base/env')
4
+ const glassEasel = require('../../src')
5
+
6
+ const componentSpace = new glassEasel.ComponentSpace()
7
+ componentSpace.updateComponentOptions({
8
+ writeFieldsToNode: true,
9
+ })
10
+ componentSpace.defineComponent({
11
+ is: '',
12
+ })
13
+
14
+ const regBeh = (config) => {
15
+ return componentSpace.defineBehavior(config)
16
+ }
17
+
18
+ const regElem = (config) => {
19
+ const { template, ...c } = config
20
+ if (template) c.template = tmpl(template)
21
+ return componentSpace.defineComponent(c)
22
+ }
23
+
24
+ const createElem = (is, backend) => {
25
+ const def = componentSpace.getComponent(is)
26
+ return glassEasel.Component.createWithContext(is || 'test', def, backend || domBackend)
27
+ }
28
+
29
+ const addListenerToElement = (elem, tagName, f, options) => {
30
+ elem.addListener(tagName, f, options)
31
+ return f
32
+ }
33
+
34
+ const removeListenerFromElement = (elem, tagName, f, options) => {
35
+ elem.removeListener(tagName, f, options)
36
+ }
37
+
38
+ const setListenerToElementNative = (owner, elem, tagName, f, options) => {
39
+ return owner.shadowRoot.setListener(elem, tagName, f, options)
40
+ }
41
+
42
+ describe('Events', function(){
43
+ var root = null
44
+
45
+ beforeAll(function(){
46
+ root = createElem('root')
47
+ root.$$.id = 'root'
48
+ var backendRoot = domBackend.getRootNode()
49
+ var placeholder = domBackend.document.createElement('div')
50
+ backendRoot.appendChild(placeholder)
51
+ glassEasel.Element.replaceDocumentElement(root, backendRoot, placeholder)
52
+ regElem({
53
+ is: 'events-full',
54
+ template: '<div id="wrapper"><span id="inner"></span><slot></slot></div>'
55
+ })
56
+ regElem({
57
+ is: 'events-native',
58
+ options: {
59
+ externalComponent: true,
60
+ },
61
+ template: '<div id="wrapper"><span id="inner"></span><slot></slot></div>'
62
+ })
63
+ })
64
+
65
+ describe('#addListenerToElement', function(){
66
+
67
+ it('should attach listeners to full-rendering elements', function(){
68
+ var elem = createElem('events-full')
69
+ var callOrder = []
70
+ addListenerToElement(elem, 'customevent', function(e){
71
+ callOrder.push(1)
72
+ expect(e.target).toBe(this)
73
+ expect(e.type).toBe('customevent')
74
+ expect(e.detail).toStrictEqual({a: 1})
75
+ expect(e.a).toBe(2)
76
+ })
77
+ addListenerToElement(elem.shadowRoot, 'customevent', function(e){
78
+ callOrder.push(2)
79
+ expect(e.target).toBe(elem.$.inner)
80
+ expect(e.type).toBe('customevent')
81
+ expect(e.detail).toStrictEqual({a: 1})
82
+ expect(e.a).toBe(2)
83
+ })
84
+ addListenerToElement(elem.$.wrapper, 'customevent', function(e){
85
+ callOrder.push(3)
86
+ expect(e.target).toBe(elem.$.inner)
87
+ expect(e.type).toBe('customevent')
88
+ expect(e.detail).toStrictEqual({a: 1})
89
+ expect(e.a).toBe(2)
90
+ })
91
+ addListenerToElement(elem.$.inner, 'customevent', function(e){
92
+ callOrder.push(4)
93
+ expect(e.target).toBe(this)
94
+ expect(e.type).toBe('customevent')
95
+ expect(e.detail).toStrictEqual({a: 1})
96
+ expect(e.a).toBe(2)
97
+ })
98
+ glassEasel.triggerEvent(elem.$.inner, 'customevent', {a: 1}, {bubbles: true, composed: true, extraFields: {a: 2}})
99
+ expect(callOrder).toStrictEqual([4, 3, 2, 1])
100
+ })
101
+
102
+ it('should attach listeners to native-rendering elements', function(){
103
+ var elem = createElem('events-native')
104
+ var callOrder = []
105
+ addListenerToElement(elem, 'customevent', function(e){
106
+ callOrder.push(1)
107
+ expect(e.target).toBeInstanceOf(glassEasel.Element)
108
+ expect(e.target).toBe(this)
109
+ expect(e.type).toBe('customevent')
110
+ expect(e.detail).toStrictEqual({a: 1})
111
+ expect(e.a).toBe(2)
112
+ })
113
+ setListenerToElementNative(elem, elem.shadowRoot.root, 'customevent', function(e){
114
+ callOrder.push(2)
115
+ expect(e.target).toBeInstanceOf(window.HTMLSpanElement)
116
+ expect(e.target).toBe(elem.$.inner)
117
+ expect(e.type).toBe('customevent')
118
+ expect(e.detail).toStrictEqual({a: 1})
119
+ expect(e.a).toBe(2)
120
+ })
121
+ setListenerToElementNative(elem, elem.$.wrapper, 'customevent', function(e){
122
+ callOrder.push(3)
123
+ expect(e.target).toBe(elem.$.inner)
124
+ expect(e.type).toBe('customevent')
125
+ expect(e.detail).toStrictEqual({a: 1})
126
+ expect(e.a).toBe(2)
127
+ })
128
+ setListenerToElementNative(elem, elem.$.inner, 'customevent', function(e){
129
+ callOrder.push(4)
130
+ expect(e.target).toBe(this)
131
+ expect(e.type).toBe('customevent')
132
+ expect(e.detail).toStrictEqual({a: 1})
133
+ expect(e.a).toBe(2)
134
+ })
135
+ glassEasel.triggerExternalEvent(elem, elem.$.inner, 'customevent', {a: 1}, {bubbles: true, composed: true, extraFields: {a: 2}})
136
+ expect(callOrder).toStrictEqual([4, 3, 2, 1])
137
+ })
138
+
139
+ })
140
+
141
+ describe('#removeListenerFromElement', function(){
142
+
143
+ it('should remove listeners', function(){
144
+ var elem = createElem('events-full')
145
+ var eventsLeft = 1
146
+ var f = function(){
147
+ eventsLeft--
148
+ }
149
+ addListenerToElement(elem, 'customevent', f)
150
+ var b2 = function(){
151
+ throw(new Error())
152
+ }
153
+ addListenerToElement(elem, 'customevent', b2)
154
+ removeListenerFromElement(elem, 'customevent', b2)
155
+ glassEasel.triggerEvent(elem, 'customevent', undefined, {bubbles: true, composed: true})
156
+ removeListenerFromElement(elem, 'customevent', f)
157
+ glassEasel.triggerEvent(elem, 'customevent', undefined, {bubbles: true, composed: true})
158
+ expect(eventsLeft).toBe(0)
159
+ })
160
+
161
+ })
162
+
163
+ describe('#triggerEvent', function(){
164
+
165
+ it('should trigger global events', function(){
166
+ var elem = createElem('events-full')
167
+ var child = createElem('events-native')
168
+ elem.appendChild(child)
169
+ var callOrder = []
170
+ addListenerToElement(elem, 'customevent', function(e){
171
+ callOrder.push(1)
172
+ expect(e.target).toBe(child)
173
+ })
174
+ addListenerToElement(elem.shadowRoot, 'customevent', function(e){
175
+ callOrder.push(2)
176
+ expect(e.target).toBe(elem.$.wrapper.childNodes[1])
177
+ })
178
+ addListenerToElement(elem.$.wrapper, 'customevent', function(e){
179
+ callOrder.push(3)
180
+ expect(e.target).toBe(elem.$.wrapper.childNodes[1])
181
+ })
182
+ addListenerToElement(elem.$.inner, 'customevent', function(e){
183
+ callOrder.push(4)
184
+ expect(e.target).toBe(elem.$.wrapper.childNodes[1])
185
+ })
186
+ addListenerToElement(child, 'customevent', function(e){
187
+ callOrder.push(5)
188
+ expect(e.target).toBe(this)
189
+ })
190
+ setListenerToElementNative(child, child.shadowRoot.root, 'customevent', function(e){
191
+ callOrder.push(6)
192
+ expect(e.target).toBe(child.$.inner)
193
+ })
194
+ setListenerToElementNative(child, child.$.wrapper, 'customevent', function(e){
195
+ callOrder.push(7)
196
+ expect(e.target).toBe(child.$.inner)
197
+ })
198
+ setListenerToElementNative(child, child.$.inner, 'customevent', function(e){
199
+ callOrder.push(8)
200
+ expect(e.target).toBe(this)
201
+ })
202
+ glassEasel.triggerExternalEvent(child, child.$.inner, 'customevent', undefined, {bubbles: true, composed: true})
203
+ expect(callOrder).toStrictEqual([8, 7, 6, 5, 3, 2, 1])
204
+ })
205
+
206
+ it('should trigger non-global events', function(){
207
+ var elem = createElem('events-full')
208
+ var child = createElem('events-native')
209
+ elem.appendChild(child)
210
+ var callOrder = []
211
+ addListenerToElement(elem, 'customevent', function(e){
212
+ callOrder.push(1)
213
+ expect(e.target).toBe(child)
214
+ })
215
+ addListenerToElement(elem.shadowRoot, 'customevent', function(e){
216
+ callOrder.push(2)
217
+ expect(e.target).toBe(elem.$.inner)
218
+ })
219
+ addListenerToElement(elem.$.wrapper, 'customevent', function(e){
220
+ callOrder.push(3)
221
+ expect(e.target).toBe(elem.$.inner)
222
+ })
223
+ addListenerToElement(elem.$.inner, 'customevent', function(e){
224
+ callOrder.push(4)
225
+ expect(e.target).toBe(elem.$.inner)
226
+ })
227
+ addListenerToElement(child, 'customevent', function(e){
228
+ callOrder.push(5)
229
+ expect(e.target).toBe(this)
230
+ })
231
+ setListenerToElementNative(child, child.shadowRoot.root, 'customevent', function(e){
232
+ callOrder.push(6)
233
+ expect(e.target).toBe(child.$.inner)
234
+ })
235
+ setListenerToElementNative(child, child.$.wrapper, 'customevent', function(e){
236
+ callOrder.push(7)
237
+ expect(e.target).toBe(child.$.inner)
238
+ })
239
+ setListenerToElementNative(child, child.$.inner, 'customevent', function(e){
240
+ callOrder.push(8)
241
+ expect(e.target).toBe(this)
242
+ })
243
+ glassEasel.triggerEvent(elem.$.inner, 'customevent', undefined, {bubbles: true})
244
+ glassEasel.triggerExternalEvent(child, child.$.inner, 'customevent', undefined, {bubbles: true})
245
+ glassEasel.triggerEvent(child, 'customevent', undefined, {bubbles: true})
246
+ expect(callOrder).toStrictEqual([4, 3, 2, 8, 7, 6, 5, 1])
247
+ })
248
+
249
+ it('should trigger non-bubble events', function(){
250
+ var elem = createElem('events-full')
251
+ var child = createElem('events-native')
252
+ elem.appendChild(child)
253
+ var callOrder = []
254
+ addListenerToElement(elem, 'customevent', function(e){
255
+ callOrder.push(1)
256
+ })
257
+ addListenerToElement(elem.shadowRoot, 'customevent', function(e){
258
+ callOrder.push(2)
259
+ expect(e.target).toBe(this)
260
+ })
261
+ addListenerToElement(elem.$.wrapper, 'customevent', function(e){
262
+ callOrder.push(3)
263
+ })
264
+ addListenerToElement(elem.$.inner, 'customevent', function(e){
265
+ callOrder.push(4)
266
+ })
267
+ addListenerToElement(child, 'customevent', function(e){
268
+ callOrder.push(5)
269
+ expect(e.target).toBe(this)
270
+ })
271
+ setListenerToElementNative(child, child.shadowRoot.root, 'customevent', function(e){
272
+ callOrder.push(6)
273
+ expect(e.target).toBe(this)
274
+ })
275
+ setListenerToElementNative(child, child.$.wrapper, 'customevent', function(e){
276
+ callOrder.push(7)
277
+ })
278
+ setListenerToElementNative(child, child.$.inner, 'customevent', function(e){
279
+ callOrder.push(8)
280
+ })
281
+ glassEasel.triggerEvent(elem.shadowRoot, 'customevent')
282
+ glassEasel.triggerExternalEvent(child, child.shadowRoot.root, 'customevent')
283
+ glassEasel.triggerEvent(child, 'customevent')
284
+ expect(callOrder).toStrictEqual([2, 6, 5])
285
+ })
286
+
287
+ it('should be able to interrupt bubble', function(){
288
+ var elem = createElem('events-full')
289
+ var child = createElem('events-full')
290
+ elem.appendChild(child)
291
+ var waitingEvents = 1
292
+ addListenerToElement(child, 'customevent', function(){
293
+ waitingEvents--
294
+ return false
295
+ })
296
+ addListenerToElement(elem, 'customevent', function(){
297
+ waitingEvents--
298
+ })
299
+ glassEasel.triggerEvent(child, 'customevent', undefined, {bubbles: true, composed: true})
300
+ expect(waitingEvents).toBe(0)
301
+ })
302
+
303
+ it('should convert event target correctly (in full mode)', function(){
304
+ var e1 = createElem('events-full')
305
+ var e2 = createElem('events-full')
306
+ var e3 = createElem('events-full')
307
+ e1.appendChild(e2)
308
+ e2.appendChild(e3)
309
+ var callOrder = []
310
+ addListenerToElement(e1, 'customevent', function(e){
311
+ callOrder.push(1)
312
+ expect(e.target).toBe(e3)
313
+ })
314
+ addListenerToElement(e2, 'customevent', function(e){
315
+ callOrder.push(2)
316
+ expect(e.target).toBe(e3)
317
+ })
318
+ addListenerToElement(e2.$.wrapper, 'customevent', function(e){
319
+ callOrder.push(3)
320
+ expect(e.target).toBe(e2.$.wrapper.childNodes[1])
321
+ })
322
+ addListenerToElement(e3, 'customevent', function(e){
323
+ callOrder.push(4)
324
+ expect(e.target).toBe(e3)
325
+ })
326
+ addListenerToElement(e3.$.wrapper, 'customevent', function(e){
327
+ callOrder.push(5)
328
+ expect(e.target).toBe(e3.$.inner)
329
+ })
330
+ glassEasel.triggerEvent(e3.$.inner, 'customevent', undefined, {bubbles: true, composed: true})
331
+ expect(callOrder).toStrictEqual([5, 4, 3, 2, 1])
332
+ })
333
+
334
+ it('should convert event target correctly (in native mode)', function(){
335
+ var e1 = createElem('events-native')
336
+ var e2 = createElem('events-native')
337
+ var e3 = createElem('events-native')
338
+ e1.appendChild(e2)
339
+ e2.appendChild(e3)
340
+ var callOrder = []
341
+ addListenerToElement(e1, 'customevent', function(e){
342
+ callOrder.push(1)
343
+ expect(e.target).toBe(e3)
344
+ })
345
+ addListenerToElement(e2, 'customevent', function(e){
346
+ callOrder.push(2)
347
+ expect(e.target).toBe(e3)
348
+ })
349
+ setListenerToElementNative(e2, e2.$.wrapper, 'customevent', function(e){
350
+ callOrder.push(3)
351
+ expect(e.target).toBe(e2.$.wrapper.childNodes[1])
352
+ })
353
+ addListenerToElement(e3, 'customevent', function(e){
354
+ callOrder.push(4)
355
+ expect(e.target).toBe(e3)
356
+ })
357
+ setListenerToElementNative(e3, e3.$.wrapper, 'customevent', function(e){
358
+ callOrder.push(5)
359
+ expect(e.target).toBe(e3.$.inner)
360
+ })
361
+ glassEasel.triggerExternalEvent(e3, e3.$.inner, 'customevent', undefined, {bubbles: true, composed: true})
362
+ expect(callOrder).toStrictEqual([5, 4, 3, 2, 1])
363
+ })
364
+
365
+ it('should convert event target correctly (in full and native mode)', function(){
366
+ regElem({
367
+ is: 'events-target-a',
368
+ options: {
369
+ renderingMode: 'full'
370
+ },
371
+ template: '<events-native id="inner"> <slot /> </events-native>'
372
+ })
373
+ regElem({
374
+ is: 'events-target-b',
375
+ options: {
376
+ renderingMode: 'full'
377
+ },
378
+ template: '<events-full id="inner"> <slot /> </events-full>'
379
+ })
380
+ regElem({
381
+ is: 'events-target-all',
382
+ options: {
383
+ renderingMode: 'full'
384
+ },
385
+ template: '<events-target-a id="a"> <events-target-b id="b"></events-target-b> </events-target-a>'
386
+ })
387
+ var e = createElem('events-target-all')
388
+ var es = e.shadowRoot
389
+ var eA = e.$.a
390
+ var eB = e.$.b
391
+ var eAs = eA.shadowRoot
392
+ var eASlot = eA.$.inner.childNodes[0]
393
+ var eBs = eB.shadowRoot
394
+ var eAi = eA.$.inner
395
+ var eBi = eB.$.inner
396
+ var eAw = eAi.$.wrapper
397
+ var eAwSlot = eA.$.inner.$.wrapper.childNodes[1]
398
+ var eBw = eBi.$.wrapper
399
+ var events = []
400
+ var targets = []
401
+
402
+ addListenerToElement(e, 'customevent', function(e){
403
+ expect('e').toBe(events.shift())
404
+ expect(e.target).toBe(targets.shift())
405
+ })
406
+ addListenerToElement(es, 'customevent', function(e){
407
+ expect('es').toBe(events.shift())
408
+ expect(e.target).toBe(targets.shift())
409
+ })
410
+ addListenerToElement(eA, 'customevent', function(e){
411
+ expect('eA').toBe(events.shift())
412
+ expect(e.target).toBe(targets.shift())
413
+ })
414
+ addListenerToElement(eB, 'customevent', function(e){
415
+ expect('eB').toBe(events.shift())
416
+ expect(e.target).toBe(targets.shift())
417
+ })
418
+ addListenerToElement(eAs, 'customevent', function(e){
419
+ expect('eAs').toBe(events.shift())
420
+ expect(e.target).toBe(targets.shift())
421
+ })
422
+ addListenerToElement(eBs, 'customevent', function(e){
423
+ expect('eBs').toBe(events.shift())
424
+ expect(e.target).toBe(targets.shift())
425
+ })
426
+ addListenerToElement(eAi, 'customevent', function(e){
427
+ expect('eAi').toBe(events.shift())
428
+ expect(e.target).toBe(targets.shift())
429
+ })
430
+ addListenerToElement(eBi, 'customevent', function(e){
431
+ expect('eBi').toBe(events.shift())
432
+ expect(e.target).toBe(targets.shift())
433
+ })
434
+ setListenerToElementNative(eAi, eAw, 'customevent', function(e){
435
+ expect('eAw').toBe(events.shift())
436
+ expect(e.target).toBe(targets.shift())
437
+ })
438
+ addListenerToElement(eBw, 'customevent', function(e){
439
+ expect('eBw').toBe(events.shift())
440
+ expect(e.target).toBe(targets.shift())
441
+ })
442
+
443
+ events = ['eAw', 'eAi', 'eAs', 'eA', 'es', 'e']
444
+ targets = [eAw, eAi, eAi, eA, eA, e]
445
+ glassEasel.triggerExternalEvent(eAi, eAw, 'customevent', undefined, {bubbles: true, composed: true})
446
+ expect(events.length + targets.length).toBe(0)
447
+
448
+ events = ['eBw', 'eBi', 'eBs', 'eB', 'eAw', 'eAi', 'eAs', 'eA', 'es', 'e']
449
+ targets = [eBw, eBi, eBi, eB, eAwSlot, eASlot, eASlot, eB, eB, e]
450
+ glassEasel.triggerEvent(eBw, 'customevent', undefined, {bubbles: true, composed: true})
451
+ expect(events.length + targets.length).toBe(0)
452
+ })
453
+
454
+ it('should bubble from shadowRoot', function(){
455
+ var e1 = createElem('events-full')
456
+ var e2 = createElem('events-full')
457
+ var e3 = createElem('events-native')
458
+ e1.appendChild(e2)
459
+ e2.appendChild(e3)
460
+ var events = []
461
+ var targets = []
462
+ addListenerToElement(e1, 'customevent', function(e){
463
+ expect('e1').toBe(events.shift())
464
+ expect(e.target).toBe(targets.shift())
465
+ })
466
+ addListenerToElement(e1.shadowRoot, 'customevent', function(e){
467
+ expect('e1s').toBe(events.shift())
468
+ expect(e.target).toBe(targets.shift())
469
+ })
470
+ addListenerToElement(e1.$.wrapper, 'customevent', function(e){
471
+ expect('e1w').toBe(events.shift())
472
+ expect(e.target).toBe(targets.shift())
473
+ })
474
+ addListenerToElement(e2, 'customevent', function(e){
475
+ expect('e2').toBe(events.shift())
476
+ expect(e.target).toBe(targets.shift())
477
+ })
478
+ addListenerToElement(e2.shadowRoot, 'customevent', function(e){
479
+ expect('e2s').toBe(events.shift())
480
+ expect(e.target).toBe(targets.shift())
481
+ })
482
+ addListenerToElement(e2.$.wrapper, 'customevent', function(e){
483
+ expect('e2w').toBe(events.shift())
484
+ expect(e.target).toBe(targets.shift())
485
+ })
486
+ addListenerToElement(e3, 'customevent', function(e){
487
+ expect('e3').toBe(events.shift())
488
+ expect(e.target).toBe(targets.shift())
489
+ })
490
+ setListenerToElementNative(e3, e3.shadowRoot.root, 'customevent', function(e){
491
+ expect('e3s').toBe(events.shift())
492
+ expect(e.target).toBe(targets.shift())
493
+ })
494
+ setListenerToElementNative(e3, e3.$.wrapper, 'customevent', function(e){
495
+ expect('e3w').toBe(events.shift())
496
+ expect(e.target).toBe(targets.shift())
497
+ })
498
+
499
+ events = ['e3s', 'e3', 'e2w', 'e2s', 'e2', 'e1w', 'e1s', 'e1']
500
+ targets = [e3.shadowRoot.root, e3, e2.$.wrapper.childNodes[1], e2.$.wrapper.childNodes[1], e3, e1.$.wrapper.childNodes[1], e1.$.wrapper.childNodes[1], e3]
501
+ glassEasel.triggerExternalEvent(e3, e3.shadowRoot.root, 'customevent', undefined, {bubbles: true, composed: true})
502
+ expect(events.length + targets.length).toBe(0)
503
+
504
+ events = ['e2s', 'e2', 'e1w', 'e1s', 'e1']
505
+ targets = [e2.shadowRoot, e2, e1.$.wrapper.childNodes[1], e1.$.wrapper.childNodes[1], e2]
506
+ glassEasel.triggerEvent(e2.shadowRoot, 'customevent', undefined, {bubbles: true, composed: true})
507
+ expect(events.length + targets.length).toBe(0)
508
+ })
509
+
510
+ it('should support capture phase', function(){
511
+ var e1 = createElem('events-full')
512
+ e1.id = 'e1'
513
+ var e2 = createElem('events-full')
514
+ e2.id = 'e2'
515
+ var e3 = createElem('events-full')
516
+ e3.id = 'e3'
517
+ e1.appendChild(e2)
518
+ e2.appendChild(e3)
519
+ var waitingEvents = 1
520
+ addListenerToElement(e1, 'customevent', function(e){
521
+ waitingEvents--
522
+ if(e.target === e2) return false
523
+ expect(e.target).toBe(e3)
524
+ }, {useCapture: true})
525
+ addListenerToElement(e2, 'customevent', function(e){
526
+ waitingEvents--
527
+ expect(e.target).toBe(e3)
528
+ }, {useCapture: true})
529
+ addListenerToElement(e2.$.wrapper, 'customevent', function(e){
530
+ waitingEvents--
531
+ expect(e.target).toBe(e2.$.wrapper.childNodes[1])
532
+ }, {useCapture: true})
533
+ addListenerToElement(e3.$.inner, 'customevent', function(e){
534
+ expect(waitingEvents).toBe(2)
535
+ waitingEvents--
536
+ expect(e.target).toBe(this)
537
+ }, {useCapture: true})
538
+ addListenerToElement(e3.$.inner, 'customevent', function(e){
539
+ expect(waitingEvents).toBe(1)
540
+ waitingEvents--
541
+ expect(e.target).toBe(this)
542
+ })
543
+ glassEasel.triggerEvent(e2.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
544
+ expect(waitingEvents).toBe(0)
545
+ waitingEvents = 5
546
+ glassEasel.triggerEvent(e3.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
547
+ expect(waitingEvents).toBe(0)
548
+ })
549
+
550
+ it('should contain marks', function(){
551
+ var e1 = createElem('events-full')
552
+ var e2 = createElem('events-full')
553
+ var e3 = createElem('events-native')
554
+ e1.appendChild(e2)
555
+ e2.appendChild(e3)
556
+ e1.$.wrapper.setMark('inner', 'in')
557
+ e1.setMark('p', 1)
558
+ e2.setMark('c', 2)
559
+ e3.setMark('c', 3)
560
+ var triggered = [false, false, false, false]
561
+ e1.addListener('custom', function(e) {
562
+ triggered[0] = true
563
+ expect(e.mark).toStrictEqual({ p: 1, c: e.target === e2 ? 2 : 3 })
564
+ })
565
+ e2.addListener('custom', function(e) {
566
+ triggered[1] = true
567
+ expect(e.mark).toStrictEqual({ p: 1, c: e.target === e2 ? 2 : 3 })
568
+ })
569
+ e3.addListener('custom', function(e) {
570
+ triggered[2] = true
571
+ expect(e.mark).toStrictEqual({ p: 1, c: 3 })
572
+ })
573
+ e1.shadowRoot.addListener('custom', function(e) {
574
+ triggered[3] = true
575
+ expect(e.mark).toStrictEqual({ inner: 'in' })
576
+ })
577
+ e3.triggerEvent('custom', {})
578
+ e2.triggerEvent('custom', {}, { bubbles: true })
579
+ e3.triggerEvent('custom', {}, { bubbles: true, composed: true, capturePhase: true })
580
+ expect(triggered).toStrictEqual([true, true, true, true])
581
+ })
582
+
583
+ it('should support mutated event', function(){
584
+ // bubble
585
+ var e1 = createElem('events-full')
586
+ var e2 = createElem('events-full')
587
+ var e3 = createElem('events-full')
588
+ var waitingEvents = 4
589
+ e1.appendChild(e2)
590
+ e2.appendChild(e3)
591
+
592
+ addListenerToElement(e1, 'customevent', function(e){
593
+ waitingEvents--
594
+ expect(e.mutatedMarked()).toBe(false)
595
+ }, {useCapture: true})
596
+ addListenerToElement(e1, 'customevent', function(e){
597
+ waitingEvents--
598
+ expect(e.mutatedMarked()).toBe(true)
599
+ })
600
+ addListenerToElement(e2, 'customevent', function(e){
601
+ waitingEvents--
602
+ expect(e.mutatedMarked()).toBe(false)
603
+ e.markMutated()
604
+ expect(e.mutatedMarked()).toBe(true)
605
+ })
606
+ addListenerToElement(e3, 'customevent', function(e){
607
+ waitingEvents--
608
+ expect(e.mutatedMarked()).toBe(false)
609
+ })
610
+ glassEasel.triggerEvent(e3.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
611
+ expect(waitingEvents).toBe(0)
612
+
613
+ // capture
614
+ e1 = createElem('events-full')
615
+ e2 = createElem('events-full')
616
+ e3 = createElem('events-full')
617
+ waitingEvents = 4
618
+ e1.appendChild(e2)
619
+ e2.appendChild(e3)
620
+
621
+ addListenerToElement(e1, 'customevent', function(e){
622
+ waitingEvents--
623
+ expect(e.mutatedMarked()).toBe(true)
624
+ })
625
+ addListenerToElement(e1, 'customevent', function(e){
626
+ waitingEvents--
627
+ expect(e.mutatedMarked()).toBe(false)
628
+ }, {useCapture: true})
629
+ addListenerToElement(e2, 'customevent', function(e){
630
+ waitingEvents--
631
+ expect(e.mutatedMarked()).toBe(false)
632
+ e.markMutated()
633
+ expect(e.mutatedMarked()).toBe(true)
634
+ }, {useCapture: true})
635
+ addListenerToElement(e3, 'customevent', function(e){
636
+ waitingEvents--
637
+ expect(e.mutatedMarked()).toBe(true)
638
+ }, {useCapture: true})
639
+ glassEasel.triggerEvent(e3.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
640
+ expect(waitingEvents).toBe(0)
641
+
642
+ // bubble: pass mutated option
643
+ e1 = createElem('events-full')
644
+ e2 = createElem('events-full')
645
+ e3 = createElem('events-full')
646
+ var e4 = createElem('events-full')
647
+ var e5 = createElem('events-full')
648
+ var triggerCount = 0
649
+ waitingEvents = 6
650
+ e1.appendChild(e2)
651
+ e2.appendChild(e3)
652
+ e3.appendChild(e4)
653
+ e4.appendChild(e5)
654
+ var id1, id2
655
+
656
+ addListenerToElement(e1, 'customevent', function(e){
657
+ waitingEvents--
658
+ expect(e.mutatedMarked()).toBe(false)
659
+ }, {useCapture: true})
660
+ addListenerToElement(e1, 'customevent', function(e){
661
+ waitingEvents--
662
+ expect(e.mutatedMarked()).toBe(true)
663
+ })
664
+ addListenerToElement(e2, 'customevent', function(e){
665
+ waitingEvents--
666
+ triggerCount++
667
+ expect(e.mutatedMarked()).toBe(false)
668
+ }, {mutated: true})
669
+ id1 = addListenerToElement(e3, 'customevent', function(e){
670
+ waitingEvents--
671
+ expect(e.mutatedMarked()).toBe(true)
672
+ })
673
+ id2 = addListenerToElement(e4, 'customevent', function(e){
674
+ waitingEvents--
675
+ expect(e.mutatedMarked()).toBe(false)
676
+ }, {mutated: true})
677
+ addListenerToElement(e4, 'customevent', function(e){
678
+ waitingEvents--
679
+ expect(e.mutatedMarked()).toBe(false)
680
+ })
681
+ addListenerToElement(e5, 'customevent', function(e){
682
+ waitingEvents--
683
+ expect(e.mutatedMarked()).toBe(false)
684
+ })
685
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
686
+ expect(waitingEvents).toBe(0)
687
+ expect(triggerCount).toBe(0)
688
+
689
+ // bind: removeListener
690
+ removeListenerFromElement(e3, 'customevent', id1)
691
+ removeListenerFromElement(e4, 'customevent', id2)
692
+ addListenerToElement(e3, 'customevent', function(e){
693
+ waitingEvents--
694
+ expect(e.mutatedMarked()).toBe(false)
695
+ })
696
+ waitingEvents = 6
697
+ triggerCount = 0
698
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
699
+ expect(waitingEvents).toBe(0)
700
+ expect(triggerCount).toBe(1)
701
+
702
+ // capture: pass mutated option
703
+ e1 = createElem('events-full')
704
+ e2 = createElem('events-full')
705
+ e3 = createElem('events-full')
706
+ e4 = createElem('events-full')
707
+ e5 = createElem('events-full')
708
+ triggerCount = 0
709
+ waitingEvents = 6
710
+ e1.appendChild(e2)
711
+ e2.appendChild(e3)
712
+ e3.appendChild(e4)
713
+ e4.appendChild(e5)
714
+
715
+ addListenerToElement(e1, 'customevent', function(e){
716
+ waitingEvents--
717
+ expect(e.mutatedMarked()).toBe(true)
718
+ })
719
+ addListenerToElement(e1, 'customevent', function(e){
720
+ waitingEvents--
721
+ expect(e.mutatedMarked()).toBe(false)
722
+ }, {useCapture: true})
723
+ id1 = addListenerToElement(e2, 'customevent', function(e){
724
+ waitingEvents--
725
+ expect(e.mutatedMarked()).toBe(false)
726
+ }, {useCapture: true, mutated: true})
727
+ addListenerToElement(e2, 'customevent', function(e){
728
+ waitingEvents--
729
+ expect(e.mutatedMarked()).toBe(false)
730
+ }, {useCapture: true})
731
+ id2 = addListenerToElement(e3, 'customevent', function(e){
732
+ waitingEvents--
733
+ expect(e.mutatedMarked()).toBe(true)
734
+ }, {useCapture: true})
735
+ addListenerToElement(e4, 'customevent', function(e){
736
+ waitingEvents--
737
+ triggerCount++
738
+ }, {useCapture: true, mutated: true})
739
+ addListenerToElement(e5, 'customevent', function(e){
740
+ waitingEvents--
741
+ expect(e.mutatedMarked()).toBe(true)
742
+ }, {useCapture: true})
743
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
744
+ expect(waitingEvents).toBe(0)
745
+ expect(triggerCount).toBe(0)
746
+
747
+ // capture: removeListener
748
+ removeListenerFromElement(e2, 'customevent', id1, {useCapture: true})
749
+ removeListenerFromElement(e3, 'customevent', id2, {useCapture: true})
750
+ addListenerToElement(e3, 'customevent', function(e){
751
+ waitingEvents--
752
+ expect(e.mutatedMarked()).toBe(false)
753
+ }, {useCapture: true})
754
+ waitingEvents = 6
755
+ triggerCount = 0
756
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
757
+ expect(waitingEvents).toBe(0)
758
+ expect(triggerCount).toBe(1)
759
+
760
+ // bind: mixed api and mutated option
761
+ e1 = createElem('events-full')
762
+ e2 = createElem('events-full')
763
+ e3 = createElem('events-full')
764
+ e4 = createElem('events-full')
765
+ e5 = createElem('events-full')
766
+ triggerCount = 0
767
+ waitingEvents = 5
768
+ e1.appendChild(e2)
769
+ e2.appendChild(e3)
770
+ e3.appendChild(e4)
771
+ e4.appendChild(e5)
772
+
773
+ addListenerToElement(e1, 'customevent', function(e){
774
+ waitingEvents--
775
+ expect(e.mutatedMarked()).toBe(false)
776
+ }, {useCapture: true})
777
+ addListenerToElement(e1, 'customevent', function(e){
778
+ waitingEvents--
779
+ expect(e.mutatedMarked()).toBe(true)
780
+ })
781
+ addListenerToElement(e2, 'customevent', function(e){
782
+ waitingEvents--
783
+ expect(e.mutatedMarked()).toBe(true)
784
+ })
785
+ addListenerToElement(e3, 'customevent', function(e){
786
+ waitingEvents--
787
+ triggerCount++
788
+ }, {mutated: true})
789
+ addListenerToElement(e4, 'customevent', function(e){
790
+ waitingEvents--
791
+ expect(e.mutatedMarked()).toBe(false)
792
+ e.markMutated()
793
+ expect(e.mutatedMarked()).toBe(true)
794
+ })
795
+ addListenerToElement(e5, 'customevent', function(e){
796
+ waitingEvents--
797
+ expect(e.mutatedMarked()).toBe(false)
798
+ })
799
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
800
+ expect(waitingEvents).toBe(0)
801
+ expect(triggerCount).toBe(0)
802
+
803
+ // capture: mixed api and mutated option
804
+ e1 = createElem('events-full')
805
+ e2 = createElem('events-full')
806
+ e3 = createElem('events-full')
807
+ e4 = createElem('events-full')
808
+ e5 = createElem('events-full')
809
+ triggerCount = 0
810
+ waitingEvents = 5
811
+ e1.appendChild(e2)
812
+ e2.appendChild(e3)
813
+ e3.appendChild(e4)
814
+ e4.appendChild(e5)
815
+
816
+ addListenerToElement(e1, 'customevent', function(e){
817
+ waitingEvents--
818
+ expect(e.mutatedMarked()).toBe(true)
819
+ })
820
+ addListenerToElement(e1, 'customevent', function(e){
821
+ waitingEvents--
822
+ expect(e.mutatedMarked()).toBe(false)
823
+ }, {useCapture: true})
824
+ addListenerToElement(e2, 'customevent', function(e){
825
+ waitingEvents--
826
+ expect(e.mutatedMarked()).toBe(false)
827
+ e.markMutated()
828
+ expect(e.mutatedMarked()).toBe(true)
829
+ }, {useCapture: true})
830
+ addListenerToElement(e3, 'customevent', function(e){
831
+ waitingEvents--
832
+ triggerCount++
833
+ }, {useCapture: true, mutated: true})
834
+ addListenerToElement(e4, 'customevent', function(e){
835
+ waitingEvents--
836
+ expect(e.mutatedMarked()).toBe(true)
837
+ }, {useCapture: true})
838
+ addListenerToElement(e5, 'customevent', function(e){
839
+ waitingEvents--
840
+ expect(e.mutatedMarked()).toBe(true)
841
+ }, {useCapture: true})
842
+ glassEasel.triggerEvent(e5.$.inner, 'customevent', undefined, {bubbles: true, capturePhase: true, composed: true})
843
+ expect(waitingEvents).toBe(0)
844
+ expect(triggerCount).toBe(0)
845
+ })
846
+
847
+ })
848
+
849
+ })