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