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
package/src/index.ts CHANGED
@@ -1,102 +1,101 @@
1
1
  /* eslint-disable import/first */
2
2
  /* eslint-disable arrow-body-style */
3
3
 
4
- export { TextNode } from './text_node'
5
- export { NativeNode } from './native_node'
6
- export { ShadowRoot } from './shadow_root'
7
- export { VirtualNode } from './virtual_node'
8
4
  export {
9
- globalOptions,
10
- DeepCopyKind,
11
- ComponentOptions,
12
- EnvironmentOptions,
13
- NormalizedComponentOptions,
14
- getDefaultComponentSpace,
15
- } from './global_options'
16
- export { Element, StyleSegmentIndex } from './element'
17
- export * as dataUtils from './data_utils'
5
+ BackendMode,
6
+ GeneralBackendContext,
7
+ GeneralBackendElement,
8
+ backend,
9
+ composedBackend,
10
+ domlikeBackend,
11
+ } from './backend'
12
+ export { CurrentWindowBackendContext } from './backend/current_window_backend_context'
13
+ export { EmptyBackendContext } from './backend/empty_backend'
14
+ export { EmptyComposedBackendContext } from './backend/empty_composed_backend'
15
+ export {
16
+ Behavior,
17
+ BehaviorBuilder,
18
+ BuilderContext,
19
+ GeneralBehavior,
20
+ GeneralBehaviorBuilder,
21
+ } from './behavior'
22
+ export { ClassList, StyleScopeId, StyleScopeManager } from './class_list'
23
+ export {
24
+ Component,
25
+ ComponentDefinition,
26
+ GeneralComponent,
27
+ GeneralComponentDefinition,
28
+ } from './component'
29
+ export * as typeUtils from './component_params'
30
+ export { ComponentSpace, getDefaultComponentSpace } from './component_space'
18
31
  export * as dataPath from './data_path'
19
32
  export {
33
+ DataChange,
20
34
  DataGroup,
21
- GeneralDataGroup,
22
- DataValue,
23
35
  DataObserver,
24
- DataChange,
25
- PropertyChange,
26
36
  DataUpdateCallback,
37
+ DataValue,
38
+ GeneralDataGroup,
39
+ NormalizedPropertyType,
40
+ PropertyChange,
27
41
  } from './data_proxy'
42
+ export * as dataUtils from './data_utils'
43
+ export { Element, StyleSegmentIndex } from './element'
44
+ export { ElementIterator, ElementIteratorType } from './element_iterator'
28
45
  export {
29
46
  Event,
30
- ShadowedEvent,
31
47
  EventBubbleStatus,
32
- EventOptions,
33
48
  EventListener,
34
49
  EventListenerOptions,
35
50
  MutLevel as EventMutLevel,
51
+ EventOptions,
52
+ ShadowedEvent,
36
53
  } from './event'
37
- export * as typeUtils from './component_params'
38
- export {
39
- Behavior,
40
- GeneralBehavior,
41
- BehaviorBuilder,
42
- GeneralBehaviorBuilder,
43
- BuilderContext,
44
- NormalizedPropertyType,
45
- } from './behavior'
46
- export {
47
- Component,
48
- ComponentDefinition,
49
- GeneralComponent,
50
- GeneralComponentDefinition,
51
- } from './component'
52
- export { MutationObserver as Observer, MutationObserver } from './mutation_observer'
53
- export * as mutationObserver from './mutation_observer'
54
+ export { ExternalShadowRoot } from './external_shadow_tree'
55
+ export { FuncArr, GeneralFuncType, safeCallback } from './func_arr'
54
56
  export {
55
- Node,
56
- dumpElement,
57
- dumpElementToString,
58
- dumpSingleElementToString,
59
- GeneralBackendElement,
60
- GeneralBackendContext,
61
- NodeCast,
62
- } from './node'
63
- export { ElementIterator, ElementIteratorType } from './element_iterator'
57
+ ComponentOptions,
58
+ DeepCopyKind,
59
+ EnvironmentOptions,
60
+ NormalizedComponentOptions,
61
+ globalOptions,
62
+ } from './global_options'
63
+ export { MutationObserver, MutationObserver as Observer } from './mutation_observer'
64
+ export { NativeNode } from './native_node'
65
+ export { Node, NodeCast, dumpElement, dumpElementToString, dumpSingleElementToString } from './node'
66
+ export { RelationFailedListener, RelationListener, RelationType } from './relation'
67
+ export { triggerRender } from './render'
68
+ export { ParsedSelector } from './selector'
69
+ export { ShadowRoot } from './shadow_root'
70
+ export * as templateEngine from './template_engine'
71
+ export { TextNode } from './text_node'
72
+ export * as template from './tmpl'
73
+ export { TraitBehavior } from './trait_behaviors'
74
+ export { VirtualNode } from './virtual_node'
64
75
  export {
65
- FuncArr,
66
- GeneralFuncType,
67
- safeCallback,
68
76
  addGlobalErrorListener,
69
- removeGlobalErrorListener,
70
77
  addGlobalWarningListener,
78
+ removeGlobalErrorListener,
71
79
  removeGlobalWarningListener,
72
- } from './func_arr'
73
- export { ParsedSelector } from './selector'
74
- export { StyleScopeManager, ClassList, StyleScopeId } from './class_list'
75
- export { RelationType, RelationListener, RelationFailedListener } from './relation'
76
- export { TraitBehavior } from './trait_behaviors'
77
- export { triggerRender } from './render'
78
- export { ComponentSpace } from './component_space'
79
- export { ExternalShadowRoot } from './external_shadow_tree'
80
- export * as template from './tmpl'
81
- export * as backend from './backend/backend_protocol'
82
- export * as composedBackend from './backend/composed_backend_protocol'
83
- export * as domlikeBackend from './backend/domlike_backend_protocol'
84
- export { BackendMode } from './backend/mode'
85
- export * as templateEngine from './template_engine'
86
- export * as glassEaselTemplate from './tmpl'
80
+ } from './warning'
87
81
 
82
+ import { type Behavior } from './behavior'
83
+ import {
84
+ Component,
85
+ type ComponentDefinition,
86
+ type GeneralComponent,
87
+ type GeneralComponentDefinition,
88
+ } from './component'
88
89
  import {
89
- ComponentParams,
90
- DataList,
91
- PropertyList,
92
- MethodList,
93
- ComponentInstance,
94
- Empty,
90
+ type ComponentInstance,
91
+ type ComponentParams,
92
+ type DataList,
93
+ type Empty,
94
+ type MethodList,
95
+ type PropertyList,
95
96
  } from './component_params'
96
- import { Behavior } from './behavior'
97
- import { Component, ComponentDefinition, GeneralComponent, GeneralComponentDefinition } from './component'
97
+ import { getDefaultComponentSpace } from './component_space'
98
98
  import { Event } from './event'
99
- import { getDefaultComponentSpace } from './global_options'
100
99
 
101
100
  export const registerBehavior = <
102
101
  TData extends DataList = Empty,
@@ -1,5 +1,8 @@
1
- import { Element, Node, TextNode } from '.'
1
+ import { type Element } from './element'
2
2
  import { FuncArr } from './func_arr'
3
+ import { type Node } from './node'
4
+ import { type TextNode } from './text_node'
5
+ import { isElement } from './type_symbol'
3
6
 
4
7
  /**
5
8
  * What the observer will listen
@@ -81,7 +84,7 @@ export class MutationObserverTarget {
81
84
  this._$subtreeObserversCount += diff
82
85
  const children = this._$boundElement.childNodes
83
86
  children.forEach((child) => {
84
- if (child instanceof Element) {
87
+ if (isElement(child)) {
85
88
  if (!child._$mutationObserverTarget) {
86
89
  child._$mutationObserverTarget = new MutationObserverTarget(child)
87
90
  }
@@ -161,7 +164,7 @@ export class MutationObserver {
161
164
  /** Start observation */
162
165
  observe(
163
166
  targetElement: Element,
164
- options: MutationObserverOptions = {
167
+ options: Partial<MutationObserverOptions> = {
165
168
  properties: false,
166
169
  childList: false,
167
170
  characterData: false,
@@ -190,7 +193,7 @@ export class MutationObserver {
190
193
  this._$normalizedListener = cb
191
194
  this._$boundTarget = target
192
195
  if (options.properties) {
193
- if (!target.attrObservers) target.attrObservers = new FuncArr()
196
+ if (!target.attrObservers) target.attrObservers = new FuncArr('attributeObserver')
194
197
  target.attrObservers.add(cb)
195
198
  this._$boundFuncArrs.push(
196
199
  target.attrObservers as FuncArr<MutationObserverListener<MutationObserverEvent>>,
@@ -198,7 +201,7 @@ export class MutationObserver {
198
201
  this._$subtreeListenersCount += 1
199
202
  }
200
203
  if (options.childList) {
201
- if (!target.childObservers) target.childObservers = new FuncArr()
204
+ if (!target.childObservers) target.childObservers = new FuncArr('childObserver')
202
205
  target.childObservers.add(cb)
203
206
  this._$boundFuncArrs.push(
204
207
  target.childObservers as FuncArr<MutationObserverListener<MutationObserverEvent>>,
@@ -206,7 +209,7 @@ export class MutationObserver {
206
209
  this._$subtreeListenersCount += 1
207
210
  }
208
211
  if (options.characterData) {
209
- if (!target.textObservers) target.textObservers = new FuncArr()
212
+ if (!target.textObservers) target.textObservers = new FuncArr('textObserver')
210
213
  target.textObservers.add(cb)
211
214
  this._$boundFuncArrs.push(
212
215
  target.textObservers as FuncArr<MutationObserverListener<MutationObserverEvent>>,
@@ -217,7 +220,7 @@ export class MutationObserver {
217
220
  target.updateSubtreeCount(this._$subtreeListenersCount)
218
221
  }
219
222
  if (options.attachStatus) {
220
- if (!target.attachObservers) target.attachObservers = new FuncArr()
223
+ if (!target.attachObservers) target.attachObservers = new FuncArr('attachObserver')
221
224
  target.attachObservers.add(cb)
222
225
  this._$boundFuncArrs.push(
223
226
  target.attachObservers as FuncArr<MutationObserverListener<MutationObserverEvent>>,
@@ -1,71 +1,95 @@
1
- import * as backend from './backend/backend_protocol'
2
- import * as composedBackend from './backend/composed_backend_protocol'
3
- import * as domlikeBackend from './backend/domlike_backend_protocol'
4
- import { globalOptions } from './global_options'
5
- import { ClassList } from './class_list'
1
+ import {
2
+ BM,
3
+ BackendMode,
4
+ type GeneralBackendElement,
5
+ type backend,
6
+ type composedBackend,
7
+ type domlikeBackend,
8
+ } from './backend'
9
+ import { ClassList, StyleScopeManager } from './class_list'
10
+ import { type DataValue, type ModelBindingListener } from './data_proxy'
6
11
  import { Element } from './element'
7
- import { ShadowRoot } from './shadow_root'
8
- import { GeneralBackendElement } from '.'
9
- import { BM, BackendMode } from './backend/mode'
10
- import { DataValue, ModelBindingListener } from './data_proxy'
12
+ import { ENV, globalOptions } from './global_options'
13
+ import { performanceMeasureEnd, performanceMeasureStart } from './devtool'
14
+ import { type ShadowRoot } from './shadow_root'
15
+ import { NATIVE_NODE_SYMBOL, isNativeNode } from './type_symbol'
11
16
 
12
17
  export class NativeNode extends Element {
18
+ [NATIVE_NODE_SYMBOL]: true
13
19
  is: string
20
+ public stylingName: string
21
+ /* @internal */
14
22
  private _$modelBindingListeners?: { [name: string]: ModelBindingListener }
15
23
 
24
+ /* istanbul ignore next */
16
25
  constructor() {
17
26
  throw new Error('Element cannot be constructed directly')
18
27
  // eslint-disable-next-line no-unreachable
19
28
  super()
20
29
  }
21
30
 
31
+ static isNativeNode = isNativeNode
32
+
22
33
  static create(
23
34
  tagName: string,
24
35
  owner: ShadowRoot,
25
36
  stylingName?: string,
26
- placeholderHandler?: () => void,
37
+ placeholderHandlerRemover?: () => void,
27
38
  ): NativeNode {
28
39
  const node = Object.create(NativeNode.prototype) as NativeNode
29
40
  node.is = tagName
30
- node._$placeholderHandler = placeholderHandler
31
- const nodeTreeContext = owner._$nodeTreeContext
32
- let backendElement: GeneralBackendElement | null
33
- if (BM.DOMLIKE || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Domlike)) {
34
- backendElement = (nodeTreeContext as domlikeBackend.Context).document.createElement(tagName)
35
- } else if (BM.SHADOW || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Shadow)) {
36
- const backend = owner._$backendShadowRoot
37
- backendElement = backend?.createElement(tagName, stylingName ?? tagName) || null
38
- } else {
39
- const backend = nodeTreeContext as composedBackend.Context
40
- backendElement = backend.createElement(tagName, stylingName ?? tagName)
41
+ node.stylingName = stylingName ?? tagName
42
+ node._$placeholderHandlerRemover = placeholderHandlerRemover
43
+ const nodeTreeContext = owner.getBackendContext()
44
+ let backendElement: GeneralBackendElement | null = null
45
+ if (nodeTreeContext) {
46
+ if (ENV.DEV) performanceMeasureStart('backend.createElement')
47
+ if (BM.DOMLIKE || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Domlike)) {
48
+ backendElement = (nodeTreeContext as domlikeBackend.Context).document.createElement(tagName)
49
+ } else if (BM.SHADOW || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Shadow)) {
50
+ backendElement = owner._$backendShadowRoot!.createElement(tagName, node.stylingName)
51
+ } else {
52
+ const backend = nodeTreeContext as composedBackend.Context
53
+ backendElement = backend.createElement(tagName, node.stylingName)
54
+ }
55
+ if (ENV.DEV) performanceMeasureEnd()
41
56
  }
42
- node._$initialize(false, backendElement, owner, nodeTreeContext)
43
- node.classList = new ClassList(node, null)
44
- if (owner && backendElement) {
45
- const styleScope = owner.getHostNode()._$definition._$options.styleScope
46
- if (styleScope) {
47
- if (!(BM.DOMLIKE || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Domlike))) {
48
- ;(backendElement as backend.Element | composedBackend.Element).setStyleScope(styleScope)
49
- }
57
+ node._$initialize(false, backendElement, owner, owner._$nodeTreeContext)
58
+ const ownerHost = owner.getHostNode()
59
+ const ownerComponentOptions = ownerHost.getComponentOptions()
60
+ const styleScope = ownerComponentOptions.styleScope ?? StyleScopeManager.globalScope()
61
+ const extraStyleScope = ownerComponentOptions.extraStyleScope ?? undefined
62
+ const styleScopeManager = ownerHost._$behavior.ownerSpace.styleScopeManager
63
+ node.classList = new ClassList(
64
+ node,
65
+ undefined,
66
+ ownerHost.classList,
67
+ styleScope,
68
+ extraStyleScope,
69
+ styleScopeManager,
70
+ )
71
+ if (backendElement) {
72
+ if (BM.COMPOSED || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Composed)) {
73
+ if (ENV.DEV) performanceMeasureStart('backend.setStyleScope')
74
+ ;(backendElement as composedBackend.Element).setStyleScope(styleScope, extraStyleScope)
75
+ if (ENV.DEV) performanceMeasureEnd()
50
76
  }
51
77
  if (globalOptions.writeExtraInfoToAttr) {
52
- const prefix = owner
53
- .getHostNode()
54
- ._$behavior.ownerSpace?.styleScopeManager.queryName(styleScope)
78
+ const prefix = styleScopeManager.queryName(styleScope)
55
79
  if (prefix) {
56
80
  backendElement.setAttribute('exparser:info-class-prefix', `${prefix}--`)
57
81
  }
58
82
  }
59
- }
60
- if (backendElement) {
83
+ if (ENV.DEV) performanceMeasureStart('backend.associateValue')
61
84
  if (!(BM.DOMLIKE || (BM.DYNAMIC && owner.getBackendMode() === BackendMode.Domlike))) {
62
85
  ;(backendElement as backend.Element | composedBackend.Element).associateValue(node)
63
86
  } else {
64
- ;(owner._$nodeTreeContext as domlikeBackend.Context).associateValue(
87
+ ;(owner.getBackendContext() as domlikeBackend.Context).associateValue(
65
88
  backendElement as domlikeBackend.Element,
66
89
  node,
67
90
  )
68
91
  }
92
+ if (ENV.DEV) performanceMeasureEnd()
69
93
  }
70
94
  return node
71
95
  }
@@ -83,6 +107,7 @@ export class NativeNode extends Element {
83
107
  listener.call(this, value)
84
108
  }
85
109
  }
110
+ if (ENV.DEV) performanceMeasureStart('backend.setModelBindingStat')
86
111
  if (BM.DOMLIKE || (BM.DYNAMIC && this.getBackendMode() === BackendMode.Domlike)) {
87
112
  ;(this.getBackendContext() as domlikeBackend.Context).setModelBindingStat(
88
113
  backendElement as domlikeBackend.Element,
@@ -95,8 +120,27 @@ export class NativeNode extends Element {
95
120
  listener,
96
121
  )
97
122
  }
123
+ if (ENV.DEV) performanceMeasureEnd()
98
124
  }
99
125
  }
100
126
  this._$modelBindingListeners[propName] = listener
101
127
  }
128
+
129
+ getModelBindingListeners() {
130
+ const listeners = Object.create(null) as { [name: string]: ModelBindingListener }
131
+ if (this._$modelBindingListeners) {
132
+ Object.keys(this._$modelBindingListeners).forEach((propName) => {
133
+ const listener = (value: DataValue) => {
134
+ const listener = this._$modelBindingListeners?.[propName]
135
+ if (listener) {
136
+ listener.call(this, value)
137
+ }
138
+ }
139
+ listeners[propName] = listener
140
+ })
141
+ }
142
+ return listeners
143
+ }
102
144
  }
145
+
146
+ NativeNode.prototype[NATIVE_NODE_SYMBOL] = true
package/src/node.ts CHANGED
@@ -1,22 +1,15 @@
1
- import * as backend from './backend/backend_protocol'
2
- import * as composedBackend from './backend/composed_backend_protocol'
3
- import * as domlikeBackend from './backend/domlike_backend_protocol'
4
- import { TextNode } from './text_node'
5
- import { Element } from './element'
6
- import { VirtualNode } from './virtual_node'
7
- import { Component, ComponentDefinition } from './component'
8
- import { NativeNode } from './native_node'
9
- import { DataList, PropertyList, MethodList, ComponentInstance } from './component_params'
10
-
11
- export type GeneralBackendContext =
12
- | backend.Context
13
- | composedBackend.Context
14
- | domlikeBackend.Context
15
-
16
- export type GeneralBackendElement =
17
- | backend.Element
18
- | composedBackend.Element
19
- | domlikeBackend.Element
1
+ import { type ComponentDefinition } from './component'
2
+ import {
3
+ type ComponentInstance,
4
+ type DataList,
5
+ type MethodList,
6
+ type PropertyList,
7
+ } from './component_params'
8
+ import { type Element } from './element'
9
+ import { type NativeNode } from './native_node'
10
+ import { type TextNode } from './text_node'
11
+ import { isComponent, isElement, isNativeNode, isTextNode, isVirtualNode } from './type_symbol'
12
+ import { type VirtualNode } from './virtual_node'
20
13
 
21
14
  export type Node = TextNode | Element
22
15
 
@@ -61,7 +54,7 @@ export interface NodeCast {
61
54
 
62
55
  const dumpAttributesToString = (elem: Element): string => {
63
56
  let ret = ''
64
- if (elem instanceof Element) {
57
+ if (isElement(elem)) {
65
58
  if (elem._$slotName !== null) ret += ` (slot) name="${elem._$slotName}"`
66
59
  if (elem.id) ret += ` id="${elem.id}"`
67
60
  if (elem.slot) ret += ` slot="${elem.slot}"`
@@ -70,10 +63,10 @@ const dumpAttributesToString = (elem: Element): string => {
70
63
  const style = elem.style
71
64
  if (style) ret += ` style="${elem.style}"`
72
65
  }
73
- if (elem instanceof VirtualNode) {
66
+ if (isVirtualNode(elem)) {
74
67
  // empty
75
- } else if (elem instanceof Component) {
76
- Component.listProperties(elem).forEach((propName) => {
68
+ } else if (isComponent(elem)) {
69
+ Object.keys(elem._$behavior._$propertyMap).forEach((propName) => {
77
70
  ret += ` ${propName}="${String((elem.data as DataList)[propName])}"`
78
71
  })
79
72
  } else {
@@ -85,20 +78,20 @@ const dumpAttributesToString = (elem: Element): string => {
85
78
  }
86
79
 
87
80
  export const dumpSingleElementToString = (elem: any) => {
88
- if (elem instanceof Element) {
81
+ if (isElement(elem)) {
89
82
  let tagName: string
90
- if (elem instanceof VirtualNode) {
83
+ if (isVirtualNode(elem)) {
91
84
  tagName = `(virtual):${elem.is}`
92
- } else if (elem instanceof Component) {
85
+ } else if (isComponent(elem)) {
93
86
  tagName = `${elem.tagName}:${elem.is}`
94
- } else if (elem instanceof NativeNode) {
87
+ } else if (isNativeNode(elem)) {
95
88
  tagName = elem.is
96
89
  } else {
97
90
  tagName = '(unknown)'
98
91
  }
99
92
  return `<${tagName}${dumpAttributesToString(elem)}>`
100
93
  }
101
- if (elem instanceof TextNode) {
94
+ if (isTextNode(elem)) {
102
95
  return elem.textContent.trim()
103
96
  }
104
97
  if (elem === null) {
@@ -119,8 +112,8 @@ export const dumpElementToString = (elem: any, composed: boolean, tabDepth = 0)
119
112
  let ret = linePrefix + dumpSingleElementToString(elem)
120
113
  let isExternal = false
121
114
 
122
- if (elem instanceof Element) {
123
- if (elem instanceof Component) {
115
+ if (isElement(elem)) {
116
+ if (isComponent(elem)) {
124
117
  isExternal = elem._$external
125
118
  }
126
119
  if (composed) {
package/src/relation.ts CHANGED
@@ -1,9 +1,12 @@
1
- import { VirtualNode } from './virtual_node'
2
- import { GeneralBehavior } from './behavior'
3
- import { Component, GeneralComponent } from './component'
4
- import { Element } from './element'
5
- import { safeCallback, triggerWarning } from './func_arr'
1
+ import { Behavior, type GeneralBehavior } from './behavior'
2
+ import { ComponentDefinition, type GeneralComponent } from './component'
3
+ import { type RelationParams, type TraitRelationParams } from './component_params'
4
+ import { type ComponentSpace } from './component_space'
5
+ import { type Element } from './element'
6
+ import { safeCallback } from './func_arr'
6
7
  import { TraitBehavior } from './trait_behaviors'
8
+ import { isComponent, isElement, isVirtualNode } from './type_symbol'
9
+ import { triggerWarning } from './warning'
7
10
 
8
11
  export const enum RelationType {
9
12
  Ancestor = 0,
@@ -16,6 +19,92 @@ export const enum RelationType {
16
19
 
17
20
  const RELATION_TYPE_COUNT = 6
18
21
 
22
+ export const normalizeRelation = <TOut extends { [key: string]: any }>(
23
+ ownerSpace: ComponentSpace,
24
+ is: string,
25
+ key: string,
26
+ relation: RelationParams | TraitRelationParams<TOut>,
27
+ ): RelationDefinition | null => {
28
+ const checkRelationFunc = (f: unknown): RelationListener | null => {
29
+ if (typeof f === 'function') {
30
+ return f as RelationListener
31
+ }
32
+ if (f !== undefined) {
33
+ triggerWarning(
34
+ `the "${key}" relation listener is not a function (when preparing behavior "${is}").`,
35
+ )
36
+ }
37
+ return null
38
+ }
39
+ let type: RelationType
40
+ if (relation.type === 'parent') {
41
+ type = RelationType.ParentComponent
42
+ } else if (relation.type === 'child') {
43
+ type = RelationType.ChildComponent
44
+ } else if (relation.type === 'parent-common-node') {
45
+ type = RelationType.ParentNonVirtualNode
46
+ } else if (relation.type === 'child-common-node') {
47
+ type = RelationType.ChildNonVirtualNode
48
+ } else if (relation.type === 'ancestor') {
49
+ type = RelationType.Ancestor
50
+ } else if (relation.type === 'descendant') {
51
+ type = RelationType.Descendant
52
+ } else {
53
+ const type = relation.type as string
54
+ triggerWarning(
55
+ `the "${key}" relation has an invalid relation type "${type}" (when preparing behavior "${is}").`,
56
+ )
57
+ return null
58
+ }
59
+ let target:
60
+ | GeneralBehavior
61
+ | TraitBehavior<{ [key: string]: unknown }, { [key: string]: unknown }>
62
+ | null = null
63
+ if (relation.target instanceof ComponentDefinition) {
64
+ target = relation.target.behavior as GeneralBehavior
65
+ } else if (relation.target instanceof Behavior || relation.target instanceof TraitBehavior) {
66
+ target = relation.target
67
+ } else {
68
+ const path = String(relation.target || key)
69
+ const usingTarget = ownerSpace.getComponentByUrlWithoutDefault(path, is)
70
+ if (usingTarget) {
71
+ target = usingTarget.behavior
72
+ } else {
73
+ const globalTarget = ownerSpace.getGlobalUsingComponent(path)
74
+ if (typeof globalTarget === 'object' && globalTarget !== null) {
75
+ target = globalTarget.behavior
76
+ }
77
+ }
78
+ }
79
+ if (!target) {
80
+ triggerWarning(
81
+ `the target of relation "${key}" is not a valid behavior or component (when preparing behavior "${is}").`,
82
+ )
83
+ return null
84
+ }
85
+ return {
86
+ target,
87
+ type,
88
+ linked: checkRelationFunc(relation.linked),
89
+ linkChanged: checkRelationFunc(relation.linkChanged),
90
+ unlinked: checkRelationFunc(relation.unlinked),
91
+ linkFailed: checkRelationFunc(relation.linkFailed) as RelationFailedListener,
92
+ }
93
+ }
94
+
95
+ export interface RelationHandler<TTarget, TOut> {
96
+ list(): TTarget[]
97
+ listAsTrait: TOut extends never ? undefined : () => TOut[]
98
+ }
99
+
100
+ export interface RelationInit {
101
+ (def: RelationParams): RelationHandler<any, never>
102
+ <TOut extends { [key: string]: any }>(def: TraitRelationParams<TOut>): RelationHandler<
103
+ unknown,
104
+ TOut
105
+ >
106
+ }
107
+
19
108
  export type RelationListener = (target: unknown) => void
20
109
 
21
110
  export type RelationFailedListener = () => void
@@ -165,10 +254,10 @@ export class Relation {
165
254
  const next = cur.parentNode
166
255
  if (!next) break
167
256
  cur = next
168
- if (cur instanceof VirtualNode) {
257
+ if (isVirtualNode(cur)) {
169
258
  continue
170
259
  }
171
- if (cur instanceof Component) {
260
+ if (isComponent(cur)) {
172
261
  if (cur.hasBehavior(parentBehavior)) {
173
262
  const parentRelation = cur._$relation
174
263
  if (parentRelation) {
@@ -186,7 +275,7 @@ export class Relation {
186
275
  const def = parentDefs[j]!
187
276
  if (def.target && this._$comp.hasBehavior(def.target)) {
188
277
  newLink = {
189
- target: cur as GeneralComponent,
278
+ target: cur,
190
279
  def,
191
280
  }
192
281
  break
@@ -304,12 +393,12 @@ export class Relation {
304
393
  const children = node.childNodes
305
394
  for (let i = 0; i < children.length; i += 1) {
306
395
  const child = children[i]!
307
- if (!(child instanceof Element)) continue
308
- if (child instanceof VirtualNode) {
396
+ if (!isElement(child)) continue
397
+ if (isVirtualNode(child)) {
309
398
  dfs(child)
310
399
  continue
311
400
  }
312
- if (child instanceof Component) {
401
+ if (isComponent(child)) {
313
402
  if (child._$relation) {
314
403
  let links
315
404
  if (type === RelationType.ChildComponent) {
@@ -323,7 +412,7 @@ export class Relation {
323
412
  for (let i = 0; i < links.length; i += 1) {
324
413
  const link = links[i]!
325
414
  if (link && link.target === comp && link.def === def) {
326
- ret.push(child as GeneralComponent)
415
+ ret.push(child)
327
416
  break
328
417
  }
329
418
  }
package/src/render.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { type GeneralBackendContext } from './backend'
2
+ import { type Element } from './element'
1
3
  import { safeCallback } from './func_arr'
2
- import { Element } from './element'
3
- import { GeneralBackendContext } from './node'
4
4
 
5
5
  const triggerRenderOnContext = (
6
6
  context: GeneralBackendContext,
@@ -15,5 +15,7 @@ const triggerRenderOnContext = (
15
15
 
16
16
  export const triggerRender = (element: Element, callback?: (err: Error | null) => void) => {
17
17
  const context = element.getBackendContext()
18
- triggerRenderOnContext(context, callback || null)
18
+ if (context) {
19
+ triggerRenderOnContext(context, callback || null)
20
+ }
19
21
  }