@twobirds/microcomponents 0.0.33 → 0.0.37

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 (118) hide show
  1. package/README.md +40 -27
  2. package/assets/documentation/{MicroComponents.md → MC.md} +17 -17
  3. package/assets/documentation/comparision.md +0 -0
  4. package/assets/documentation/elements.md +276 -0
  5. package/assets/documentation/magic.md +10 -68
  6. package/dist/MC.d.ts +2 -3
  7. package/dist/MC.d.ts.map +1 -1
  8. package/dist/MC.min.js +45 -43
  9. package/dist/MC.ts +173 -175
  10. package/dist/autoloader.ts +1 -1
  11. package/dist/{customElements.d.ts → elements.d.ts} +1 -1
  12. package/dist/elements.d.ts.map +1 -0
  13. package/dist/elements.min.js +1 -0
  14. package/dist/{customElements.ts → elements.ts} +23 -14
  15. package/dist/helpers.d.ts +6 -4
  16. package/dist/helpers.d.ts.map +1 -1
  17. package/dist/helpers.ts +95 -128
  18. package/dist/microcomponents.d.ts +3 -3
  19. package/dist/microcomponents.d.ts.map +1 -1
  20. package/dist/microcomponents.min.js +1 -1
  21. package/dist/microcomponents.ts +3 -3
  22. package/dist/{customObservables.d.ts → observables.d.ts} +3 -3
  23. package/dist/observables.d.ts.map +1 -0
  24. package/dist/observables.min.js +1 -0
  25. package/dist/observables.ts +354 -0
  26. package/dist/{customSelectors.d.ts → selectors.d.ts} +1 -1
  27. package/dist/selectors.d.ts.map +1 -0
  28. package/dist/selectors.min.js +1 -0
  29. package/dist/test.ts +133 -157
  30. package/klemmstein.png +0 -0
  31. package/package.json +52 -52
  32. package/public/MC.js +46 -44
  33. package/public/MC.js.map +1 -1
  34. package/public/MC.min.js +45 -43
  35. package/public/assets/search.js +1 -1
  36. package/public/autoloader.js +1 -1
  37. package/public/autoloader.js.map +1 -1
  38. package/public/classes/{DC.html → MC.DC.html} +60 -59
  39. package/public/classes/{MC.html → MC.MC.html} +41 -35
  40. package/public/classes/{McBase.html → MC.McBase.html} +28 -20
  41. package/public/classes/{McEvent.html → MC.McEvent.html} +48 -42
  42. package/public/documentation/{MicroComponents.md → MC.md} +17 -17
  43. package/public/documentation/comparision.md +0 -0
  44. package/public/documentation/elements.md +276 -0
  45. package/public/documentation/magic.md +10 -68
  46. package/public/{customElements.js → elements.js} +9 -10
  47. package/public/elements.js.map +1 -0
  48. package/public/elements.min.js +1 -0
  49. package/public/functions/{addListener.html → MC.addListener.html} +18 -12
  50. package/public/functions/{removeListener.html → MC.removeListener.html} +18 -12
  51. package/public/functions/elements.defineCE.html +78 -0
  52. package/public/functions/elements.getCE.html +63 -0
  53. package/public/functions/formValues.formValues.html +68 -0
  54. package/public/functions/observables.observe.html +65 -0
  55. package/public/functions/selectors._d.html +69 -0
  56. package/public/functions/selectors._t.html +69 -0
  57. package/public/helpers.js +66 -89
  58. package/public/helpers.js.map +1 -1
  59. package/public/index.html +48 -33
  60. package/public/interfaces/{HTMLMcElement.html → MC.HTMLMcElement.html} +601 -595
  61. package/public/interfaces/selectors.DSelector.html +1013 -0
  62. package/public/interfaces/selectors.TSelector.html +712 -0
  63. package/public/microcomponents.js +3 -3
  64. package/public/microcomponents.js.map +1 -1
  65. package/public/microcomponents.min.js +1 -1
  66. package/public/modules/MC.html +78 -0
  67. package/public/modules/elements.html +62 -0
  68. package/public/modules/formValues.html +60 -0
  69. package/public/modules/observables.html +65 -0
  70. package/public/modules/selectors.html +76 -0
  71. package/public/modules.html +11 -23
  72. package/public/observables.js +255 -0
  73. package/public/observables.js.map +1 -0
  74. package/public/observables.min.js +1 -0
  75. package/public/{customSelectors.js → selectors.js} +1 -1
  76. package/public/selectors.js.map +1 -0
  77. package/public/selectors.min.js +1 -0
  78. package/public/src/MC.ts +376 -0
  79. package/public/src/McEvent.ts +96 -0
  80. package/public/src/autoloader.ts +98 -0
  81. package/{src/customElements.ts → public/src/elements.ts} +23 -14
  82. package/public/src/formValues.ts +275 -0
  83. package/public/src/helpers.ts +140 -0
  84. package/public/src/microcomponents.ts +8 -0
  85. package/public/src/observables.ts +354 -0
  86. package/public/src/test.ts +187 -0
  87. package/public/test.js +99 -115
  88. package/public/test.js.map +1 -1
  89. package/public/types/observables.Observable.html +91 -0
  90. package/public/types/selectors.selection.html +58 -0
  91. package/public/types/selectors.singleSelector.html +58 -0
  92. package/src/MC.ts +173 -175
  93. package/src/autoloader.ts +1 -1
  94. package/src/elements.ts +76 -0
  95. package/src/helpers.ts +95 -128
  96. package/src/microcomponents.ts +3 -3
  97. package/src/observables.ts +354 -0
  98. package/src/selectors.ts +1634 -0
  99. package/src/test.ts +133 -157
  100. package/typedoc.json +1 -1
  101. package/webpack.config.js +9 -9
  102. package/dist/customElements.d.ts.map +0 -1
  103. package/dist/customElements.min.js +0 -1
  104. package/dist/customObservables.d.ts.map +0 -1
  105. package/dist/customObservables.min.js +0 -1
  106. package/dist/customObservables.ts +0 -348
  107. package/dist/customSelectors.d.ts.map +0 -1
  108. package/dist/customSelectors.min.js +0 -1
  109. package/public/customElements.js.map +0 -1
  110. package/public/customElements.min.js +0 -1
  111. package/public/customObservables.js +0 -256
  112. package/public/customObservables.js.map +0 -1
  113. package/public/customObservables.min.js +0 -1
  114. package/public/customSelectors.js.map +0 -1
  115. package/public/customSelectors.min.js +0 -1
  116. package/src/customObservables.ts +0 -348
  117. /package/dist/{customSelectors.ts → selectors.ts} +0 -0
  118. /package/{src/customSelectors.ts → public/src/selectors.ts} +0 -0
@@ -0,0 +1,376 @@
1
+ 'use strict';
2
+
3
+ import { LooseObject } from './helpers.js';
4
+ import { McEvent } from './McEvent.js';
5
+
6
+ var isBrowser = new Function(
7
+ 'try {return this===window;}catch(e){ return false;}'
8
+ );
9
+
10
+ let nativeEventNames: Set<string> = new Set();
11
+
12
+ // HTMLElement native event names
13
+ if (isBrowser()) {
14
+ Object.keys(HTMLElement.prototype)
15
+ .filter((key) => /^on/.test(key))
16
+ .forEach((eventName) => nativeEventNames.add(eventName));
17
+ }
18
+
19
+ export interface HTMLMcElement extends HTMLElement {
20
+ _mc: LooseObject;
21
+ }
22
+
23
+ // get all microcomponents from a list of HTMLElements
24
+ function getMicroComponents(elements: any[], search: string): any[] {
25
+ let mcValues: any[] = [];
26
+
27
+ elements.forEach((e) => {
28
+ if (e) {
29
+ if (e instanceof HTMLElement) {
30
+ const _mc = (e as any)?._mc;
31
+ if (!search && _mc) {
32
+ mcValues = mcValues.concat(Object.values((e as any)._mc));
33
+ } else if (search && _mc && _mc[search]) {
34
+ mcValues.push(_mc[search]);
35
+ }
36
+ }
37
+ }
38
+ });
39
+ return mcValues;
40
+ }
41
+
42
+ // get all ancestor DOM nodes up to the document root
43
+ function traverseNodes(
44
+ node: { [key: string]: any },
45
+ search: string,
46
+ firstonly = true
47
+ ): any[] {
48
+ let mcValues: any[] = [];
49
+ while (node) {
50
+ if (node._mc) {
51
+ if (!search) {
52
+ mcValues = mcValues.concat(Object.values(node._mc));
53
+ } else if (search && node._mc[search]) {
54
+ mcValues.push(node._mc[search]);
55
+ }
56
+ if (firstonly) return mcValues;
57
+ }
58
+ node = node.parentNode;
59
+ }
60
+ return mcValues;
61
+ }
62
+
63
+ function isDOM(element: { [key: string]: any }) {
64
+ return element && element instanceof HTMLElement;
65
+ }
66
+
67
+ function addListener(
68
+ domNode: Node,
69
+ eventName: string,
70
+ handler: EventListenerOrEventListenerObject | null,
71
+ capture: boolean = false,
72
+ once: boolean = false
73
+ ) {
74
+ let options: EventListenerOptions & { once: boolean } = { once: false };
75
+ if (capture) {
76
+ options.capture = capture;
77
+ }
78
+
79
+ if (once) {
80
+ options.once = once;
81
+ }
82
+
83
+ //console.log( 'addEventListener', eventName, ( handler as Function ).name, options );
84
+ domNode.addEventListener(eventName, handler, options);
85
+ }
86
+
87
+ function removeListener(
88
+ domNode: Node,
89
+ eventName: string,
90
+ handler: EventListenerOrEventListenerObject | null
91
+ ) {
92
+ domNode.removeEventListener(eventName, handler);
93
+ }
94
+
95
+ // add a microcomponent to a target DOM node
96
+ function add(target: HTMLElement, key: string, element = {}): any {
97
+ let node = target as HTMLMcElement;
98
+
99
+ // create the _mc property if necessary
100
+ if (!node._mc) {
101
+ let debug = (DC as any)?.debug;
102
+ (DC as any).debug = false;
103
+ node._mc = new (DC as any)(target);
104
+ (DC as any).debug = debug;
105
+ delete node._mc._mc; // NOT NEEDED on the top level _mc property of a DOM HTMLElement
106
+ }
107
+
108
+ const _mc = node._mc;
109
+
110
+ // add the element with the given property key to the _mc property
111
+ if (key.length && !_mc[key]) {
112
+ _mc[key] = element;
113
+ // add attribute if HTMLElement
114
+ if (target instanceof HTMLElement) {
115
+ target.setAttribute('_mc', '');
116
+ }
117
+ }
118
+ return element;
119
+ }
120
+
121
+ // remove a micro component from the DOM
122
+ function remove(target: HTMLMcElement, key: string) {
123
+ if (!key) return; // silent fail
124
+
125
+ const _mc = target?._mc || {};
126
+
127
+ // delete the property from the HTMLElement _mc collection
128
+ if (_mc && _mc[key]) {
129
+ delete _mc[key];
130
+ }
131
+
132
+ // remove the _mc attribute if the DOM collection is empty
133
+ if (
134
+ !Object.keys(_mc).length &&
135
+ target instanceof HTMLElement &&
136
+ target.hasAttribute('_mc')
137
+ ) {
138
+ target.removeAttribute('_mc');
139
+ }
140
+ return;
141
+ }
142
+
143
+ // trigger an event
144
+ function trigger(target: unknown, ev: McEvent | string, data: any = {}) {
145
+ let _mc = (target as any)?._mc;
146
+ if (!_mc) return;
147
+ [...Object.values(_mc)].forEach((mc: any) => {
148
+ //console.log( 'mc [', mc.constructor.name, ']', mc.constructor.prototype?.oneInit );
149
+ if ((mc as any)?.trigger && typeof (mc as any)?.trigger === 'function') {
150
+ (mc as any)?.trigger(ev, data);
151
+ }
152
+ });
153
+ return;
154
+ }
155
+
156
+ // run the "init" lifecycle event on the complete _mc structure
157
+ function init(element: MC | DC) {
158
+ if (element.constructor === DC) return;
159
+
160
+ setTimeout(() => {
161
+ element.trigger('Init');
162
+ /*
163
+ let keys = Object.keys( ( element as any)?._mc );
164
+ if ( keys.length ){
165
+ //console.log( 'inner Inits on [', mc.constructor.name, ']', keys );
166
+ keys?.forEach( (key: string) => {
167
+ let mc = ( element as any)?._mc?.[key];
168
+ //console.log( key, typeof mc?.oneInit, mc );
169
+ if ( ( mc as any )['oneInit'] && typeof ( mc as any ).oneInit == 'function' ){
170
+ ( mc as any ).oneInit( new McEvent('Init') );
171
+ }
172
+ });
173
+ };
174
+ */
175
+ }, 0);
176
+ }
177
+
178
+ function autoAttachListeners(element: MC | DC) {
179
+ if (!isBrowser() || element.constructor === DC) return;
180
+
181
+ const target = element.target;
182
+
183
+ if (target instanceof HTMLElement) {
184
+ let that: LooseObject = element;
185
+ Object.getOwnPropertyNames(that.constructor.prototype)
186
+ .filter(
187
+ (key) =>
188
+ /^on[A-Z]|one[A-Z]/.test(key) &&
189
+ typeof that.constructor.prototype[key] === 'function'
190
+ )
191
+ .forEach((key) => {
192
+ let once = /^one/.test(key),
193
+ withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
194
+ nativeEventName = withoutOnOne.toLowerCase(),
195
+ listener = (ev: McEvent | Event | CustomEvent) => {
196
+ that.trigger(withoutOnOne, ev);
197
+ };
198
+ if (once) {
199
+ // console.log( '...is only called once', that.constructor.prototype[key] );
200
+ Object.defineProperty(element, 'on' + withoutOnOne, {
201
+ configurable: true,
202
+ enumerable: false,
203
+ writable: true,
204
+ value: (ev: any) => {
205
+ // console.log( 'onceHandler execute:', that.constructor.prototype[key] );
206
+ that.constructor.prototype[key].bind(that)(ev);
207
+ },
208
+ });
209
+ }
210
+
211
+ if (nativeEventNames.has('on' + nativeEventName)) {
212
+ // native event defined in HTMLElement
213
+ // console.log('added as native listener', target, nativeEventName );
214
+ addListener(target, nativeEventName, listener, false, once);
215
+ }
216
+ });
217
+ }
218
+ }
219
+
220
+ class McBase {
221
+ #target: WeakRef<any>; // avoid circular reference
222
+
223
+ constructor(target?: { [key: string]: any }, debug: boolean = false) {
224
+ let that: unknown = this,
225
+ element = that as MC | DC;
226
+
227
+ this.#target = new WeakRef(target || {});
228
+
229
+ init(element); // async lifecycle event
230
+
231
+ autoAttachListeners(element);
232
+ }
233
+
234
+ get target(): any {
235
+ return this.#target.deref();
236
+ }
237
+ }
238
+
239
+ class MC extends McBase {
240
+ _mc: { [key: string]: any } = {};
241
+
242
+ constructor(target?: any) {
243
+ super(target);
244
+ }
245
+
246
+ static trigger = trigger;
247
+
248
+ trigger(ev: McEvent | string, data: any = {}, bubble?: string) {
249
+ let that = this;
250
+
251
+ //console.log( that, '.trigger(', ev, data, bubble, ')' );
252
+ bubble = bubble || 'l';
253
+
254
+ // run all triggers
255
+ if (that.constructor === MC || that.constructor === DC) {
256
+ [...Object.getOwnPropertyNames(that)].forEach((mc) => {
257
+ if (
258
+ (that as any)[mc]?.trigger &&
259
+ typeof (that as any)[mc]?.trigger === 'function'
260
+ ) {
261
+ (that as any)[mc]?.trigger(ev, data, bubble);
262
+ }
263
+ });
264
+ return; // must return here!
265
+ }
266
+
267
+ // only this instance
268
+ if ((that as any) instanceof MC || (that as any) instanceof DC) {
269
+ const that = this,
270
+ mcEvent: McEvent =
271
+ typeof ev !== 'string'
272
+ ? (ev as McEvent)
273
+ : new McEvent(ev, data, bubble),
274
+ handlerName =
275
+ 'on' + mcEvent.type[0].toUpperCase() + mcEvent.type.slice(1);
276
+ // console.log('trigger', handlerName, mcEvent, data, bubble );
277
+
278
+ if (mcEvent.bubble.indexOf('l') > -1) {
279
+ if (
280
+ !mcEvent.immediateStopped &&
281
+ typeof (that as any)[handlerName] === 'function'
282
+ ) {
283
+ // console.log( 'execute handler:', handlerName );
284
+ (that as any)[handlerName](mcEvent);
285
+ if ((that as any).hasOwnProperty(handlerName)) {
286
+ // it is a once handler
287
+ delete (that as any)[handlerName]; // remove after first execution
288
+ }
289
+ }
290
+ }
291
+
292
+ // if event stopped or local only, handling is cancelled
293
+ if (mcEvent.stopped || mcEvent.bubble === 'l') {
294
+ return that;
295
+ }
296
+
297
+ // at this point, either 'u' or 'd' bubbling should be indicated
298
+ // mcEvent bubbling is asynchronous, and the order of target MC execution in case of multiple matches is not guaranteed!
299
+ if (
300
+ isBrowser() &&
301
+ /[ud]/.test(mcEvent.bubble) &&
302
+ (that as any) instanceof MC
303
+ ) {
304
+ setTimeout(() => {
305
+ // bubbling must include 'l' for local, or else no handlers are executed'
306
+ if (mcEvent.bubble.indexOf('l') === -1) {
307
+ mcEvent.bubble += 'l';
308
+ }
309
+
310
+ // bubble up towards root
311
+ if (mcEvent.bubble.indexOf('u') > -1) {
312
+ (that as any).parent().forEach((mc: any) => {
313
+ mc instanceof MC ? (mc as any).trigger(mcEvent) : null;
314
+ });
315
+ }
316
+
317
+ // bubble down
318
+ if (mcEvent.bubble.indexOf('d') > -1) {
319
+ (that as any).children().forEach((mc: any) => {
320
+ mc instanceof MC ? (mc as any).trigger(mcEvent) : null;
321
+ });
322
+ }
323
+ }, 0);
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ class DC extends McBase {
330
+ _mc: { [key: string]: any } = {};
331
+
332
+ constructor(target: HTMLElement, debug: boolean = false) {
333
+ super(target);
334
+ }
335
+
336
+ static add: Function = add;
337
+ static remove: Function = remove;
338
+ static trigger: Function = trigger;
339
+
340
+ trigger(ev: McEvent | string, data: any = {}, bubble?: string) {
341
+ MC.prototype.trigger.call(this, ev, data, bubble);
342
+ }
343
+
344
+ parent(search: string = ''): any[] {
345
+ let target: HTMLElement = (this as any).target;
346
+ if (!isDOM(target)) return [];
347
+ return traverseNodes((target as any).parentNode, search, true);
348
+ }
349
+
350
+ ancestors(search: string = ''): any[] {
351
+ let target: any = (this as any)?.target;
352
+ if (!isDOM(target)) return [];
353
+ return traverseNodes((this as any).target.parentNode, search, false);
354
+ }
355
+
356
+ children(search: string = ''): any[] {
357
+ let target: any = (this as any)?.target;
358
+ if (!isDOM(target)) return [];
359
+ const id = Math.random().toString().replace('.', '');
360
+ const selector = '[_mc]:not([temp_id="' + id + '"] [_mc] [_mc])';
361
+ target.setAttribute('temp_id', id);
362
+ const myDomElements = target.querySelectorAll(selector);
363
+ const mcValues = getMicroComponents([...myDomElements], search);
364
+ target.removeAttribute('temp_id');
365
+ return mcValues;
366
+ }
367
+
368
+ descendants(search: string = ''): any[] {
369
+ let target: any = (this as any)?.target;
370
+ if (!isDOM(target)) return [];
371
+ const myDomElements = target.querySelectorAll('*[_mc]');
372
+ return getMicroComponents([...myDomElements], search);
373
+ }
374
+ }
375
+
376
+ export { addListener, removeListener, McBase, MC, DC, McEvent };
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ var isBrowser=new Function("try {return this===window;}catch(e){ return false;}");
4
+
5
+ let nativeEventNames: Set<string> = new Set();
6
+
7
+ // HTMLElement native event names
8
+ if ( isBrowser() ){
9
+ Object.keys( HTMLElement.prototype ).filter( key => /^on/.test(key) ).forEach( eventName => nativeEventNames.add( eventName ) );
10
+ }
11
+
12
+ function isDOM(element: { [key:string]: any } ) {
13
+ return element && element instanceof HTMLElement;
14
+ }
15
+
16
+ interface McEvent {
17
+ data: any;
18
+ bubble: string;
19
+ }
20
+
21
+ class McEvent{
22
+
23
+ #type: string;
24
+ #stopped: boolean = false;
25
+ #immediateStopped: boolean = false;
26
+
27
+ constructor( type: string, data: any = {}, bubble: string = 'l' ){
28
+ // bubble standard = local only, options = any combination of'uld' characters: up to root, local, down
29
+ this.#type = type;
30
+ this.data = data;
31
+ this.bubble = bubble;
32
+ }
33
+
34
+ get type(): string {
35
+ return this.#type;
36
+ }
37
+
38
+ get stopped(): boolean {
39
+ return this.#stopped;
40
+ }
41
+
42
+ get immediateStopped(): boolean {
43
+ return this.#immediateStopped;
44
+ }
45
+
46
+ stopPropagation(){
47
+ this.#stopped = true;
48
+ }
49
+
50
+ stopImmediatePropagation(){
51
+ this.stopPropagation();
52
+ this.#immediateStopped = true;
53
+ }
54
+
55
+ }
56
+
57
+ // get all microcomponents from a list of HTMLElements
58
+ function getMicroComponents( elements: any[], search: string): any[] {
59
+ let mcValues: any[] = [];
60
+
61
+ elements.forEach( e => {
62
+ if (e) {
63
+ if (e instanceof HTMLElement) {
64
+ const _mc = ( e as any )?._mc;
65
+ if ( !search && _mc ) {
66
+ mcValues = mcValues.concat(Object.values(( e as any )._mc));
67
+ }
68
+ else if ( search && _mc && _mc[search] ) {
69
+ mcValues.push( _mc[search] );
70
+ }
71
+ }
72
+ }
73
+ });
74
+ return mcValues;
75
+ }
76
+
77
+ // get all ancestor DOM nodes up to the document root
78
+ function traverseNodes(node: { [key:string]: any }, search: string, firstonly = true): any[] {
79
+ let mcValues: any[] = [];
80
+ while (node) {
81
+ if (node._mc) {
82
+ if (!search) {
83
+ mcValues = mcValues.concat(Object.values(node._mc));
84
+ }
85
+ else if (search && node._mc[search]) {
86
+ mcValues.push(node._mc[search]);
87
+ }
88
+ if (firstonly)
89
+ return mcValues;
90
+ }
91
+ node = node.parentNode;
92
+ }
93
+ return mcValues;
94
+ }
95
+
96
+ export { McEvent };
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ import { getCE } from './elements.js'
4
+
5
+ // set of currently loading scripts
6
+ const loadingScripts: Set<string> = new Set();
7
+
8
+ const _makeLoadData = ( e: HTMLElement ): Array<any> | false => {
9
+
10
+ let
11
+ tagName = e?.localName ?? '',
12
+ isAttribute = e.getAttribute?.('is') || '',
13
+ isUBE = isAttribute ? true : false,
14
+ isCE = tagName.indexOf('-') !== -1 ? true : false,
15
+ ubeSelector = isUBE ? `${tagName}[is=\"${isAttribute}\"]:defined` : '',
16
+ ceSelector = isCE ? tagName + ':defined' : '',
17
+ fileBaseName = isUBE
18
+ ? isAttribute
19
+ : isCE
20
+ ? tagName
21
+ : '',
22
+ fileName = fileBaseName.length ? '/' + fileBaseName.split('-').join('/') + '.js' : '',
23
+ selector = isUBE
24
+ ? ubeSelector
25
+ : isCE
26
+ ? ceSelector
27
+ : ''
28
+ ;
29
+
30
+ //console.log( 'makeLoadData()', tagName, isUBE, isCE, ubeSelector, ceSelector, fileBaseName, ' => ', (isUBE || isCE) ? [ e, selector, fileName ] : false );
31
+ return (isUBE || isCE) ? [ e, selector, fileName, fileBaseName ] : false;
32
+ }
33
+
34
+ const _loadRequirements = ( node: HTMLTemplateElement | HTMLElement ): Promise<any> => {
35
+
36
+ let
37
+ undefinedSet: Set<any> = new Set(),
38
+ element: any = node instanceof HTMLTemplateElement ? (node as HTMLTemplateElement).content : node,
39
+ head = document.head,
40
+ allPromises: Array<any> = [],
41
+ e: HTMLElement;
42
+ ;
43
+
44
+ if ( element instanceof HTMLTemplateElement === false ){
45
+ // if node itself is undefined
46
+ let data: any = _makeLoadData(element);
47
+
48
+ if ( data && !data[0].matches( data[1] ) ){
49
+ undefinedSet.add( data );
50
+ }
51
+ }
52
+
53
+ // if some of the childNodes are undefined
54
+ Array.from( element.childNodes ).forEach(( node )=>{
55
+ let data: any = _makeLoadData(node as HTMLElement);
56
+
57
+ if ( data && !data[0].matches( data[1] ) ){
58
+ undefinedSet.add( data );
59
+ }
60
+ });
61
+
62
+ if ( !!undefinedSet.size ){ // there are requirements
63
+
64
+ undefinedSet.forEach( (data) => {
65
+ if ( !getCE( data[3] ) && !loadingScripts.has( data[2]) ){
66
+
67
+ loadingScripts.add( data[2] );
68
+
69
+ const se: HTMLScriptElement = document.createElement('script');
70
+
71
+ se.setAttribute( 'src', data[2] );
72
+ se.setAttribute( 'blocking', 'render' );
73
+ se.setAttribute( 'type', 'module' );
74
+ let s = (data as any)[2];
75
+ se.onload = () => {
76
+ // console.info('loaded', s);
77
+ loadingScripts.delete( s );
78
+ };
79
+
80
+ head.append( se );
81
+
82
+ let e = (data as Array<any>)[0];
83
+ } else {
84
+ return ;
85
+ }
86
+ });
87
+
88
+ }
89
+
90
+ return Promise.all( allPromises );
91
+ }
92
+
93
+ /*
94
+ TBD
95
+ if ( template.content.childNodes.length ){
96
+ _loadRequirements(template);
97
+ }
98
+ */
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
- import { DC } from './MC.js';
4
- import { kebabToPascal } from './helpers.js';
3
+ import { DC } from "./MC.js";
4
+ import { kebabToPascal } from "./helpers.js";
5
5
 
6
6
  class CeBaseClass extends HTMLElement {
7
7
  constructor() {
@@ -9,34 +9,43 @@ class CeBaseClass extends HTMLElement {
9
9
  }
10
10
 
11
11
  connectedCallback() {
12
- (DC as any).trigger(this, 'Connected');
12
+ (DC as any).trigger(this, "Connected");
13
13
  }
14
14
 
15
15
  disconnectedCallback() {
16
- (DC as any).trigger(this, 'Disconnected');
16
+ (DC as any).trigger(this, "Disconnected");
17
17
  }
18
18
 
19
19
  adoptedCallback() {
20
- (DC as any).trigger(this, 'Adopted');
20
+ (DC as any).trigger(this, "Adopted");
21
21
  }
22
22
 
23
23
  attributeChangedCallback(name: string, oldValue: any, newValue: any) {
24
- (DC as any).trigger(this, 'AttributeChanged', { name, oldValue, newValue });
24
+ (DC as any).trigger(this, "AttributeChanged", { name, oldValue, newValue });
25
25
  }
26
26
  }
27
27
 
28
- function createNamedClass(name: string, ClassBody: { new (...args: any[]): any } ) {
29
- return Object.defineProperty( ClassBody, 'name', { value: name });
28
+ function createNamedClass(
29
+ name: string,
30
+ ClassBody: { new (...args: any[]): any }
31
+ ) {
32
+ return Object.defineProperty(ClassBody, "name", { value: name });
30
33
  }
31
34
 
32
- export function defineCE( tagName: string, DefinitionClass: { new (...args: any[]): any }, observedAttributes: string[] = []){
35
+ export function defineCE(
36
+ tagName: string,
37
+ DefinitionClass: { new (...args: any[]): any },
38
+ observedAttributes: string[] = []
39
+ ) {
33
40
  if (customElements.get(tagName)) {
34
41
  console.warn(`IGNORED: Custom element "${tagName}" is already defined!`);
35
42
  return;
36
43
  }
37
44
 
38
- if (!tagName.includes('-')) {
39
- throw new Error('createCustomElement: tagName must contain at least one hyphen ("-").');
45
+ if (!tagName.includes("-")) {
46
+ throw new Error(
47
+ 'createCustomElement: tagName must contain at least one hyphen ("-").'
48
+ );
40
49
  }
41
50
 
42
51
  let name = kebabToPascal(tagName);
@@ -48,10 +57,10 @@ export function defineCE( tagName: string, DefinitionClass: { new (...args: any[
48
57
  class extends CeBaseClass {
49
58
  instance: any;
50
59
 
51
- constructor( data?: any ) {
60
+ constructor(data?: any) {
52
61
  super();
53
62
  let instance = new DefinitionClass(this, data);
54
- ( DC as any ).add(this, name, instance );
63
+ (DC as any).add(this, name, instance);
55
64
  }
56
65
 
57
66
  static get observedAttributes() {
@@ -60,7 +69,7 @@ export function defineCE( tagName: string, DefinitionClass: { new (...args: any[
60
69
  }
61
70
  )
62
71
  );
63
- };
72
+ }
64
73
 
65
74
  export function getCE(tagName: string): CustomElementConstructor | undefined {
66
75
  return customElements.get(tagName);