@twobirds/microcomponents 0.1.9 → 0.1.11

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