@studiometa/js-toolkit 3.1.0 → 3.2.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 (228) hide show
  1. package/Base/Base.d.ts +14 -12
  2. package/Base/Base.js +17 -16
  3. package/Base/Base.js.map +2 -2
  4. package/Base/managers/AbstractManager.d.ts +1 -1
  5. package/Base/managers/ChildrenManager.d.ts +2 -2
  6. package/Base/managers/ChildrenManager.js +4 -4
  7. package/Base/managers/ChildrenManager.js.map +2 -2
  8. package/Base/managers/EventsManager.d.ts +10 -10
  9. package/Base/managers/EventsManager.js +10 -10
  10. package/Base/managers/EventsManager.js.map +1 -1
  11. package/Base/managers/ResponsiveOptionsManager.d.ts +6 -6
  12. package/Base/managers/ResponsiveOptionsManager.js +6 -6
  13. package/Base/managers/ResponsiveOptionsManager.js.map +1 -1
  14. package/Base/managers/ServicesManager.d.ts +2 -2
  15. package/Base/managers/ServicesManager.js +2 -2
  16. package/Base/managers/ServicesManager.js.map +1 -1
  17. package/Base/utils.d.ts +3 -2
  18. package/Base/utils.js +7 -5
  19. package/Base/utils.js.map +2 -2
  20. package/decorators/index.d.ts +1 -0
  21. package/decorators/index.js +1 -0
  22. package/decorators/index.js.map +2 -2
  23. package/decorators/withBreakpointManager.d.ts +2 -1
  24. package/decorators/withBreakpointManager.js.map +2 -2
  25. package/decorators/withBreakpointObserver.d.ts +2 -1
  26. package/decorators/withBreakpointObserver.js.map +2 -2
  27. package/decorators/withDrag.d.ts +2 -1
  28. package/decorators/withDrag.js.map +2 -2
  29. package/decorators/withExtraConfig.d.ts +2 -1
  30. package/decorators/withExtraConfig.js.map +2 -2
  31. package/decorators/withFreezedOptions.d.ts +2 -1
  32. package/decorators/withFreezedOptions.js.map +2 -2
  33. package/decorators/withGroup.d.ts +16 -0
  34. package/decorators/withGroup.js +33 -0
  35. package/decorators/withGroup.js.map +7 -0
  36. package/decorators/withIntersectionObserver.d.ts +2 -1
  37. package/decorators/withIntersectionObserver.js.map +2 -2
  38. package/decorators/withMountOnMediaQuery.d.ts +2 -1
  39. package/decorators/withMountOnMediaQuery.js.map +2 -2
  40. package/decorators/withMountWhenInView.d.ts +2 -1
  41. package/decorators/withMountWhenInView.js.map +2 -2
  42. package/decorators/withMountWhenPrefersMotion.d.ts +3 -0
  43. package/decorators/withMountWhenPrefersMotion.js.map +2 -2
  44. package/decorators/withMutation.d.ts +2 -1
  45. package/decorators/withMutation.js.map +2 -2
  46. package/decorators/withRelativePointer.d.ts +2 -1
  47. package/decorators/withRelativePointer.js.map +2 -2
  48. package/decorators/withResponsiveOptions.d.ts +2 -1
  49. package/decorators/withResponsiveOptions.js.map +2 -2
  50. package/decorators/withScrolledInView/withScrolledInView.d.ts +2 -1
  51. package/decorators/withScrolledInView/withScrolledInView.js.map +2 -2
  52. package/helpers/createApp.d.ts +2 -1
  53. package/helpers/createApp.js.map +2 -2
  54. package/helpers/getClosestParent.d.ts +2 -1
  55. package/helpers/getClosestParent.js.map +2 -2
  56. package/helpers/getDirectChildren.d.ts +13 -11
  57. package/helpers/getDirectChildren.js.map +2 -2
  58. package/helpers/getInstanceFromElement.d.ts +2 -1
  59. package/helpers/getInstanceFromElement.js +2 -2
  60. package/helpers/getInstanceFromElement.js.map +2 -2
  61. package/helpers/importOnInteraction.d.ts +3 -2
  62. package/helpers/importOnInteraction.js.map +2 -2
  63. package/helpers/importOnMediaQuery.d.ts +3 -2
  64. package/helpers/importOnMediaQuery.js.map +2 -2
  65. package/helpers/importWhenIdle.d.ts +3 -2
  66. package/helpers/importWhenIdle.js.map +2 -2
  67. package/helpers/importWhenPrefersMotion.d.ts +3 -2
  68. package/helpers/importWhenPrefersMotion.js.map +2 -2
  69. package/helpers/importWhenVisible.d.ts +3 -2
  70. package/helpers/importWhenVisible.js.map +2 -2
  71. package/helpers/index.d.ts +1 -0
  72. package/helpers/index.js +1 -0
  73. package/helpers/index.js.map +2 -2
  74. package/helpers/registerComponent.d.ts +10 -0
  75. package/helpers/registerComponent.js +11 -0
  76. package/helpers/registerComponent.js.map +7 -0
  77. package/helpers/utils.d.ts +1 -1
  78. package/helpers/utils.js.map +1 -1
  79. package/index.d.ts +1 -0
  80. package/index.js +4 -0
  81. package/index.js.map +2 -2
  82. package/package.json +1 -1
  83. package/services/AbstractService.d.ts +1 -1
  84. package/services/AbstractService.js.map +1 -1
  85. package/services/DragService.d.ts +3 -2
  86. package/services/DragService.js +5 -1
  87. package/services/DragService.js.map +2 -2
  88. package/services/KeyService.d.ts +2 -1
  89. package/services/KeyService.js.map +2 -2
  90. package/services/LoadService.d.ts +2 -1
  91. package/services/LoadService.js.map +2 -2
  92. package/services/MutationService.d.ts +2 -1
  93. package/services/MutationService.js.map +2 -2
  94. package/services/PointerService.d.ts +2 -1
  95. package/services/PointerService.js.map +2 -2
  96. package/services/RafService.d.ts +2 -1
  97. package/services/RafService.js.map +2 -2
  98. package/services/ResizeService.d.ts +2 -1
  99. package/services/ResizeService.js.map +2 -2
  100. package/services/ScrollService.d.ts +2 -1
  101. package/services/ScrollService.js.map +2 -2
  102. package/tsconfig.build.tsbuildinfo +1 -1
  103. package/utils/SmartQueue.js.map +1 -1
  104. package/utils/cache.d.ts +2 -1
  105. package/utils/cache.js.map +2 -2
  106. package/utils/collide/boundingRectToCircle.d.ts +3 -2
  107. package/utils/collide/boundingRectToCircle.js.map +2 -2
  108. package/utils/collide/collideCircleCircle.d.ts +3 -2
  109. package/utils/collide/collideCircleCircle.js.map +2 -2
  110. package/utils/collide/collideCircleRect.d.ts +3 -2
  111. package/utils/collide/collideCircleRect.js.map +2 -2
  112. package/utils/collide/collidePointCircle.d.ts +3 -2
  113. package/utils/collide/collidePointCircle.js.map +2 -2
  114. package/utils/collide/collidePointRect.d.ts +3 -2
  115. package/utils/collide/collidePointRect.js.map +2 -2
  116. package/utils/collide/collideRectRect.d.ts +3 -2
  117. package/utils/collide/collideRectRect.js.map +2 -2
  118. package/utils/css/animate.d.ts +2 -1
  119. package/utils/css/animate.js.map +2 -2
  120. package/utils/css/classes.d.ts +6 -3
  121. package/utils/css/classes.js.map +2 -2
  122. package/utils/css/getOffsetSizes.d.ts +2 -1
  123. package/utils/css/getOffsetSizes.js.map +2 -2
  124. package/utils/css/matrix.d.ts +10 -9
  125. package/utils/css/matrix.js.map +2 -2
  126. package/utils/css/styles.d.ts +4 -2
  127. package/utils/css/styles.js.map +2 -2
  128. package/utils/css/transform.d.ts +2 -1
  129. package/utils/css/transform.js.map +2 -2
  130. package/utils/css/transition.d.ts +3 -2
  131. package/utils/css/transition.js +1 -1
  132. package/utils/css/transition.js.map +2 -2
  133. package/utils/debounce.d.ts +5 -4
  134. package/utils/debounce.js.map +2 -2
  135. package/utils/dom/createElement.d.ts +24 -1
  136. package/utils/dom/createElement.js +8 -2
  137. package/utils/dom/createElement.js.map +2 -2
  138. package/utils/getComponentResolver.d.ts +1 -1
  139. package/utils/getComponentResolver.js.map +1 -1
  140. package/utils/history.d.ts +17 -14
  141. package/utils/history.js.map +2 -2
  142. package/utils/is.d.ts +25 -9
  143. package/utils/is.js.map +2 -2
  144. package/utils/keyCodes.d.ts +3 -0
  145. package/utils/keyCodes.js.map +2 -2
  146. package/utils/loadElement.d.ts +10 -5
  147. package/utils/loadElement.js.map +2 -2
  148. package/utils/math/clamp.d.ts +2 -6
  149. package/utils/math/clamp.js.map +2 -2
  150. package/utils/math/clamp01.d.ts +2 -4
  151. package/utils/math/clamp01.js.map +2 -2
  152. package/utils/math/createEases.d.ts +13 -5
  153. package/utils/math/createEases.js.map +2 -2
  154. package/utils/math/createRange.d.ts +2 -1
  155. package/utils/math/createRange.js.map +2 -2
  156. package/utils/math/damp.d.ts +7 -6
  157. package/utils/math/damp.js.map +2 -2
  158. package/utils/math/ease.d.ts +23 -14
  159. package/utils/math/ease.js.map +2 -2
  160. package/utils/math/inertiaFinalValue.d.ts +6 -5
  161. package/utils/math/inertiaFinalValue.js.map +2 -2
  162. package/utils/math/lerp.d.ts +6 -5
  163. package/utils/math/lerp.js.map +2 -2
  164. package/utils/math/map.d.ts +3 -2
  165. package/utils/math/map.js.map +2 -2
  166. package/utils/math/mean.d.ts +3 -0
  167. package/utils/math/mean.js.map +2 -2
  168. package/utils/math/round.d.ts +5 -4
  169. package/utils/math/round.js.map +2 -2
  170. package/utils/math/smoothTo.d.ts +2 -1
  171. package/utils/math/smoothTo.js +3 -7
  172. package/utils/math/smoothTo.js.map +2 -2
  173. package/utils/math/spring.d.ts +9 -9
  174. package/utils/math/spring.js.map +1 -1
  175. package/utils/math/wrap.d.ts +2 -1
  176. package/utils/math/wrap.js.map +2 -2
  177. package/utils/memo.d.ts +2 -1
  178. package/utils/memo.js.map +2 -2
  179. package/utils/memoize.d.ts +2 -1
  180. package/utils/memoize.js.map +2 -2
  181. package/utils/nextFrame.d.ts +2 -1
  182. package/utils/nextFrame.js.map +2 -2
  183. package/utils/nextMicrotask.d.ts +2 -1
  184. package/utils/nextMicrotask.js.map +2 -2
  185. package/utils/nextTick.d.ts +2 -1
  186. package/utils/nextTick.js.map +2 -2
  187. package/utils/noop.d.ts +1 -1
  188. package/utils/noop.js.map +1 -1
  189. package/utils/object/getAllProperties.d.ts +1 -1
  190. package/utils/object/getAllProperties.js.map +1 -1
  191. package/utils/random.d.ts +11 -8
  192. package/utils/random.js.map +2 -2
  193. package/utils/scheduler.d.ts +6 -1
  194. package/utils/scheduler.js.map +2 -2
  195. package/utils/scrollTo.d.ts +3 -2
  196. package/utils/scrollTo.js.map +2 -2
  197. package/utils/string/changeCase.d.ts +12 -6
  198. package/utils/string/changeCase.js.map +2 -2
  199. package/utils/string/endsWith.d.ts +2 -1
  200. package/utils/string/endsWith.js.map +2 -2
  201. package/utils/string/startsWith.d.ts +2 -1
  202. package/utils/string/startsWith.js.map +2 -2
  203. package/utils/string/withLeadingCharacters.d.ts +5 -4
  204. package/utils/string/withLeadingCharacters.js.map +2 -2
  205. package/utils/string/withLeadingSlash.d.ts +3 -2
  206. package/utils/string/withLeadingSlash.js.map +2 -2
  207. package/utils/string/withTrailingCharacters.d.ts +5 -4
  208. package/utils/string/withTrailingCharacters.js.map +2 -2
  209. package/utils/string/withTrailingSlash.d.ts +3 -2
  210. package/utils/string/withTrailingSlash.js.map +2 -2
  211. package/utils/string/withoutLeadingCharacters.d.ts +5 -4
  212. package/utils/string/withoutLeadingCharacters.js.map +2 -2
  213. package/utils/string/withoutLeadingCharactersRecursive.d.ts +5 -4
  214. package/utils/string/withoutLeadingCharactersRecursive.js.map +2 -2
  215. package/utils/string/withoutLeadingSlash.d.ts +3 -2
  216. package/utils/string/withoutLeadingSlash.js.map +2 -2
  217. package/utils/string/withoutTrailingCharacters.d.ts +5 -4
  218. package/utils/string/withoutTrailingCharacters.js.map +2 -2
  219. package/utils/string/withoutTrailingCharactersRecursive.d.ts +5 -4
  220. package/utils/string/withoutTrailingCharactersRecursive.js.map +2 -2
  221. package/utils/string/withoutTrailingSlash.d.ts +3 -2
  222. package/utils/string/withoutTrailingSlash.js.map +2 -2
  223. package/utils/throttle.d.ts +3 -2
  224. package/utils/throttle.js.map +2 -2
  225. package/utils/trapFocus.d.ts +4 -2
  226. package/utils/trapFocus.js.map +2 -2
  227. package/utils/tween.d.ts +1 -1
  228. package/utils/tween.js.map +1 -1
package/Base/Base.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ChildrenManager, RefsManager, ServicesManager, EventsManager, OptionsManager } from './managers/index.js';
2
2
  export type BaseEl = HTMLElement & {
3
- __base__?: WeakMap<BaseConstructor, Base | 'terminated'>;
3
+ __base__?: Map<string, Base | 'terminated'>;
4
4
  };
5
5
  export type BaseConstructor<T extends Base = Base> = {
6
6
  new (...args: any[]): T;
@@ -46,11 +46,13 @@ export type Managers = {
46
46
  };
47
47
  /**
48
48
  * Base class.
49
+ *
50
+ * @link https://js-toolkit.studiometa.dev/api/
49
51
  */
50
52
  export declare class Base<T extends BaseProps = BaseProps> {
51
53
  /**
52
54
  * Declare the `this.constructor` type
53
- * @see https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311
55
+ * @link https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311
54
56
  */
55
57
  ['constructor']: BaseConstructor;
56
58
  /**
@@ -126,8 +128,8 @@ export declare class Base<T extends BaseProps = BaseProps> {
126
128
  /**
127
129
  * Test if the given event has been bound to the instance.
128
130
  *
129
- * @param {string} event The event's name.
130
- * @returns {boolean} Wether the given event has been bound or not.
131
+ * @param {string} event The event's name.
132
+ * @return {boolean} Wether the given event has been bound or not.
131
133
  */
132
134
  __hasEvent(event: string): boolean;
133
135
  /**
@@ -155,15 +157,15 @@ export declare class Base<T extends BaseProps = BaseProps> {
155
157
  /**
156
158
  * Add an emitted event.
157
159
  *
158
- * @param {string} event The event name.
159
- * @returns {void}
160
+ * @param {string} event The event name.
161
+ * @return {void}
160
162
  */
161
163
  __addEmits(event: string): void;
162
164
  /**
163
165
  * Remove an emitted event.
164
166
  *
165
- * @param {string} event The event name.
166
- * @returns {void}
167
+ * @param {string} event The event name.
168
+ * @return {void}
167
169
  */
168
170
  __removeEmits(event: string): void;
169
171
  /**
@@ -175,7 +177,7 @@ export declare class Base<T extends BaseProps = BaseProps> {
175
177
  * Function to be called.
176
178
  * @param {boolean|AddEventListenerOptions} [options]
177
179
  * Options for the `removeEventListener` method.
178
- * @returns {() => void}
180
+ * @return {() => void}
179
181
  * A function to unbind the listener.
180
182
  */
181
183
  $on(event: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): () => void;
@@ -188,7 +190,7 @@ export declare class Base<T extends BaseProps = BaseProps> {
188
190
  * Function to be removed.
189
191
  * @param {boolean|EventListenerOptions} [options]
190
192
  * Options for the `removeEventListener` method.
191
- * @returns {void}
193
+ * @return {void}
192
194
  */
193
195
  $off(event: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
194
196
  /**
@@ -196,11 +198,11 @@ export declare class Base<T extends BaseProps = BaseProps> {
196
198
  *
197
199
  * @param {string} event Name of the event.
198
200
  * @param {any[]} args The arguments to apply to the functions bound to this event.
199
- * @returns {void}
201
+ * @return {void}
200
202
  */
201
203
  $emit(event: string | Event, ...args: unknown[]): void;
202
204
  /**
203
205
  * Register and mount all instances of the component.
204
206
  */
205
- static $register(nameOrSelector?: string): Array<Promise<Base>>;
207
+ static $register<T extends BaseProps = BaseProps, U extends typeof Base<T> = typeof Base<T>>(this: U, nameOrSelector?: string): Promise<InstanceType<U>>[];
206
208
  }
package/Base/Base.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  EventsManager,
13
13
  OptionsManager
14
14
  } from "./managers/index.js";
15
+ import { getInstanceFromElement } from "../helpers/getInstanceFromElement.js";
15
16
  import { noop, isDev, isFunction, isArray } from "../utils/index.js";
16
17
  let id = 0;
17
18
  class Base {
@@ -171,8 +172,8 @@ class Base {
171
172
  /**
172
173
  * Test if the given event has been bound to the instance.
173
174
  *
174
- * @param {string} event The event's name.
175
- * @returns {boolean} Wether the given event has been bound or not.
175
+ * @param {string} event The event's name.
176
+ * @return {boolean} Wether the given event has been bound or not.
176
177
  */
177
178
  __hasEvent(event) {
178
179
  const eventHandlers = this.__eventHandlers.get(event);
@@ -190,20 +191,20 @@ class Base {
190
191
  }
191
192
  return;
192
193
  }
193
- const { __config } = this;
194
- if (__config.name === "Base") {
194
+ const { $config } = this;
195
+ if ($config.name === "Base") {
195
196
  if (isDev) {
196
197
  throw new Error("The `config.name` property is required.");
197
198
  }
198
199
  return;
199
200
  }
200
- this.$id = `${__config.name}-${id}`;
201
+ this.$id = `${$config.name}-${id}`;
201
202
  id += 1;
202
203
  this.$el = element;
203
204
  if (!this.$el.__base__) {
204
- this.$el.__base__ = /* @__PURE__ */ new WeakMap();
205
+ this.$el.__base__ = /* @__PURE__ */ new Map();
205
206
  }
206
- this.$el.__base__.set(this.constructor, this);
207
+ this.$el.__base__.set($config.name, this);
207
208
  for (const service of ["Options", "Services", "Events", "Refs", "Children"]) {
208
209
  this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);
209
210
  }
@@ -297,14 +298,14 @@ class Base {
297
298
  // Execute the `terminated` hook if it exists
298
299
  addToQueue(() => this.__callMethod("terminated")),
299
300
  // Delete instance
300
- addToQueue(() => this.$el.__base__.set(this.constructor, "terminated"))
301
+ addToQueue(() => this.$el.__base__.set(this.$config.name, "terminated"))
301
302
  ]);
302
303
  }
303
304
  /**
304
305
  * Add an emitted event.
305
306
  *
306
- * @param {string} event The event name.
307
- * @returns {void}
307
+ * @param {string} event The event name.
308
+ * @return {void}
308
309
  */
309
310
  __addEmits(event) {
310
311
  const ctor = this.constructor;
@@ -317,8 +318,8 @@ class Base {
317
318
  /**
318
319
  * Remove an emitted event.
319
320
  *
320
- * @param {string} event The event name.
321
- * @returns {void}
321
+ * @param {string} event The event name.
322
+ * @return {void}
322
323
  */
323
324
  __removeEmits(event) {
324
325
  const ctor = this.constructor;
@@ -334,7 +335,7 @@ class Base {
334
335
  * Function to be called.
335
336
  * @param {boolean|AddEventListenerOptions} [options]
336
337
  * Options for the `removeEventListener` method.
337
- * @returns {() => void}
338
+ * @return {() => void}
338
339
  * A function to unbind the listener.
339
340
  */
340
341
  $on(event, listener, options) {
@@ -371,7 +372,7 @@ class Base {
371
372
  * Function to be removed.
372
373
  * @param {boolean|EventListenerOptions} [options]
373
374
  * Options for the `removeEventListener` method.
374
- * @returns {void}
375
+ * @return {void}
375
376
  */
376
377
  $off(event, listener, options) {
377
378
  if (isDev) {
@@ -386,7 +387,7 @@ class Base {
386
387
  *
387
388
  * @param {string} event Name of the event.
388
389
  * @param {any[]} args The arguments to apply to the functions bound to this event.
389
- * @returns {void}
390
+ * @return {void}
390
391
  */
391
392
  $emit(event, ...args) {
392
393
  if (isDev) {
@@ -401,7 +402,7 @@ class Base {
401
402
  */
402
403
  static $register(nameOrSelector) {
403
404
  return getComponentElements(nameOrSelector ?? this.config.name).map(
404
- (el) => new this(el).$mount()
405
+ async (el) => getInstanceFromElement(el, this) ?? new this(el).$mount()
405
406
  );
406
407
  }
407
408
  }
package/Base/Base.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/Base/Base.ts"],
4
- "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: WeakMap<BaseConstructor, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n */\nexport class Base<T extends BaseProps = BaseProps> {\n /**\n * Declare the `this.constructor` type\n * @see https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311\n */\n declare ['constructor']: BaseConstructor;\n\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Is the component currently mounting itself and its children?\n * @private\n */\n __isMounting = false;\n\n /**\n * Store the event handlers.\n * @private\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n * @private\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n get $config() {\n return this.__config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager<T['$refs'] & BaseRefs>;\n\n get $refs(): T['$refs'] & BaseRefs {\n return this.__refs.props;\n }\n\n __options: OptionsManager<T['$options'] & BaseOptions>;\n\n get $options(): T['$options'] & BaseOptions {\n return this.__options.props;\n }\n\n __children: ChildrenManager<T['$children'] & BaseChildren>;\n\n get $children(): T['$children'] & BaseChildren {\n return this.__children.props;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.$options.log ? window.console.log.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.$options.log ? window.console.warn.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.$options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @returns {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { __config } = this;\n\n if (__config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${__config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new WeakMap();\n }\n\n this.$el.__base__.set(this.constructor, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted || this.__isMounting) {\n return this;\n }\n\n this.__isMounting = true;\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.__children.registerAll()),\n addToQueue(() => this.__refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.__services.enableAll()),\n addToQueue(() => this.__children.mountAll()),\n ]);\n\n await addToQueue(() => {\n this.$isMounted = true;\n this.__callMethod('mounted');\n });\n\n this.__isMounting = false;\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.__refs.unregisterAll()),\n addToQueue(() => this.__services.disableAll()),\n // Redo\n addToQueue(() => this.__children.registerAll()),\n addToQueue(() => this.__refs.registerAll()),\n addToQueue(() => this.__services.enableAll()),\n // Update\n addToQueue(() => this.__children.updateAll()),\n ]);\n\n await addToQueue(() => this.__callMethod('updated'));\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n this.$isMounted = false;\n\n await Promise.all([\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.__refs.unregisterAll()),\n addToQueue(() => this.__services.disableAll()),\n addToQueue(() => this.__children.destroyAll()),\n ]);\n\n await addToQueue(() => this.__callMethod('destroyed'));\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.constructor, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __addEmits(event: string): void {\n const ctor = this.constructor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @returns {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.constructor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.addEventListener(event, listener, options);\n\n if (isDev) {\n if (!target) {\n console.warn(\n `[${this.$id}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${this.$el.constructor.name}\\`.`,\n );\n }\n }\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @returns {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @returns {void}\n */\n $emit(event: string | Event, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.$el.dispatchEvent(\n event instanceof Event ? event : new CustomEvent(event, { detail: args }),\n );\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register(nameOrSelector?: string): Array<Promise<Base>> {\n return getComponentElements(nameOrSelector ?? this.config.name).map((el) =>\n new this(el).$mount(),\n );\n }\n}\n"],
5
- "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,OAAO,YAAY,eAAe;AAEjD,IAAI,KAAK;AA+CF,MAAM,KAAsC;AAAA;AAAA;AAAA;AAAA,EAUjD,OAAgB,UAAU;AAAA;AAAA;AAAA;AAAA,EAK1B,UAA+B;AAAA;AAAA;AAAA;AAAA,EAK/B;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,EAMb,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAMf,kBAAwE,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA,EAKhF,IAAI,QAAc;AAChB,QAAI,CAAC,KAAK,SAAS;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,KAAK;AAClB,QAAI,OAAO,KAAK;AAEhB,WAAO,QAAQ;AACb,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO;AAAA,MACT;AAEA,eAAS,OAAO;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,WAAuB;AACzB,QAAI,QAAQ,OAAO,eAAe,IAAI;AACtC,QAAI,EAAE,OAAO,IAAI,MAAM;AAEvB,WAAO,MAAM,YAAY,UAAU,MAAM,YAAY,SAAS;AAC5D,eAAS,EAAE,GAAG,MAAM,YAAY,QAAQ,GAAG,OAAO;AAElD,UAAI,MAAM,YAAY,OAAO,SAAS;AACpC,eAAO,UAAU,EAAE,GAAG,MAAM,YAAY,OAAO,SAAS,GAAG,OAAO,QAAQ;AAAA,MAC5E;AAEA,UAAI,MAAM,YAAY,OAAO,SAAS,OAAO,OAAO;AAClD,eAAO,QAAQ,CAAC,GAAG,MAAM,YAAY,OAAO,OAAO,GAAG,OAAO,KAAK;AAAA,MACpE;AAEA,cAAQ,OAAO,eAAe,KAAK;AAAA,IACrC;AAEA,WAAO,UAAU,OAAO,WAAW,CAAC;AACpC,WAAO,OAAO,OAAO,QAAQ,CAAC;AAC9B,WAAO,aAAa,OAAO,cAAc,CAAC;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,MAEL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,IAAI,YAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA;AAAA,EAEA,IAAI,QAA+B;AACjC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA;AAAA,EAEA,IAAI,WAAwC;AAC1C,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA;AAAA,EAEA,IAAI,YAA2C;AAC7C,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAqC;AACvC,WAAO,KAAK,SAAS,MAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ,IAAI,KAAK,GAAG,GAAG,IAAI;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAsC;AACxC,WAAO,KAAK,SAAS,MAAM,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,GAAG,IAAI;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAwC;AAC1C,WAAO,SAAS,KAAK,SAAS,QAC1B,OAAO,QAAQ,IAAI,KAAK,QAAQ,YAAY,KAAK,GAAG,GAAG,IACvD;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAuB;AACzB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,WAAmB,MAA0B;AACxD,QAAI,OAAO;AACT,WAAK,QAAQ,cAAc,QAAQ,GAAG,IAAI;AAAA,IAC5C;AAEA,SAAK,MAAM,QAAQ,GAAG,IAAI;AAG1B,QAAI,CAAC,WAAW,KAAK,MAAM,CAAC,GAAG;AAC7B,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,IACpC;AAEA,WAAO,KAAK,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAwB;AACjC,UAAM,gBAAgB,KAAK,gBAAgB,IAAI,KAAK;AACpD,WAAO,iBAAiB,cAAc,OAAO;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,SAAsB;AAChC,QAAI,CAAC,SAAS;AACZ,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AACA;AAAA,IACF;AAEA,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,SAAS,SAAS,QAAQ;AAC5B,UAAI,OAAO;AACT,cAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D;AACA;AAAA,IACF;AAEA,SAAK,MAAM,GAAG,SAAS,IAAI,IAAI,EAAE;AACjC,UAAM;AAEN,SAAK,MAAM;AAEX,QAAI,CAAC,KAAK,IAAI,UAAU;AACtB,WAAK,IAAI,WAAW,oBAAI,QAAQ;AAAA,IAClC;AAEA,SAAK,IAAI,SAAS,IAAI,KAAK,aAAa,IAAI;AAE5C,eAAW,WAAW,CAAC,WAAW,YAAY,UAAU,QAAQ,UAAU,GAAG;AAC3E,WAAK,KAAK,QAAQ,YAAY,CAAC,EAAE,IAAI,IAAI,KAAK,WAAW,GAAG,OAAO,SAAS,EAAE,IAAI;AAAA,IACpF;AAEA,SAAK,IAAI,WAAW,MAAM;AACxB,kBAAY,IAAI;AAAA,IAClB,CAAC;AACD,SAAK,IAAI,aAAa,MAAM;AAC1B,qBAAe,IAAI;AAAA,IACrB,CAAC;AAED,QAAI,OAAO;AACT,WAAK,QAAQ,eAAe,IAAI;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAwB;AAC5B,QAAI,KAAK,cAAc,KAAK,cAAc;AACxC,aAAO;AAAA,IACT;AAEA,SAAK,eAAe;AACpB,SAAK,MAAM,gBAAgB;AAE3B,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAM,KAAK,WAAW,YAAY,CAAC;AAAA,MAC9C,WAAW,MAAM,KAAK,OAAO,YAAY,CAAC;AAAA,MAC1C,WAAW,MAAM,KAAK,SAAS,gBAAgB,CAAC;AAAA,MAChD,WAAW,MAAM,KAAK,WAAW,UAAU,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,WAAW,SAAS,CAAC;AAAA,IAC7C,CAAC;AAED,UAAM,WAAW,MAAM;AACrB,WAAK,aAAa;AAClB,WAAK,aAAa,SAAS;AAAA,IAC7B,CAAC;AAED,SAAK,eAAe;AAEpB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS;AAAA,IACxB;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,OAAO,cAAc,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,WAAW,WAAW,CAAC;AAAA;AAAA,MAE7C,WAAW,MAAM,KAAK,WAAW,YAAY,CAAC;AAAA,MAC9C,WAAW,MAAM,KAAK,OAAO,YAAY,CAAC;AAAA,MAC1C,WAAW,MAAM,KAAK,WAAW,UAAU,CAAC;AAAA;AAAA,MAE5C,WAAW,MAAM,KAAK,WAAW,UAAU,CAAC;AAAA,IAC9C,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,aAAa,SAAS,CAAC;AAEnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,QAAI,CAAC,KAAK,YAAY;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,OAAO;AACT,WAAK,QAAQ,UAAU;AAAA,IACzB;AAEA,SAAK,aAAa;AAElB,UAAM,QAAQ,IAAI;AAAA,MAChB,WAAW,MAAM,KAAK,SAAS,kBAAkB,CAAC;AAAA,MAClD,WAAW,MAAM,KAAK,OAAO,cAAc,CAAC;AAAA,MAC5C,WAAW,MAAM,KAAK,WAAW,WAAW,CAAC;AAAA,MAC7C,WAAW,MAAM,KAAK,WAAW,WAAW,CAAC;AAAA,IAC/C,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,aAAa,WAAW,CAAC;AAErD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,QAAI,OAAO;AACT,WAAK,QAAQ,YAAY;AAAA,IAC3B;AAEA,UAAM,QAAQ,IAAI;AAAA;AAAA,MAEhB,WAAW,MAAM,KAAK,SAAS,CAAC;AAAA;AAAA,MAEhC,WAAW,MAAM,KAAK,aAAa,YAAY,CAAC;AAAA;AAAA,MAEhD,WAAW,MAAM,KAAK,IAAI,SAAS,IAAI,KAAK,aAAa,YAAY,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAW,OAAqB;AAC9B,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,KAAK,OAAO,KAAK,GAAG;AAC9B,WAAK,OAAO,MAAM,KAAK,KAAK;AAAA,IAC9B,OAAO;AACL,WAAK,OAAO,QAAQ,CAAC,KAAK;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,OAAqB;AACjC,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK;AAC7C,SAAK,OAAO,MAAM,OAAO,OAAO,CAAC;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,IACE,OACA,UACA,SACY;AACZ,QAAI,OAAO;AACT,WAAK,QAAQ,OAAO,OAAO,UAAU,OAAO;AAAA,IAC9C;AAEA,QAAI,MAAM,KAAK,gBAAgB,IAAI,KAAK;AAExC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,WAAK,gBAAgB,IAAI,OAAO,GAAG;AAAA,IACrC;AAEA,QAAI,IAAI,QAAQ;AAEhB,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,YAAQ,iBAAiB,OAAO,UAAU,OAAO;AAEjD,QAAI,OAAO;AACT,UAAI,CAAC,QAAQ;AACX,gBAAQ;AAAA,UACN,IAAI,KAAK,GAAG;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,wCAAwC,KAAK,IAAI,YAAY,IAAI;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX,WAAK,KAAK,OAAO,UAAU,OAAO;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KACE,OACA,UACA,SACA;AACA,QAAI,OAAO;AACT,WAAK,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACtC;AAEA,SAAK,gBAAgB,IAAI,KAAK,EAAE,OAAO,QAAQ;AAE/C,UAAM,SAAS,eAAe,MAAM,OAAO,KAAK,QAAQ;AACxD,YAAQ,oBAAoB,OAAO,UAAU,OAAO;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAA0B,MAAiB;AAC/C,QAAI,OAAO;AACT,WAAK,QAAQ,SAAS,OAAO,IAAI;AAAA,IACnC;AAEA,SAAK,IAAI;AAAA,MACP,iBAAiB,QAAQ,QAAQ,IAAI,YAAY,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,gBAA+C;AAC9D,WAAO,qBAAqB,kBAAkB,KAAK,OAAO,IAAI,EAAE;AAAA,MAAI,CAAC,OACnE,IAAI,KAAK,EAAE,EAAE,OAAO;AAAA,IACtB;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["/* eslint-disable no-use-before-define */\nimport {\n getComponentElements,\n getEventTarget,\n addToQueue,\n addInstance,\n deleteInstance,\n} from './utils.js';\nimport {\n ChildrenManager,\n RefsManager,\n ServicesManager,\n EventsManager,\n OptionsManager,\n} from './managers/index.js';\nimport { getInstanceFromElement } from '../helpers/getInstanceFromElement.js';\nimport { noop, isDev, isFunction, isArray } from '../utils/index.js';\n\nlet id = 0;\n\nexport type BaseEl = HTMLElement & { __base__?: Map<string, Base | 'terminated'> };\nexport type BaseConstructor<T extends Base = Base> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n new (...args: any[]): T;\n prototype: Base;\n} & Pick<typeof Base, keyof typeof Base>;\nexport type BaseAsyncConstructor<T extends Base = Base> = (\n instance: Base,\n) => Promise<BaseConstructor<T> | { default: BaseConstructor<T> }>;\nexport type BaseOptions = { [name: string]: unknown };\nexport type BaseRefs = { [name: string]: HTMLElement | HTMLElement[] };\nexport type BaseChildren = { [nameOrSelector: string]: Base[] | Promise<Base>[] };\nexport type BaseConfigComponents = {\n [nameOrSelector: string]: BaseConstructor | BaseAsyncConstructor;\n};\n\nexport type BaseConfig = {\n name: string;\n debug?: boolean;\n log?: boolean;\n refs?: string[];\n emits?: string[];\n components?: BaseConfigComponents;\n options?: import('./managers/OptionsManager').OptionsSchema;\n};\n\nexport type BaseProps = {\n $el?: HTMLElement;\n $options?: BaseOptions;\n $refs?: BaseRefs;\n $children?: BaseChildren;\n $parent?: Base;\n};\n\nexport type Managers = {\n ChildrenManager: typeof ChildrenManager;\n EventsManager: typeof EventsManager;\n OptionsManager: typeof OptionsManager;\n RefsManager: typeof RefsManager;\n ServicesManager: typeof ServicesManager;\n};\n\n/**\n * Base class.\n *\n * @link https://js-toolkit.studiometa.dev/api/\n */\nexport class Base<T extends BaseProps = BaseProps> {\n /**\n * Declare the `this.constructor` type\n * @link https://github.com/microsoft/TypeScript/issues/3841#issuecomment-2381594311\n */\n declare ['constructor']: BaseConstructor;\n\n /**\n * This is a Base instance.\n */\n static readonly $isBase = true as const;\n\n /**\n * The instance parent.\n */\n $parent: T['$parent'] & Base = null;\n\n /**\n * The instance id.\n */\n $id: string;\n\n /**\n * The root element.\n */\n $el: T['$el'] & BaseEl;\n\n /**\n * The state of the component.\n */\n $isMounted = false;\n\n /**\n * Is the component currently mounting itself and its children?\n * @private\n */\n __isMounting = false;\n\n /**\n * Store the event handlers.\n * @private\n */\n __eventHandlers: Map<string, Set<EventListenerOrEventListenerObject>> = new Map();\n\n /**\n * Get the root instance of the app.\n */\n get $root(): Base {\n if (!this.$parent) {\n return this;\n }\n\n let parent = this.$parent;\n let root = this.$parent;\n\n while (parent) {\n if (!parent.$parent) {\n root = parent;\n }\n\n parent = parent.$parent;\n }\n\n return root;\n }\n\n /**\n * Merge configuration with the parents' configurations.\n * @private\n */\n get __config(): BaseConfig {\n let proto = Object.getPrototypeOf(this);\n let { config } = proto.constructor;\n\n while (proto.constructor.config && proto.constructor.$isBase) {\n config = { ...proto.constructor.config, ...config };\n\n if (proto.constructor.config.options) {\n config.options = { ...proto.constructor.config.options, ...config.options };\n }\n\n if (proto.constructor.config.emits && config.emits) {\n config.emits = [...proto.constructor.config.emits, ...config.emits];\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n config.options = config.options ?? {};\n config.refs = config.refs ?? [];\n config.components = config.components ?? {};\n\n return config;\n }\n\n get $config() {\n return this.__config;\n }\n\n static config: BaseConfig = {\n name: 'Base',\n emits: [\n // hook events\n 'before-mounted',\n 'mounted',\n 'updated',\n 'destroyed',\n 'terminated',\n // default services' events\n 'ticked',\n 'scrolled',\n 'resized',\n 'moved',\n 'loaded',\n 'keyed',\n ],\n };\n\n __services: ServicesManager;\n\n get $services(): ServicesManager {\n return this.__services;\n }\n\n __refs: RefsManager<T['$refs'] & BaseRefs>;\n\n get $refs(): T['$refs'] & BaseRefs {\n return this.__refs.props;\n }\n\n __options: OptionsManager<T['$options'] & BaseOptions>;\n\n get $options(): T['$options'] & BaseOptions {\n return this.__options.props;\n }\n\n __children: ChildrenManager<T['$children'] & BaseChildren>;\n\n get $children(): T['$children'] & BaseChildren {\n return this.__children.props;\n }\n\n __events: EventsManager;\n\n /**\n * Small helper to log stuff.\n */\n get $log(): (...args: unknown[]) => void {\n return this.$options.log ? window.console.log.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to make warning easier.\n */\n get $warn(): (...args: unknown[]) => void {\n return this.$options.log ? window.console.warn.bind(window, `[${this.$id}]`) : noop;\n }\n\n /**\n * Small helper to debug information.\n */\n get __debug(): (...args: unknown[]) => void {\n return isDev && this.$options.debug\n ? window.console.log.bind(window, `[debug] [${this.$id}]`)\n : noop;\n }\n\n /**\n * Get manager constructors.\n */\n get __managers(): Managers {\n return {\n ChildrenManager,\n EventsManager,\n OptionsManager,\n RefsManager,\n ServicesManager,\n };\n }\n\n /**\n * Call an instance method and emit corresponding events.\n */\n __callMethod(method: string, ...args: unknown[]): unknown {\n if (isDev) {\n this.__debug('callMethod', method, ...args);\n }\n\n this.$emit(method, ...args);\n\n // We always emit an event, but we do not call the method if it does not exist\n if (!isFunction(this[method])) {\n return null;\n }\n\n if (isDev) {\n this.__debug(method, this, ...args);\n }\n\n return this[method].call(this, ...args);\n }\n\n /**\n * Test if the given event has been bound to the instance.\n *\n * @param {string} event The event's name.\n * @return {boolean} Wether the given event has been bound or not.\n */\n __hasEvent(event: string): boolean {\n const eventHandlers = this.__eventHandlers.get(event);\n return eventHandlers && eventHandlers.size > 0;\n }\n\n /**\n * Class constructor where all the magic takes place.\n *\n * @param {HTMLElement} element The component's root element dd.\n */\n constructor(element: HTMLElement) {\n if (!element) {\n if (isDev) {\n throw new Error('The root element must be defined.');\n }\n return;\n }\n\n const { $config } = this;\n\n if ($config.name === 'Base') {\n if (isDev) {\n throw new Error('The `config.name` property is required.');\n }\n return;\n }\n\n this.$id = `${$config.name}-${id}`;\n id += 1;\n\n this.$el = element;\n\n if (!this.$el.__base__) {\n this.$el.__base__ = new Map();\n }\n\n this.$el.__base__.set($config.name, this);\n\n for (const service of ['Options', 'Services', 'Events', 'Refs', 'Children']) {\n this[`__${service.toLowerCase()}`] = new this.__managers[`${service}Manager`](this);\n }\n\n this.$on('mounted', () => {\n addInstance(this);\n });\n this.$on('destroyed', () => {\n deleteInstance(this);\n });\n\n if (isDev) {\n this.__debug('constructor', this);\n }\n }\n\n /**\n * Trigger the `mounted` callback.\n */\n async $mount(): Promise<this> {\n if (this.$isMounted || this.__isMounting) {\n return this;\n }\n\n this.__isMounting = true;\n this.$emit('before-mounted');\n\n if (isDev) {\n this.__debug('$mount');\n }\n\n await Promise.all([\n addToQueue(() => this.__children.registerAll()),\n addToQueue(() => this.__refs.registerAll()),\n addToQueue(() => this.__events.bindRootElement()),\n addToQueue(() => this.__services.enableAll()),\n addToQueue(() => this.__children.mountAll()),\n ]);\n\n await addToQueue(() => {\n this.$isMounted = true;\n this.__callMethod('mounted');\n });\n\n this.__isMounting = false;\n\n return this;\n }\n\n /**\n * Update the instance children.\n */\n async $update(): Promise<this> {\n if (isDev) {\n this.__debug('$update');\n }\n\n await Promise.all([\n // Undo\n addToQueue(() => this.__refs.unregisterAll()),\n addToQueue(() => this.__services.disableAll()),\n // Redo\n addToQueue(() => this.__children.registerAll()),\n addToQueue(() => this.__refs.registerAll()),\n addToQueue(() => this.__services.enableAll()),\n // Update\n addToQueue(() => this.__children.updateAll()),\n ]);\n\n await addToQueue(() => this.__callMethod('updated'));\n\n return this;\n }\n\n /**\n * Trigger the `destroyed` callback.\n */\n async $destroy(): Promise<this> {\n if (!this.$isMounted) {\n return this;\n }\n\n if (isDev) {\n this.__debug('$destroy');\n }\n\n this.$isMounted = false;\n\n await Promise.all([\n addToQueue(() => this.__events.unbindRootElement()),\n addToQueue(() => this.__refs.unregisterAll()),\n addToQueue(() => this.__services.disableAll()),\n addToQueue(() => this.__children.destroyAll()),\n ]);\n\n await addToQueue(() => this.__callMethod('destroyed'));\n\n return this;\n }\n\n /**\n * Terminate a child instance when it is not needed anymore.\n */\n async $terminate(): Promise<void> {\n if (isDev) {\n this.__debug('$terminate');\n }\n\n await Promise.all([\n // First, destroy the component.\n addToQueue(() => this.$destroy()),\n // Execute the `terminated` hook if it exists\n addToQueue(() => this.__callMethod('terminated')),\n // Delete instance\n addToQueue(() => this.$el.__base__.set(this.$config.name, 'terminated')),\n ]);\n }\n\n /**\n * Add an emitted event.\n *\n * @param {string} event The event name.\n * @return {void}\n */\n __addEmits(event: string): void {\n const ctor = this.constructor;\n if (isArray(ctor.config.emits)) {\n ctor.config.emits.push(event);\n } else {\n ctor.config.emits = [event];\n }\n }\n\n /**\n * Remove an emitted event.\n *\n * @param {string} event The event name.\n * @return {void}\n */\n __removeEmits(event: string): void {\n const ctor = this.constructor;\n const index = ctor.config.emits.indexOf(event);\n ctor.config.emits.splice(index, 1);\n }\n\n /**\n * Bind a listener function to an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be called.\n * @param {boolean|AddEventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @return {() => void}\n * A function to unbind the listener.\n */\n $on(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): () => void {\n if (isDev) {\n this.__debug('$on', event, listener, options);\n }\n\n let set = this.__eventHandlers.get(event);\n\n if (!set) {\n set = new Set();\n this.__eventHandlers.set(event, set);\n }\n\n set.add(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.addEventListener(event, listener, options);\n\n if (isDev) {\n if (!target) {\n console.warn(\n `[${this.$id}]`,\n `The \"${event}\" event is missing from the configuration and is not a native`,\n `event for the root element of type \\`${this.$el.constructor.name}\\`.`,\n );\n }\n }\n\n return () => {\n this.$off(event, listener, options);\n };\n }\n\n /**\n * Unbind a listener function from an event.\n *\n * @param {string} event\n * Name of the event.\n * @param {EventListenerOrEventListenerObject} listener\n * Function to be removed.\n * @param {boolean|EventListenerOptions} [options]\n * Options for the `removeEventListener` method.\n * @return {void}\n */\n $off(\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {\n if (isDev) {\n this.__debug('$off', event, listener);\n }\n\n this.__eventHandlers.get(event).delete(listener);\n\n const target = getEventTarget(this, event, this.__config);\n target?.removeEventListener(event, listener, options);\n }\n\n /**\n * Emits an event.\n *\n * @param {string} event Name of the event.\n * @param {any[]} args The arguments to apply to the functions bound to this event.\n * @return {void}\n */\n $emit(event: string | Event, ...args: unknown[]) {\n if (isDev) {\n this.__debug('$emit', event, args);\n }\n\n this.$el.dispatchEvent(\n event instanceof Event ? event : new CustomEvent(event, { detail: args }),\n );\n }\n\n /**\n * Register and mount all instances of the component.\n */\n static $register<T extends BaseProps = BaseProps, U extends typeof Base<T> = typeof Base<T>>(\n this: U,\n nameOrSelector?: string,\n ): Promise<InstanceType<U>>[] {\n return getComponentElements(nameOrSelector ?? this.config.name).map(\n async (el) =>\n getInstanceFromElement(el, this) ?? (new this(el).$mount() as Promise<InstanceType<U>>),\n );\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,7 @@ export declare class AbstractManager<T extends any = any> {
11
11
  * Get the base instance root element.
12
12
  */
13
13
  get __element(): HTMLElement & {
14
- __base__?: WeakMap<import("../Base.js").BaseConstructor, Base | "terminated">;
14
+ __base__?: Map<string, Base | "terminated">;
15
15
  };
16
16
  /**
17
17
  * Get the base instance config.
@@ -57,11 +57,11 @@ export declare class ChildrenManager<T> extends AbstractManager<T> {
57
57
  /**
58
58
  * Get a child component's instance.
59
59
  *
60
- * @param {HTMLElement & { __base__?: WeakMap<BaseConstructor, Base> }} el
60
+ * @param {BaseEl} el
61
61
  * The root element of the child component.
62
62
  * @param {BaseConstructor|BaseAsyncConstructor} ComponentClass
63
63
  * A Base class or a Promise for async components.
64
- * @returns {Base|Promise<Base | 'terminated'>|'terminated'}
64
+ * @return {Base|Promise<Base | 'terminated'>|'terminated'}
65
65
  * A Base instance or a Promise resolving to a Base instance.
66
66
  * @private
67
67
  */
@@ -92,11 +92,11 @@ class ChildrenManager extends AbstractManager {
92
92
  /**
93
93
  * Get a child component's instance.
94
94
  *
95
- * @param {HTMLElement & { __base__?: WeakMap<BaseConstructor, Base> }} el
95
+ * @param {BaseEl} el
96
96
  * The root element of the child component.
97
97
  * @param {BaseConstructor|BaseAsyncConstructor} ComponentClass
98
98
  * A Base class or a Promise for async components.
99
- * @returns {Base|Promise<Base | 'terminated'>|'terminated'}
99
+ * @return {Base|Promise<Base | 'terminated'>|'terminated'}
100
100
  * A Base instance or a Promise resolving to a Base instance.
101
101
  * @private
102
102
  */
@@ -109,8 +109,8 @@ class ChildrenManager extends AbstractManager {
109
109
  if (asyncComponentPromise) {
110
110
  ctor = asyncComponentPromise.ctor;
111
111
  }
112
- if (el.__base__ && el.__base__.has(ctor)) {
113
- return el.__base__.get(ctor);
112
+ if (el.__base__ && el.__base__.has(ctor.config.name)) {
113
+ return el.__base__.get(ctor.config.name);
114
114
  }
115
115
  const child = new ctor(el);
116
116
  Object.defineProperty(child, "$parent", { get: () => this.__base });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/ChildrenManager.ts"],
4
- "sourcesContent": ["import type { Base, BaseConstructor, BaseAsyncConstructor, BaseEl } from '../index.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { getComponentElements, addToQueue } from '../utils.js';\n\n/**\n * Children manager.\n */\nexport class ChildrenManager<T> extends AbstractManager<T> {\n /**\n * Store async component promises to avoid calling them multiple times and\n * waiting for them when they are already resolved.\n */\n __asyncComponentPromises: WeakMap<\n BaseAsyncConstructor,\n {\n promise: ReturnType<BaseAsyncConstructor>;\n status: 'pending' | 'resolved';\n ctor?: BaseConstructor;\n }\n > = new WeakMap();\n\n get registeredNames(): string[] {\n return Object.keys(this.props);\n }\n\n /**\n * Register instances of all children components.\n */\n async registerAll() {\n for (const [name, component] of Object.entries(this.__config.components)) {\n this.__register(name, component);\n }\n }\n\n /**\n * Mount all child component instances.\n */\n async mountAll() {\n await this.__triggerHookForAll('$mount');\n }\n\n /**\n * Update all child component instances.\n */\n async updateAll() {\n await this.__triggerHookForAll('$update');\n }\n\n /**\n * Destroy all child component instances.\n */\n async destroyAll() {\n await this.__triggerHookForAll('$destroy');\n }\n\n /**\n * Execute the given hook for the given instance.\n *\n * @param {'$mount'|'$update'|'$destroy'} hook The hook to trigger.\n * @param {Base} instance The target instance.\n * @param {string} name The name of the component.\n * @private\n */\n async __triggerHook(hook: '$mount' | '$update' | '$destroy', instance: Base, name: string) {\n if (hook === '$update' && !instance.$isMounted) {\n // eslint-disable-next-line no-param-reassign\n hook = '$mount';\n }\n\n if (hook === '$update' || hook === '$destroy') {\n this.__eventsManager.unbindChild(name, instance);\n }\n\n if (hook === '$update' || hook === '$mount') {\n this.__eventsManager.bindChild(name, instance);\n }\n\n await instance[hook]();\n }\n\n /**\n * Register instance of a child component.\n *\n * @param {string} name\n * The name of the child component.\n * @param {BaseConstructor|BaseAsyncConstructor} component\n * A Base class or a Promise for async components.\n * @private\n */\n __register(name: string, component: BaseConstructor | BaseAsyncConstructor) {\n Object.defineProperty(this.props, name, {\n enumerable: true,\n configurable: true,\n get: () => this.__getValue(name, component),\n });\n }\n\n /**\n * Get children.\n * @private\n */\n __getValue(name: string, component: BaseConstructor | BaseAsyncConstructor) {\n const elements = getComponentElements(name, this.__element);\n\n if (elements.length === 0) {\n return [];\n }\n\n const children = [];\n for (const element of elements) {\n const child = this.__getChild(element, component);\n if (child !== 'terminated') {\n children.push(child);\n }\n }\n\n return children;\n }\n\n /**\n * Get a child component's instance.\n *\n * @param {HTMLElement & { __base__?: WeakMap<BaseConstructor, Base> }} el\n * The root element of the child component.\n * @param {BaseConstructor|BaseAsyncConstructor} ComponentClass\n * A Base class or a Promise for async components.\n * @returns {Base|Promise<Base | 'terminated'>|'terminated'}\n * A Base instance or a Promise resolving to a Base instance.\n * @private\n */\n __getChild(\n el: BaseEl,\n ComponentClass: BaseConstructor | BaseAsyncConstructor,\n ): Base | Promise<Base | 'terminated'> | 'terminated' {\n const asyncComponentPromise = this.__asyncComponentPromises.get(\n ComponentClass as BaseAsyncConstructor,\n );\n\n // Test if we have a constructor and not a promise or if the promise has been resolved\n if (\n '$isBase' in ComponentClass ||\n (asyncComponentPromise && asyncComponentPromise.status === 'resolved')\n ) {\n let ctor = ComponentClass as BaseConstructor;\n\n // Get resolved constructor from weakmap.\n // Only test for existence as the status was checked before.\n if (asyncComponentPromise) {\n ctor = asyncComponentPromise.ctor;\n }\n\n // Return existing instance if it exists\n if (el.__base__ && el.__base__.has(ctor)) {\n return el.__base__.get(ctor);\n }\n\n // Return a new instance if the component class is a child of the Base class\n // eslint-disable-next-line new-cap\n const child = new ctor(el);\n Object.defineProperty(child, '$parent', { get: () => this.__base });\n return child;\n }\n\n const promise = asyncComponentPromise\n ? asyncComponentPromise.promise\n : ComponentClass(this.__base);\n\n if (!asyncComponentPromise) {\n this.__asyncComponentPromises.set(ComponentClass, {\n promise,\n status: 'pending',\n ctor: undefined,\n });\n }\n\n // Resolve async components\n return promise.then((module) => {\n // @ts-ignore\n const ctor = module.default ?? module;\n\n this.__asyncComponentPromises.set(ComponentClass, {\n promise,\n status: 'resolved',\n ctor,\n });\n\n return this.__getChild(el, ctor);\n });\n }\n\n /**\n * Execute the given hook for all children instances.\n *\n * @param {'$mount'|'$update'|'$destroy'} hook The hook to execute.\n * @private\n */\n async __triggerHookForAll(hook: '$mount' | '$update' | '$destroy') {\n return addToQueue(() => {\n const promises = [];\n for (const name of this.registeredNames) {\n for (const instance of this.props[name]) {\n if (instance instanceof Promise) {\n instance.then((resolvedInstance) =>\n addToQueue(() => this.__triggerHook(hook, resolvedInstance, name)),\n );\n } else {\n promises.push(addToQueue(() => this.__triggerHook(hook, instance, name)));\n }\n }\n }\n return Promise.all(promises);\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { Base, BaseConstructor, BaseAsyncConstructor, BaseEl } from '../index.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { getComponentElements, addToQueue } from '../utils.js';\n\n/**\n * Children manager.\n */\nexport class ChildrenManager<T> extends AbstractManager<T> {\n /**\n * Store async component promises to avoid calling them multiple times and\n * waiting for them when they are already resolved.\n */\n __asyncComponentPromises: WeakMap<\n BaseAsyncConstructor,\n {\n promise: ReturnType<BaseAsyncConstructor>;\n status: 'pending' | 'resolved';\n ctor?: BaseConstructor;\n }\n > = new WeakMap();\n\n get registeredNames(): string[] {\n return Object.keys(this.props);\n }\n\n /**\n * Register instances of all children components.\n */\n async registerAll() {\n for (const [name, component] of Object.entries(this.__config.components)) {\n this.__register(name, component);\n }\n }\n\n /**\n * Mount all child component instances.\n */\n async mountAll() {\n await this.__triggerHookForAll('$mount');\n }\n\n /**\n * Update all child component instances.\n */\n async updateAll() {\n await this.__triggerHookForAll('$update');\n }\n\n /**\n * Destroy all child component instances.\n */\n async destroyAll() {\n await this.__triggerHookForAll('$destroy');\n }\n\n /**\n * Execute the given hook for the given instance.\n *\n * @param {'$mount'|'$update'|'$destroy'} hook The hook to trigger.\n * @param {Base} instance The target instance.\n * @param {string} name The name of the component.\n * @private\n */\n async __triggerHook(hook: '$mount' | '$update' | '$destroy', instance: Base, name: string) {\n if (hook === '$update' && !instance.$isMounted) {\n // eslint-disable-next-line no-param-reassign\n hook = '$mount';\n }\n\n if (hook === '$update' || hook === '$destroy') {\n this.__eventsManager.unbindChild(name, instance);\n }\n\n if (hook === '$update' || hook === '$mount') {\n this.__eventsManager.bindChild(name, instance);\n }\n\n await instance[hook]();\n }\n\n /**\n * Register instance of a child component.\n *\n * @param {string} name\n * The name of the child component.\n * @param {BaseConstructor|BaseAsyncConstructor} component\n * A Base class or a Promise for async components.\n * @private\n */\n __register(name: string, component: BaseConstructor | BaseAsyncConstructor) {\n Object.defineProperty(this.props, name, {\n enumerable: true,\n configurable: true,\n get: () => this.__getValue(name, component),\n });\n }\n\n /**\n * Get children.\n * @private\n */\n __getValue(name: string, component: BaseConstructor | BaseAsyncConstructor) {\n const elements = getComponentElements(name, this.__element);\n\n if (elements.length === 0) {\n return [];\n }\n\n const children = [];\n for (const element of elements) {\n const child = this.__getChild(element, component);\n if (child !== 'terminated') {\n children.push(child);\n }\n }\n\n return children;\n }\n\n /**\n * Get a child component's instance.\n *\n * @param {BaseEl} el\n * The root element of the child component.\n * @param {BaseConstructor|BaseAsyncConstructor} ComponentClass\n * A Base class or a Promise for async components.\n * @return {Base|Promise<Base | 'terminated'>|'terminated'}\n * A Base instance or a Promise resolving to a Base instance.\n * @private\n */\n __getChild(\n el: BaseEl,\n ComponentClass: BaseConstructor | BaseAsyncConstructor,\n ): Base | Promise<Base | 'terminated'> | 'terminated' {\n const asyncComponentPromise = this.__asyncComponentPromises.get(\n ComponentClass as BaseAsyncConstructor,\n );\n\n // Test if we have a constructor and not a promise or if the promise has been resolved\n if (\n '$isBase' in ComponentClass ||\n (asyncComponentPromise && asyncComponentPromise.status === 'resolved')\n ) {\n let ctor = ComponentClass as BaseConstructor;\n\n // Get resolved constructor from weakmap.\n // Only test for existence as the status was checked before.\n if (asyncComponentPromise) {\n ctor = asyncComponentPromise.ctor;\n }\n\n // Return existing instance if it exists\n if (el.__base__ && el.__base__.has(ctor.config.name)) {\n return el.__base__.get(ctor.config.name);\n }\n\n // Return a new instance if the component class is a child of the Base class\n // eslint-disable-next-line new-cap\n const child = new ctor(el);\n Object.defineProperty(child, '$parent', { get: () => this.__base });\n return child;\n }\n\n const promise = asyncComponentPromise\n ? asyncComponentPromise.promise\n : ComponentClass(this.__base);\n\n if (!asyncComponentPromise) {\n this.__asyncComponentPromises.set(ComponentClass, {\n promise,\n status: 'pending',\n ctor: undefined,\n });\n }\n\n // Resolve async components\n return promise.then((module) => {\n // @ts-ignore\n const ctor = module.default ?? module;\n\n this.__asyncComponentPromises.set(ComponentClass, {\n promise,\n status: 'resolved',\n ctor,\n });\n\n return this.__getChild(el, ctor);\n });\n }\n\n /**\n * Execute the given hook for all children instances.\n *\n * @param {'$mount'|'$update'|'$destroy'} hook The hook to execute.\n * @private\n */\n async __triggerHookForAll(hook: '$mount' | '$update' | '$destroy') {\n return addToQueue(() => {\n const promises = [];\n for (const name of this.registeredNames) {\n for (const instance of this.props[name]) {\n if (instance instanceof Promise) {\n instance.then((resolvedInstance) =>\n addToQueue(() => this.__triggerHook(hook, resolvedInstance, name)),\n );\n } else {\n promises.push(addToQueue(() => this.__triggerHook(hook, instance, name)));\n }\n }\n }\n return Promise.all(promises);\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -25,8 +25,8 @@ export declare class EventsManager extends AbstractManager {
25
25
  */
26
26
  __documentHandler: {
27
27
  /**
28
- * @param {Event|CustomEvent} event
29
- * @returns {void}
28
+ * @param {Event|CustomEvent} event
29
+ * @return {void}
30
30
  */
31
31
  handleEvent: (event: any) => void;
32
32
  };
@@ -37,8 +37,8 @@ export declare class EventsManager extends AbstractManager {
37
37
  */
38
38
  __windowHandler: {
39
39
  /**
40
- * @param {Event|CustomEvent} event
41
- * @returns {void}
40
+ * @param {Event|CustomEvent} event
41
+ * @return {void}
42
42
  */
43
43
  handleEvent: (event: any) => void;
44
44
  };
@@ -61,7 +61,7 @@ export declare class EventsManager extends AbstractManager {
61
61
  * The name of the ref.
62
62
  * @param {HTMLElement[]} elements
63
63
  * The elements of the ref.
64
- * @returns {void}
64
+ * @return {void}
65
65
  */
66
66
  bindRef(name: string, elements: HTMLElement[]): void;
67
67
  /**
@@ -71,7 +71,7 @@ export declare class EventsManager extends AbstractManager {
71
71
  * The name of the ref.
72
72
  * @param {HTMLElement[]} elements
73
73
  * The elements of the ref.
74
- * @returns {void}
74
+ * @return {void}
75
75
  */
76
76
  unbindRef(name: string, elements: HTMLElement[]): void;
77
77
  /**
@@ -81,7 +81,7 @@ export declare class EventsManager extends AbstractManager {
81
81
  * The name of the ref.
82
82
  * @param {Base} instance
83
83
  * A base instance.
84
- * @returns {void}
84
+ * @return {void}
85
85
  */
86
86
  bindChild(name: string, instance: Base): void;
87
87
  /**
@@ -91,19 +91,19 @@ export declare class EventsManager extends AbstractManager {
91
91
  * The name of the ref.
92
92
  * @param {Base} instance
93
93
  * A base instance.
94
- * @returns {void}
94
+ * @return {void}
95
95
  */
96
96
  unbindChild(name: string, instance: Base): void;
97
97
  /**
98
98
  * Bind event methods on the root element.
99
99
  *
100
- * @returns {void}
100
+ * @return {void}
101
101
  */
102
102
  bindRootElement(): void;
103
103
  /**
104
104
  * Unbind event method from the root element.
105
105
  *
106
- * @returns {void}
106
+ * @return {void}
107
107
  */
108
108
  unbindRootElement(): void;
109
109
  }
@@ -112,8 +112,8 @@ class EventsManager extends AbstractManager {
112
112
  */
113
113
  __documentHandler = {
114
114
  /**
115
- * @param {Event|CustomEvent} event
116
- * @returns {void}
115
+ * @param {Event|CustomEvent} event
116
+ * @return {void}
117
117
  */
118
118
  handleEvent: (event) => {
119
119
  const normalizedEventName = pascalCase(event.type);
@@ -128,8 +128,8 @@ class EventsManager extends AbstractManager {
128
128
  */
129
129
  __windowHandler = {
130
130
  /**
131
- * @param {Event|CustomEvent} event
132
- * @returns {void}
131
+ * @param {Event|CustomEvent} event
132
+ * @return {void}
133
133
  */
134
134
  handleEvent: (event) => {
135
135
  const normalizedEventName = pascalCase(event.type);
@@ -189,7 +189,7 @@ class EventsManager extends AbstractManager {
189
189
  * The name of the ref.
190
190
  * @param {HTMLElement[]} elements
191
191
  * The elements of the ref.
192
- * @returns {void}
192
+ * @return {void}
193
193
  */
194
194
  bindRef(name, elements) {
195
195
  manageRef(this, name, elements);
@@ -201,7 +201,7 @@ class EventsManager extends AbstractManager {
201
201
  * The name of the ref.
202
202
  * @param {HTMLElement[]} elements
203
203
  * The elements of the ref.
204
- * @returns {void}
204
+ * @return {void}
205
205
  */
206
206
  unbindRef(name, elements) {
207
207
  manageRef(this, name, elements, "remove");
@@ -213,7 +213,7 @@ class EventsManager extends AbstractManager {
213
213
  * The name of the ref.
214
214
  * @param {Base} instance
215
215
  * A base instance.
216
- * @returns {void}
216
+ * @return {void}
217
217
  */
218
218
  bindChild(name, instance) {
219
219
  manageChild(this, name, instance);
@@ -225,7 +225,7 @@ class EventsManager extends AbstractManager {
225
225
  * The name of the ref.
226
226
  * @param {Base} instance
227
227
  * A base instance.
228
- * @returns {void}
228
+ * @return {void}
229
229
  */
230
230
  unbindChild(name, instance) {
231
231
  manageChild(this, name, instance, "remove");
@@ -233,7 +233,7 @@ class EventsManager extends AbstractManager {
233
233
  /**
234
234
  * Bind event methods on the root element.
235
235
  *
236
- * @returns {void}
236
+ * @return {void}
237
237
  */
238
238
  bindRootElement() {
239
239
  manageRootElement(this);
@@ -241,7 +241,7 @@ class EventsManager extends AbstractManager {
241
241
  /**
242
242
  * Unbind event method from the root element.
243
243
  *
244
- * @returns {void}
244
+ * @return {void}
245
245
  */
246
246
  unbindRootElement() {
247
247
  manageRootElement(this, "remove");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/Base/managers/EventsManager.ts"],
4
- "sourcesContent": ["import type { Base, BaseProps } from '../index.js';\nimport { getAllProperties } from '../../utils/object/getAllProperties.js';\nimport { dashCase, isArray, pascalCase } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @returns {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @returns {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return dashCase(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @returns {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n element?.[action](event, that.__refsHandler);\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @returns {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n const config = instance.__config;\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n if (getEventTarget(instance, event, config)) {\n instance[action](event, that.__childrenHandler);\n }\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @returns {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n } else {\n const target = getEventTarget(base, event, config);\n target?.[modeMethod](event, that.__rootElementHandler);\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? (event.detail ?? []) : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @returns {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = pascalCase(refName);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const children = this.__base.$children;\n\n for (const childName of Object.keys(children)) {\n let index = -1;\n\n for (const child of children[childName] as Base<BaseProps>[]) {\n index++;\n\n if (\n child.$el === event.currentTarget &&\n (eventIsNative(event.type, child.$el) ||\n eventIsDefinedInConfig(event.type, child.__config))\n ) {\n const normalizedEventName = pascalCase(event.type);\n const normalizedChildName = pascalCase(childName);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: child }));\n }\n }\n }\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @returns {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @returns {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @returns {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @returns {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
4
+ "sourcesContent": ["import type { Base, BaseProps } from '../index.js';\nimport { getAllProperties } from '../../utils/object/getAllProperties.js';\nimport { dashCase, isArray, pascalCase } from '../../utils/index.js';\nimport { getEventTarget, eventIsNative, eventIsDefinedInConfig } from '../utils.js';\nimport { AbstractManager } from './AbstractManager.js';\nimport { normalizeRefName } from './RefsManager.js';\nimport { features } from '../features.js';\n\nconst regexes = new Map();\n\n/**\n * Get a regex with a cache;\n *\n * @param {string} regex\n * @return {RegExp}\n */\nfunction getRegex(regex: string): RegExp {\n if (!regexes.has(regex)) {\n regexes.set(regex, new RegExp(regex));\n }\n\n return regexes.get(regex);\n}\n\n/**\n * Get the event name from the given method and its tied ref or children name.\n *\n * @param {string} method\n * @param {string} name\n * @return {string}\n * @private\n */\nfunction getEventNameByMethod(method: string, name = ''): string {\n const regex = getRegex(`^on${pascalCase(name)}([A-Z].*)$`);\n const [, event] = method.match(regex);\n return dashCase(event);\n}\n\n/**\n * Get the base instance methods matching the `onSomething` pattern.\n *\n * @param {EventsManager} that\n * @param {string} [name]\n * @return {string[]}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction getEventMethodsByName(that: EventsManager, name = ''): string[] {\n const regex = getRegex(`^on${pascalCase(name)}[A-Z].*$`);\n const key = regex.toString();\n\n let methods = that.__methodsCache.get(key);\n\n if (!methods) {\n methods = Array.from(\n getAllProperties(that.__base, [], (method) => regex.test(method)).reduce(\n (set, [method]) => set.add(method),\n new Set(),\n ),\n ) as string[];\n that.__methodsCache.set(key, methods);\n }\n\n return methods;\n}\n\n/**\n * Manage a ref event methods.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @return {void}\n * @private\n */\nfunction manageRef(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n elements: HTMLElement[],\n mode: 'add' | 'remove' = 'add',\n) {\n const action = `${mode}EventListener`;\n const methods = getEventMethodsByName(that, name);\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n for (const element of elements) {\n element?.[action](event, that.__refsHandler);\n }\n }\n}\n/**\n * Manage event methods to the given child instance.\n *\n * @param {EventsManager} that\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners.\n * @return {void}\n * @private\n */\nfunction manageChild(\n // eslint-disable-next-line no-use-before-define\n that: EventsManager,\n name: string,\n instance: Base,\n mode: 'add' | 'remove' = 'add',\n) {\n const action = mode === 'add' ? '$on' : '$off';\n const methods = getEventMethodsByName(that, name);\n const config = instance.__config;\n for (const method of methods) {\n const event = getEventNameByMethod(method, name);\n if (getEventTarget(instance, event, config)) {\n instance[action](event, that.__childrenHandler);\n }\n }\n}\n\nconst isDocumentRegex = /^onDocument[A-Z][a-z]+/;\nconst isWindowRegex = /^onWindow[A-Z][a-z]+/;\nconst methodIsDocument = (method) => isDocumentRegex.test(method);\nconst methodIsWindow = (method) => isWindowRegex.test(method);\nconst methodIsGlobal = (method) => methodIsWindow(method) || methodIsDocument(method);\nconst getGlobalEventTarget = (method) => (methodIsDocument(method) ? document : window);\n\n/**\n * Manage event methods on the root element.\n *\n * @param {EventsManager} that\n * @param {'add'|'remove'} [mode]\n * The action to perform: add or remove the event listeners, defaults to 'add'.\n * @return {void}\n * @private\n */\n// eslint-disable-next-line no-use-before-define\nfunction manageRootElement(that: EventsManager, mode: 'add' | 'remove' = 'add') {\n const modeMethod = `${mode}EventListener`;\n const methods = getEventMethodsByName(that);\n\n const { __base: base, __config: config } = that;\n\n for (const method of methods) {\n let event = getEventNameByMethod(method);\n\n if (methodIsGlobal(method)) {\n event = getEventNameByMethod(method, methodIsDocument(method) ? 'document' : 'window');\n const target = getGlobalEventTarget(method);\n target[modeMethod](\n event,\n methodIsDocument(method) ? that.__documentHandler : that.__windowHandler,\n );\n } else {\n const target = getEventTarget(base, event, config);\n target?.[modeMethod](event, that.__rootElementHandler);\n }\n }\n}\n\nexport type EventManagerCallbackParams = {\n event: Event | null;\n args: Array<any>;\n index: number;\n target: Element | Base | Promise<Base> | typeof window | typeof document | null;\n};\n\n/**\n * Normalize `on...` method params.\n */\nfunction normalizeParams(\n params: Partial<EventManagerCallbackParams> = {},\n): EventManagerCallbackParams {\n return {\n event: null,\n args: [],\n index: 0,\n target: null,\n ...params,\n };\n}\n\n/**\n * Event management class.\n *\n * @todo Prevent binding of `onChildOrRefEvent` to the root element\n * @todo Use event delegation?\n */\nexport class EventsManager extends AbstractManager {\n __methodsCache: Map<string, string[]> = new Map();\n\n /**\n * Event listener object for the root element.\n */\n __rootElementHandler: EventListenerObject = {\n handleEvent: (event: Event | CustomEvent) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedEventName}`;\n const isCustomEvent = event instanceof CustomEvent;\n\n this.__base[method](\n normalizeParams({\n event,\n args: isCustomEvent ? (event.detail ?? []) : [],\n target: isCustomEvent ? this.__base : this.__element,\n }),\n );\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __documentHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @return {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onDocument${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: document }));\n },\n };\n\n /**\n * Event listener object for the root element.\n *\n * @type {EventListenerObject}\n */\n __windowHandler = {\n /**\n * @param {Event|CustomEvent} event\n * @return {void}\n */\n handleEvent: (event) => {\n const normalizedEventName = pascalCase(event.type);\n const method = `onWindow${normalizedEventName}`;\n\n this.__base[method](normalizeParams({ event, target: window }));\n },\n };\n\n /**\n * Event listener object for the refs.\n */\n __refsHandler: EventListenerObject = {\n handleEvent: (event) => {\n const ref = event.currentTarget as HTMLElement;\n const attributes = features.get('attributes');\n const refName = normalizeRefName(ref.getAttribute(attributes.ref));\n\n const normalizedRefName = pascalCase(refName);\n const normalizedEventName = pascalCase(event.type);\n const method = `on${normalizedRefName}${normalizedEventName}`;\n\n let index = 0;\n if (isArray(this.__base.$refs[refName])) {\n index = (this.__base.$refs[refName] as HTMLElement[]).indexOf(ref);\n }\n\n this.__base[method](normalizeParams({ event, index, target: ref }));\n },\n };\n\n /**\n * Event listener object for the children.\n */\n __childrenHandler: EventListenerObject = {\n handleEvent: (event: CustomEvent) => {\n const children = this.__base.$children;\n\n for (const childName of Object.keys(children)) {\n let index = -1;\n\n for (const child of children[childName] as Base<BaseProps>[]) {\n index++;\n\n if (\n child.$el === event.currentTarget &&\n (eventIsNative(event.type, child.$el) ||\n eventIsDefinedInConfig(event.type, child.__config))\n ) {\n const normalizedEventName = pascalCase(event.type);\n const normalizedChildName = pascalCase(childName);\n const method = `on${normalizedChildName}${normalizedEventName}`;\n const args = isArray(event.detail) ? event.detail : [];\n this.__base[method](normalizeParams({ event, index, args, target: child }));\n }\n }\n }\n },\n };\n\n /**\n * Class constructor.\n */\n constructor(base: Base) {\n super(base);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @return {void}\n */\n bindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements);\n }\n\n /**\n * Bind event methods to the given ref elements.\n *\n * @param {string} name\n * The name of the ref.\n * @param {HTMLElement[]} elements\n * The elements of the ref.\n * @return {void}\n */\n unbindRef(name: string, elements: HTMLElement[]) {\n manageRef(this, name, elements, 'remove');\n }\n\n /**\n * Bind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @return {void}\n */\n bindChild(name: string, instance: Base) {\n manageChild(this, name, instance);\n }\n\n /**\n * Unbind event methods to the given child instance.\n *\n * @param {string} name\n * The name of the ref.\n * @param {Base} instance\n * A base instance.\n * @return {void}\n */\n unbindChild(name: string, instance: Base) {\n manageChild(this, name, instance, 'remove');\n }\n\n /**\n * Bind event methods on the root element.\n *\n * @return {void}\n */\n bindRootElement() {\n manageRootElement(this);\n }\n\n /**\n * Unbind event method from the root element.\n *\n * @return {void}\n */\n unbindRootElement() {\n manageRootElement(this, 'remove');\n }\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }