@twobirds/microcomponents 0.1.16 → 0.1.18

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.
package/dist/MC.ts CHANGED
@@ -5,308 +5,298 @@ import { LooseObject } from './helpers.js';
5
5
  const isBrowser = new Function('try {return this===window;}catch(e){ return false;}');
6
6
 
7
7
  export interface HTMLMcElement extends HTMLElement {
8
- _mc: LooseObject;
8
+ _mc: LooseObject;
9
9
  }
10
10
 
11
11
  function isDOM(element: { [key: string]: any }) {
12
- return element && element instanceof HTMLElement;
12
+ return element && element instanceof HTMLElement;
13
13
  }
14
14
 
15
15
  // add a microcomponent to a target DOM node
16
16
  function add(target: HTMLElement, key: string, element: any = {}): HTMLMcElement {
17
- let node = target as HTMLMcElement;
17
+ let node = target as HTMLMcElement;
18
18
 
19
- // create the _mc property if necessary
20
- if (!node._mc) {
21
- node._mc = new (DC as any)(target);
22
- }
19
+ // create the _mc property if necessary
20
+ if (!node._mc) {
21
+ node._mc = new (DC as any)(target);
22
+ }
23
23
 
24
- const _mc = node._mc;
24
+ const _mc = node._mc;
25
25
 
26
- // add the element with the given property key to the _mc property
27
- if (key.length && !_mc[key]) {
28
- _mc[key] = element;
29
- // add attribute if HTMLElement
30
- if (target instanceof HTMLElement && !target.getAttribute('data-mc')) {
31
- target.setAttribute('data-mc', '');
32
- }
33
- }
26
+ // add the element with the given property key to the _mc property
27
+ if (key.length && !_mc[key]) {
28
+ _mc[key] = element;
29
+ // add attribute if HTMLElement
30
+ if (target instanceof HTMLElement && !target.getAttribute('data-mc')) {
31
+ target.setAttribute('data-mc', '');
32
+ }
33
+ }
34
34
 
35
- return node;
35
+ return node;
36
36
  }
37
37
 
38
38
  // remove a micro component from the DOM
39
39
  function remove(target: HTMLElement, key: string) {
40
- if (!key) return; // silent fail
41
-
42
- const _mc = (target as unknown as HTMLMcElement)?._mc || {};
43
-
44
- // delete the property from the HTMLElement _mc collection
45
- if (_mc && _mc[key]) {
46
- delete _mc[key];
47
- }
48
-
49
- // remove the _mc attribute if the DOM collection is empty
50
- if (
51
- !Object.keys(_mc).length &&
52
- target instanceof HTMLElement &&
53
- target.hasAttribute('data-mc')
54
- ) {
55
- target.removeAttribute('data-mc');
56
- }
57
- return;
40
+ if (!key) return; // silent fail
41
+
42
+ const _mc = (target as unknown as HTMLMcElement)?._mc || {};
43
+
44
+ // delete the property from the HTMLElement _mc collection
45
+ if (_mc && _mc[key]) {
46
+ delete _mc[key];
47
+ }
48
+
49
+ // remove the _mc attribute if the DOM collection is empty
50
+ if (!Object.keys(_mc).length && target instanceof HTMLElement && target.hasAttribute('data-mc')) {
51
+ target.removeAttribute('data-mc');
52
+ }
53
+ return;
58
54
  }
59
55
 
60
56
  // run the "init" lifecycle event on the complete _mc structure
61
57
  function init(element: DC) {
62
- setTimeout(() => {
63
- if (element.constructor === DC) return;
64
- element.trigger('Init');
65
- }, 0);
58
+ setTimeout(() => {
59
+ if (element.constructor === DC) return;
60
+ element.trigger('Init');
61
+ }, 0);
66
62
  }
67
63
 
68
64
  // 'eventName' => '_mcEventName'
69
65
  function getMcEventName(eventName: string): string {
70
- return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
66
+ return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
71
67
  }
72
68
 
73
69
  /*
74
70
  CustomEvent Section...
75
71
  */
76
72
  function off(domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject) {
77
- domNode.removeEventListener(getMcEventName(eventName), handler);
73
+ domNode.removeEventListener(getMcEventName(eventName), handler);
78
74
  }
79
75
 
80
76
  function on(
81
- domNode: Node,
82
- eventName: string,
83
- handler: EventListenerOrEventListenerObject,
84
- once: boolean = false
77
+ domNode: Node,
78
+ eventName: string,
79
+ handler: EventListenerOrEventListenerObject,
80
+ once: boolean = false
85
81
  ): EventListenerOrEventListenerObject {
86
- domNode.addEventListener(getMcEventName(eventName), handler, { capture: false, once });
87
- return handler;
82
+ domNode.addEventListener(getMcEventName(eventName), handler, { capture: false, once });
83
+ return handler;
88
84
  }
89
85
 
90
86
  function one(
91
- domNode: Node,
92
- eventName: string,
93
- handler: EventListenerOrEventListenerObject
87
+ domNode: Node,
88
+ eventName: string,
89
+ handler: EventListenerOrEventListenerObject
94
90
  ): EventListenerOrEventListenerObject {
95
- on(domNode, eventName, handler, true);
96
- return handler;
91
+ on(domNode, eventName, handler, true);
92
+ return handler;
97
93
  }
98
94
 
99
95
  class BubbleController {
100
- stopped = false;
101
- constructor() {}
102
- stop() {
103
- this.stopped = true;
104
- }
96
+ stopped = false;
97
+ constructor() {}
98
+ stop() {
99
+ this.stopped = true;
100
+ }
105
101
  }
106
102
 
107
103
  // create and dispatch custom event
108
104
  function trigger(
109
- domNode: HTMLElement,
110
- event: string,
111
- data: any = {},
112
- bubble: string = 'l', // direction of bubbling
113
- controller?: BubbleController
105
+ domNode: HTMLElement,
106
+ event: string,
107
+ data: any = {},
108
+ bubble: string = 'l', // direction of bubbling
109
+ controller?: BubbleController
114
110
  ) {
115
- const eventName = /^_mc/.test(event) ? event : getMcEventName(event),
116
- bubbleController = controller ? controller : new BubbleController(),
117
- ev = new CustomEvent(eventName, {
118
- detail: { data, control: bubbleController },
119
- bubbles: false,
120
- });
121
-
122
- if (bubbleController.stopped) return;
123
-
124
- if (/l/.test(bubble)) {
125
- domNode.dispatchEvent(ev);
126
- ev.stopImmediatePropagation();
127
-
128
- if (bubbleController.stopped) return;
129
- }
130
-
131
- // bubble if up or down is indicated
132
- if (/[ud]/.test(bubble)) {
133
- //console.log( 'bubble', bubble, domNode );
134
-
135
- // add missing 'l', or else no handlers are executed
136
- if (bubble.indexOf('l') === -1) {
137
- bubble += 'l';
138
- }
139
-
140
- setTimeout(() => {
141
- // bubble up towards document.body
142
- if (bubble.indexOf('u') > -1) {
143
- let parentMc: HTMLMcElement | null | undefined =
144
- domNode.parentElement?.closest('[data-mc]');
145
- if (parentMc) {
146
- parentMc?._mc.trigger(eventName, data, bubble, bubbleController);
147
- }
148
- }
149
-
150
- // bubble down towards DOM children
151
- if (bubble.indexOf('d') > -1) {
152
- let childNodes: DC[] | null = (domNode as HTMLMcElement)._mc.children();
153
- if (childNodes) {
154
- childNodes.forEach((_mc: DC) => _mc.trigger(eventName, data, bubble)); // event multiplex - dont carry bubble controller
155
- }
156
- }
157
- }, 0);
158
- }
111
+ const eventName = /^_mc/.test(event) ? event : getMcEventName(event),
112
+ bubbleController = controller ? controller : new BubbleController(),
113
+ ev = new CustomEvent(eventName, {
114
+ detail: { data, control: bubbleController },
115
+ bubbles: false,
116
+ });
117
+
118
+ if (bubbleController.stopped) return;
119
+
120
+ if (/l/.test(bubble)) {
121
+ domNode.dispatchEvent(ev);
122
+ ev.stopImmediatePropagation();
123
+
124
+ if (bubbleController.stopped) return;
125
+ }
126
+
127
+ // bubble if up or down is indicated
128
+ if (/[ud]/.test(bubble)) {
129
+ //console.log( 'bubble', bubble, domNode );
130
+
131
+ // add missing 'l', or else no handlers are executed
132
+ if (bubble.indexOf('l') === -1) {
133
+ bubble += 'l';
134
+ }
135
+
136
+ setTimeout(() => {
137
+ // bubble up towards document.body
138
+ if (bubble.indexOf('u') > -1) {
139
+ let parentMc: HTMLMcElement | null | undefined =
140
+ domNode.parentElement?.closest('[data-mc]');
141
+ if (parentMc) {
142
+ parentMc?._mc.trigger(eventName, data, bubble, bubbleController);
143
+ }
144
+ }
145
+
146
+ // bubble down towards DOM children
147
+ if (bubble.indexOf('d') > -1) {
148
+ let childNodes: DC[] | null = (domNode as HTMLMcElement)._mc.children();
149
+ if (childNodes) {
150
+ childNodes.forEach((_mc: DC) => _mc.trigger(eventName, data, bubble)); // event multiplex - dont carry bubble controller
151
+ }
152
+ }
153
+ }, 0);
154
+ }
159
155
  }
160
156
 
161
157
  function autoAttachListeners(element: MC | DC) {
162
- if (!isBrowser() || element.constructor === DC) return;
163
-
164
- const target = element.target;
165
-
166
- if (target instanceof HTMLElement) {
167
- let that: LooseObject = element;
168
- Object.getOwnPropertyNames(that.constructor.prototype)
169
- .filter(
170
- (key) =>
171
- /^(on[A-Z]|one[A-Z])/.test(key) &&
172
- typeof that.constructor.prototype[key] === 'function'
173
- )
174
- .forEach((key) => {
175
- let once = /^one/.test(key),
176
- withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
177
- nativeEventName = withoutOnOne.toLowerCase(); // lowercase for native event names
178
-
179
- if ('on' + nativeEventName in target) {
180
- // it is a native HTML event
181
- let listener = (ev: Event) => {
182
- that[key](ev);
183
- };
184
- // console.log( 'AAL: attach native event listener', nativeEventName, 'to', target );
185
- target.addEventListener(nativeEventName, listener);
186
- } else {
187
- // it is a customEvent
188
- // console.log( 'AAL: attach custom event listener', '_mc' + withoutOnOne , 'to key', key, 'in', element );
189
- let listener = (ev: CustomEvent) => {
190
- that[key](ev);
191
- };
192
- on(target, withoutOnOne, listener as EventListenerOrEventListenerObject, once);
193
- }
194
- });
195
- }
158
+ if (!isBrowser() || element.constructor === DC) return;
159
+
160
+ const target = element.target;
161
+
162
+ if (target instanceof HTMLElement) {
163
+ let that: LooseObject = element;
164
+ Object.getOwnPropertyNames(that.constructor.prototype)
165
+ .filter(
166
+ (key) =>
167
+ /^(on[A-Z]|one[A-Z])/.test(key) && typeof that.constructor.prototype[key] === 'function'
168
+ )
169
+ .forEach((key) => {
170
+ let once = /^one/.test(key),
171
+ withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
172
+ nativeEventName = withoutOnOne.toLowerCase(); // lowercase for native event names
173
+
174
+ if ('on' + nativeEventName in target) {
175
+ // it is a native HTML event
176
+ let listener = (ev: Event) => {
177
+ that[key](ev);
178
+ };
179
+ // console.log( 'AAL: attach native event listener', nativeEventName, 'to', target );
180
+ target.addEventListener(nativeEventName, listener);
181
+ } else {
182
+ // it is a customEvent
183
+ // console.log( 'AAL: attach custom event listener', '_mc' + withoutOnOne , 'to key', key, 'in', element );
184
+ let listener = (ev: CustomEvent) => {
185
+ that[key](ev);
186
+ };
187
+ on(target, withoutOnOne, listener as EventListenerOrEventListenerObject, once);
188
+ }
189
+ });
190
+ }
196
191
  }
197
192
 
198
193
  function getMcChildNodes(domNode: HTMLElement): DC[] | null {
199
- const id = Math.random().toString().replace('.', '');
200
- const selector = '[data-mc]:not([temp_id="' + id + '"] [data-mc] [data-mc])';
201
- domNode.setAttribute('temp_id', id);
202
- const mcArray: unknown[] = ([...domNode.querySelectorAll(selector)] as HTMLMcElement[])
203
- .filter((e) => !!e._mc)
204
- .map((e) => e._mc);
205
- domNode.removeAttribute('temp_id');
206
- return mcArray.length ? (mcArray as DC[]) : null;
194
+ const id = Math.random().toString().replace('.', '');
195
+ const selector = '[data-mc]:not([temp_id="' + id + '"] [data-mc] [data-mc])';
196
+ domNode.setAttribute('temp_id', id);
197
+ const mcArray: unknown[] = ([...domNode.querySelectorAll(selector)] as HTMLMcElement[])
198
+ .filter((e) => !!e._mc)
199
+ .map((e) => e._mc);
200
+ domNode.removeAttribute('temp_id');
201
+ return mcArray.length ? (mcArray as DC[]) : null;
207
202
  }
208
203
 
209
204
  class McBase {
210
- private _target: WeakRef<any>; // avoid circular reference
205
+ private _target: WeakRef<any>; // avoid circular reference
211
206
 
212
- constructor(target?: { [key: string]: any }) {
213
- let element = this as unknown as MC | DC;
207
+ constructor(target?: { [key: string]: any }) {
208
+ let element = this as unknown as MC | DC;
214
209
 
215
- this._target = new WeakRef(target || {});
210
+ this._target = new WeakRef(target || {});
216
211
 
217
- autoAttachListeners(element);
212
+ autoAttachListeners(element);
218
213
 
219
- init(element as DC); // async lifecycle event
220
- }
214
+ init(element as DC); // async lifecycle event
215
+ }
221
216
 
222
- get target(): any {
223
- return this._target.deref();
224
- }
217
+ get target(): any {
218
+ return this._target.deref();
219
+ }
225
220
  }
226
221
 
227
222
  class MC extends McBase {
228
- constructor(target?: any) {
229
- super(target);
230
- }
223
+ constructor(target?: any) {
224
+ super(target);
225
+ }
231
226
  }
232
227
 
233
228
  class DC extends McBase {
234
- constructor(target: HTMLElement) {
235
- super(target);
236
- }
237
-
238
- static add(target: HTMLElement, key: string, element: any = {}): HTMLMcElement {
239
- return add(target, key, element);
240
- }
241
-
242
- static remove(target: HTMLElement, key: string) {
243
- remove(target, key);
244
- }
245
-
246
- /* event handling */
247
- off(eventName: string, handler: EventListenerOrEventListenerObject) {
248
- off(this.target, eventName, handler);
249
- }
250
-
251
- on(
252
- eventName: string,
253
- handler: EventListenerOrEventListenerObject
254
- ): EventListenerOrEventListenerObject {
255
- return on(this.target, eventName, handler);
256
- }
257
-
258
- one(
259
- eventName: string,
260
- handler: EventListenerOrEventListenerObject
261
- ): EventListenerOrEventListenerObject {
262
- return one(this.target, eventName, handler);
263
- }
264
-
265
- trigger(
266
- eventName: string,
267
- data: any = {},
268
- bubble: string = 'l',
269
- controller?: BubbleController
270
- ) {
271
- trigger(this.target, eventName, data, bubble, controller);
272
- }
273
-
274
- /* DOM traversal */
275
- ancestors(): DC[] | null {
276
- let currentNode: HTMLElement | null = (this as DC)?.target as HTMLMcElement,
277
- result: DC[] = [];
278
-
279
- if (!isDOM(currentNode)) return [];
280
-
281
- while ((currentNode = currentNode.closest('[data-mc]'))) {
282
- if ((currentNode as HTMLMcElement)?._mc) {
283
- result.push((currentNode as HTMLMcElement)?._mc as DC);
284
- }
285
- }
286
-
287
- return result.length ? result : null;
288
- }
289
-
290
- closest(): DC | null {
291
- let target: HTMLElement = (this as DC).target;
292
- if (!isDOM(target)) return null;
293
- return ((target.closest('[data-mc]') as HTMLMcElement)?._mc as DC) || null;
294
- }
295
-
296
- children(): DC[] | null {
297
- let target: any = (this as any)?.target;
298
- if (!isDOM(target)) return null;
299
- return getMcChildNodes(target);
300
- }
301
-
302
- descendants(): DC[] | null {
303
- const target: any = (this as DC)?.target;
304
- if (!isDOM(target)) return [];
305
- const mcArray: unknown[] = ([...target.querySelectorAll('[data-mc]')] as HTMLMcElement[])
306
- .filter((e) => !!e._mc)
307
- .map((e) => e._mc);
308
- return mcArray.length ? (mcArray as DC[]) : null;
309
- }
229
+ constructor(target: HTMLElement) {
230
+ super(target);
231
+ }
232
+
233
+ static add(target: HTMLElement, key: string, element: any = {}): HTMLMcElement {
234
+ return add(target, key, element);
235
+ }
236
+
237
+ static remove(target: HTMLElement, key: string) {
238
+ remove(target, key);
239
+ }
240
+
241
+ /* event handling */
242
+ off(eventName: string, handler: EventListenerOrEventListenerObject) {
243
+ off(this.target, eventName, handler);
244
+ }
245
+
246
+ on(
247
+ eventName: string,
248
+ handler: EventListenerOrEventListenerObject
249
+ ): EventListenerOrEventListenerObject {
250
+ return on(this.target, eventName, handler);
251
+ }
252
+
253
+ one(
254
+ eventName: string,
255
+ handler: EventListenerOrEventListenerObject
256
+ ): EventListenerOrEventListenerObject {
257
+ return one(this.target, eventName, handler);
258
+ }
259
+
260
+ trigger(eventName: string, data: any = {}, bubble: string = 'l', controller?: BubbleController) {
261
+ trigger(this.target, eventName, data, bubble, controller);
262
+ }
263
+
264
+ /* DOM traversal */
265
+ ancestors(): DC[] | null {
266
+ let currentNode: HTMLElement | null = (this as DC)?.target as HTMLMcElement,
267
+ result: DC[] = [];
268
+
269
+ if (!isDOM(currentNode)) return [];
270
+
271
+ while ((currentNode = currentNode.closest('[data-mc]'))) {
272
+ if ((currentNode as HTMLMcElement)?._mc) {
273
+ result.push((currentNode as HTMLMcElement)?._mc as DC);
274
+ }
275
+ }
276
+
277
+ return result.length ? result : null;
278
+ }
279
+
280
+ closest(): DC | null {
281
+ let target: HTMLElement = (this as DC).target;
282
+ if (!isDOM(target)) return null;
283
+ return ((target.closest('[data-mc]') as HTMLMcElement)?._mc as DC) || null;
284
+ }
285
+
286
+ children(): DC[] | null {
287
+ let target: any = (this as any)?.target;
288
+ if (!isDOM(target)) return null;
289
+ return getMcChildNodes(target);
290
+ }
291
+
292
+ descendants(): DC[] | null {
293
+ const target: any = (this as DC)?.target;
294
+ if (!isDOM(target)) return [];
295
+ const mcArray: unknown[] = ([...target.querySelectorAll('[data-mc]')] as HTMLMcElement[])
296
+ .filter((e) => !!e._mc)
297
+ .map((e) => e._mc);
298
+ return mcArray.length ? (mcArray as DC[]) : null;
299
+ }
310
300
  }
311
301
 
312
302
  /*
@@ -316,141 +306,141 @@ Autoload Section...
316
306
  const loadingDCs = new Set<string>();
317
307
 
318
308
  function attachDC(element: string): Function {
319
- //@ts-ignore
320
- return () => {
321
- const elements: HTMLElement[] = Array.from(
322
- document.querySelectorAll(`[data-mc*="${element}"]`)
323
- ).filter((element) => element instanceof HTMLElement);
324
-
325
- if (elements.length === 0) return;
326
-
327
- //console.log( 'loadedPromise elements', elements );
328
-
329
- const Klass = customElements.get(element);
330
-
331
- elements.forEach((node: HTMLElement) => {
332
- try {
333
- //console.log( 'add', klass!.name, 'to', node );
334
- DC.add(node, Klass!.name, new Klass!(node));
335
- } catch (error) {
336
- if ((Klass as LooseObject)['create']) {
337
- let element: HTMLMcElement = (Klass as LooseObject).create(node);
338
- element.setAttribute('data-mc', node.getAttribute('data-mc')!);
339
- node.replaceWith(element);
340
- node = element;
341
- } else {
342
- throw `Class ${(Klass as LooseObject).name} doesn't have a callable constructor AND class doesn't have a static .create() method.`;
343
- }
344
- }
345
-
346
- //@ts-ignore
347
- const new_mc = node
348
- .getAttribute('data-mc')
349
- .split(' ')
350
- .filter((name) => name !== element && name !== '')
351
- .join(' ')
352
- .trim();
353
-
354
- //@ts-ignore
355
- node.setAttribute(
356
- 'data-mc',
357
- //@ts-ignore
358
- new_mc
359
- );
360
- });
361
- };
309
+ //@ts-ignore
310
+ return () => {
311
+ const elements: HTMLElement[] = Array.from(
312
+ document.querySelectorAll(`[data-mc*="${element}"]`)
313
+ ).filter((element) => element instanceof HTMLElement);
314
+
315
+ if (elements.length === 0) return;
316
+
317
+ //console.log( 'loadedPromise elements', elements );
318
+
319
+ const Klass = customElements.get(element);
320
+
321
+ elements.forEach((node: HTMLElement) => {
322
+ try {
323
+ //console.log( 'add', klass!.name, 'to', node );
324
+ DC.add(node, Klass!.name, new Klass!(node));
325
+ } catch (error) {
326
+ if ((Klass as LooseObject)['create']) {
327
+ let element: HTMLMcElement = (Klass as LooseObject).create(node);
328
+ element.setAttribute('data-mc', node.getAttribute('data-mc')!);
329
+ node.replaceWith(element);
330
+ node = element;
331
+ } else {
332
+ throw `Class ${(Klass as LooseObject).name} doesn't have a callable constructor AND class doesn't have a static .create() method.`;
333
+ }
334
+ }
335
+
336
+ //@ts-ignore
337
+ const new_mc = node
338
+ .getAttribute('data-mc')
339
+ .split(' ')
340
+ .filter((name) => name !== element && name !== '')
341
+ .join(' ')
342
+ .trim();
343
+
344
+ //@ts-ignore
345
+ node.setAttribute(
346
+ 'data-mc',
347
+ //@ts-ignore
348
+ new_mc
349
+ );
350
+ });
351
+ };
362
352
  }
363
353
 
364
354
  function makeLoadScript(element: string) {
365
- if (loadingDCs.has(element)) return; // already loading
355
+ if (loadingDCs.has(element)) return; // already loading
366
356
 
367
- loadingDCs.add(element);
357
+ loadingDCs.add(element);
368
358
 
369
- //console.log( 'makeLoadScript:', element);
370
- const fileName: string = './' + element.split('-').join('/') + '.js';
359
+ //console.log( 'makeLoadScript:', element);
360
+ const fileName: string = './' + element.split('-').join('/') + '.js';
371
361
 
372
- const se: HTMLScriptElement = document.createElement('script');
362
+ const se: HTMLScriptElement = document.createElement('script');
373
363
 
374
- se.setAttribute('src', fileName);
375
- se.setAttribute('blocking', 'render');
376
- se.async = true;
377
- se.setAttribute('type', 'module');
378
- se.setAttribute('data-name', element);
379
- se.setAttribute('loading', '');
364
+ se.setAttribute('src', fileName);
365
+ se.setAttribute('blocking', 'render');
366
+ se.async = true;
367
+ se.setAttribute('type', 'module');
368
+ se.setAttribute('data-name', element);
369
+ se.setAttribute('loading', '');
380
370
 
381
- const loadedPromise = customElements.whenDefined(element);
371
+ const loadedPromise = customElements.whenDefined(element);
382
372
 
383
- //@ts-ignore
384
- loadedPromise.then(attachDC(element));
373
+ //@ts-ignore
374
+ loadedPromise.then(attachDC(element));
385
375
 
386
- se.addEventListener('load', (ev: Event) => {
387
- loadingDCs.delete(element);
376
+ se.addEventListener('load', (ev: Event) => {
377
+ loadingDCs.delete(element);
388
378
 
389
- document.head.querySelector(`script[data-name="${element}"]`)?.remove();
390
- });
379
+ document.head.querySelector(`script[data-name="${element}"]`)?.remove();
380
+ });
391
381
 
392
- se.addEventListener('error', (ev: Event) => {
393
- console.error('could not load DC code from', fileName);
394
- });
382
+ se.addEventListener('error', (ev: Event) => {
383
+ console.error('could not load DC code from', fileName);
384
+ });
395
385
 
396
- document.head.append(se);
386
+ document.head.append(se);
397
387
  }
398
388
 
399
389
  function loadUndefinedMCs() {
400
- // load unresolved custom elements
401
- [...document.querySelectorAll(':not(:defined)')]
402
- .filter(
403
- (element) =>
404
- !!element &&
405
- !customElements.get(element.tagName.toLowerCase()) && // not in CustomElementsRegistry
406
- !loadingDCs.has(element.tagName.toLowerCase()) // not in loading list
407
- )
408
- .forEach((el) => {
409
- //console.log( 'detected CE', el.tagName.toLowerCase() );
410
- makeLoadScript(el.tagName.toLowerCase()); // will automatically be instanciated
411
- });
412
-
413
- // if defined in _mc attribute: instanciate DCs, load if necessary
414
- [...document.querySelectorAll('[data-mc]:not([data-mc=""]')]
415
- .filter((element) => !!element)
416
- .forEach((el) => {
417
- const _mc = el
418
- .getAttribute('data-mc')
419
- ?.split(' ')
420
- .filter((name) => name !== '');
421
- _mc?.forEach((element) => {
422
- //console.log( 'detected DC', dc );
423
- const isDefined = customElements.get(element);
424
- if (!loadingDCs.has(element) && !isDefined) {
425
- makeLoadScript(element);
426
- } else if (isDefined) {
427
- attachDC(element)();
428
- }
429
- });
430
- });
390
+ // load unresolved custom elements
391
+ [...document.querySelectorAll(':not(:defined)')]
392
+ .filter(
393
+ (element) =>
394
+ !!element &&
395
+ !customElements.get(element.tagName.toLowerCase()) && // not in CustomElementsRegistry
396
+ !loadingDCs.has(element.tagName.toLowerCase()) // not in loading list
397
+ )
398
+ .forEach((el) => {
399
+ //console.log( 'detected CE', el.tagName.toLowerCase() );
400
+ makeLoadScript(el.tagName.toLowerCase()); // will automatically be instanciated
401
+ });
402
+
403
+ // if defined in _mc attribute: instanciate DCs, load if necessary
404
+ [...document.querySelectorAll('[data-mc]:not([data-mc=""]')]
405
+ .filter((element) => !!element)
406
+ .forEach((el) => {
407
+ const _mc = el
408
+ .getAttribute('data-mc')
409
+ ?.split(' ')
410
+ .filter((name) => name !== '');
411
+ _mc?.forEach((element) => {
412
+ //console.log( 'detected DC', dc );
413
+ const isDefined = customElements.get(element);
414
+ if (!loadingDCs.has(element) && !isDefined) {
415
+ makeLoadScript(element);
416
+ } else if (isDefined) {
417
+ attachDC(element)();
418
+ }
419
+ });
420
+ });
431
421
  }
432
422
 
433
423
  let autoloadEnabled: boolean = false;
434
424
  let observer: MutationObserver | null = null;
435
425
 
436
426
  function autoload(enable: boolean = true): boolean {
437
- if (!enable) {
438
- observer?.disconnect();
439
- observer = null;
440
- return autoloadEnabled;
441
- }
427
+ if (!enable) {
428
+ observer?.disconnect();
429
+ observer = null;
430
+ return autoloadEnabled;
431
+ }
442
432
 
443
- autoloadEnabled = enable;
444
- observer = new MutationObserver(loadUndefinedMCs);
433
+ autoloadEnabled = enable;
434
+ observer = new MutationObserver(loadUndefinedMCs);
445
435
 
446
- setTimeout(() => {
447
- observer!.observe(document.body, { childList: true, subtree: true });
448
- loadUndefinedMCs();
449
- }, 5);
436
+ setTimeout(() => {
437
+ observer!.observe(document.body, { childList: true, subtree: true });
438
+ loadUndefinedMCs();
439
+ }, 5);
450
440
 
451
- (window as LooseObject).autoload = (window as LooseObject).autoload || autoload;
441
+ (window as LooseObject).autoload = (window as LooseObject).autoload || autoload;
452
442
 
453
- return autoloadEnabled;
443
+ return autoloadEnabled;
454
444
  }
455
445
 
456
446
  (autoload as LooseObject).state = loadingDCs;