@twobirds/microcomponents 0.0.27 → 0.0.29

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 (39) hide show
  1. package/assets/3d.html +42 -0
  2. package/assets/documentation/MicroComponents.md +39 -20
  3. package/assets/test.html +0 -1
  4. package/dist/MC.d.ts +6 -2
  5. package/dist/MC.d.ts.map +1 -1
  6. package/dist/MC.min.js +61 -85
  7. package/dist/MC.ts +85 -112
  8. package/dist/customElements.min.js +1 -1
  9. package/dist/customObservables.d.ts +1 -1
  10. package/dist/customObservables.d.ts.map +1 -1
  11. package/dist/customObservables.min.js +1 -1
  12. package/dist/customObservables.ts +2 -2
  13. package/dist/microcomponents.min.js +1 -1
  14. package/dist/test.ts +22 -5
  15. package/package.json +3 -3
  16. package/public/3d.html +42 -0
  17. package/public/MC.js +61 -85
  18. package/public/MC.js.map +1 -1
  19. package/public/MC.min.js +61 -85
  20. package/public/assets/search.js +1 -1
  21. package/public/classes/DC.html +26 -37
  22. package/public/classes/MC.html +19 -30
  23. package/public/classes/McBase.html +5 -17
  24. package/public/classes/McEvent.html +13 -13
  25. package/public/customElements.min.js +1 -1
  26. package/public/customObservables.js +1 -1
  27. package/public/customObservables.js.map +1 -1
  28. package/public/customObservables.min.js +1 -1
  29. package/public/documentation/MicroComponents.md +39 -20
  30. package/public/functions/addListener.html +1 -1
  31. package/public/functions/removeListener.html +1 -1
  32. package/public/interfaces/HTMLMcElement.html +2 -2
  33. package/public/microcomponents.min.js +1 -1
  34. package/public/test.html +0 -1
  35. package/public/test.js +16 -5
  36. package/public/test.js.map +1 -1
  37. package/src/MC.ts +85 -112
  38. package/src/customObservables.ts +2 -2
  39. package/src/test.ts +22 -5
package/assets/3d.html ADDED
@@ -0,0 +1,42 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>3D Positioned Image with CSS</title>
7
+ <style>
8
+ body {
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ height: 100vh;
13
+ background-color: #222;
14
+ perspective: 800px; /* Depth effect */
15
+ }
16
+
17
+ .container {
18
+ width: 300px;
19
+ height: 200px;
20
+ transform-style: preserve-3d; /* Needed for 3D transformations */
21
+ }
22
+
23
+ .image3d {
24
+ width: 100%;
25
+ height: 100%;
26
+ transform: rotateY(20deg) rotateX(10deg) translateZ(50px);
27
+ transition: transform 0.5s ease-in-out;
28
+ box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.5);
29
+ }
30
+
31
+ /* Hover effect */
32
+ .container:hover .image3d {
33
+ transform: rotateY(-20deg) rotateX(-10deg) translateZ(100px);
34
+ }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div class="container">
39
+ <img class="image3d" src="https://via.placeholder.com/300x200" alt="3D Image">
40
+ </div>
41
+ </body>
42
+ </html>
@@ -27,16 +27,27 @@ As an application programmer you should understand **MC** and **DC** methods and
27
27
  - **DC** use observables and formValues to provide 1-way and 2-way binding to the DOM.
28
28
  - **DC** have selectors to find other DCs in the DOM.
29
29
 
30
- ## MC() Class overview
30
+ ## McBase() Superclass (not exported), Overview
31
31
 
32
32
  **Instance Properties**
33
33
  - `.target`: readonly, a getter returning the DOM element or parent MC instance your instance resides in
34
+
35
+ **Constructor:**
36
+ - calls `init()`: triggers the 'init' lifecycle event, also recursively into the inner '._mc' structure.
37
+ - calls `autoAttachListeners()`: methods in your MC that start with "on[A-Z]" or "one[A-Z]" and describe native DOM events (e.g. "onClick") will be added to the DOM Element as listeners.
38
+
39
+ # Exported:
40
+
41
+ ## MC() Class, extends McBase
42
+
43
+ **Instance Properties**
44
+ - `.target`: (inherited from McBase)
34
45
  - `._mc`: a hash object that contains inner micro components
35
46
 
36
47
  - **Instance Methods:**
37
- - `.trigger( eventName, data )`: trigger an event on this instance
48
+ - `.trigger( eventName, data )`: (inherited from McBase)
38
49
 
39
- ## DC() Class Overview
50
+ ## DC() Class, extends McBase
40
51
 
41
52
  - **Static Methods:**
42
53
  - `DC.add( DomElement, key, mc)`: Add a DC to an HTMLElement.
@@ -44,27 +55,24 @@ As an application programmer you should understand **MC** and **DC** methods and
44
55
  - `DC.trigger( eventName, DomElement, data, bubble )`: trigger an event, handles directional traversal in the DOM.
45
56
 
46
57
  **Instance Properties**
47
-
48
- ( inherited from MC )
49
- - `.target`: readonly, a getter returning the DOM element the instance resides in
50
- - `._mc`: a hash object that contains inner MCs
58
+ - `.target`: (inherited from McBase)
59
+ - `._mc`: a hash object that contains inner micro components
51
60
 
52
61
  - **Instance Methods:**
53
62
  - `.parent(search?)`: Get parent DCs.
54
63
  - `.ancestors(search?)`: Get ancestor DCs.
55
64
  - `.children(search?)`: Get child DCs.
56
65
  - `.descendants(search?)`: Get descendant DCs.
57
- - `.autoAttachListeners()`: methods in your MC that start with "on[A-Z]" or "one[A-Z]" and describe native DOM events (e.g. "onClick") will be added to the DOM Element as listeners.
58
-
59
- (inherited from MC )
60
66
  - `.trigger( eventName, data, bubble )`: trigger an event on "this", handles directional bubbling in the DOM.
61
67
 
62
- ### Typical Workflow
68
+ # Usage
69
+
70
+ ## Typical Workflow
63
71
 
64
72
  1. **Attach DCs** to HTMLElements using `DC.add()`.
65
73
  2. **Access** other DCs by their property key or navigating through DOM (e.g., `ancestors()`, `children()`, etc.) **and use their inner functionality**.
66
74
 
67
- # Attaching Micro Components to a DOM element
75
+ ### Attach Micro Components to a DOM element
68
76
 
69
77
  To attach a micro component to an HTML element, use the `DC.add()` static function.
70
78
 
@@ -96,7 +104,7 @@ DC.add( myElement, 'myDcComponent', new MyClass( myElement ) );
96
104
  - After you added a micro component using this function, the **HTMLElement will contain a property `_mc`** which contains the external MC instances.
97
105
  - Also the **HTMLElement then has an attribute '_mc'** which will indicate that at least one micro component is attached to this dom element.
98
106
 
99
- # Removing a top level Micro Component from a DOM element
107
+ ### Remove a top level Micro Component from a DOM element
100
108
 
101
109
  Micro components can be removed using the `DC.remove()` static method.
102
110
 
@@ -106,7 +114,7 @@ DC.remove( myDomElement, 'myComponent');
106
114
 
107
115
  **When all micro components are removed** (the _mc object has no more properties), the **`_mc` attribute is also removed** from the HTML element.
108
116
 
109
- # Retrieve all top level Micro Components from a DOM element
117
+ ### Retrieve Micro Components from a DOM element
110
118
 
111
119
  ```javascript
112
120
  const target = document.querySelector( 'div' );
@@ -120,7 +128,7 @@ const specificInstance = target._mc?.myPublicComponent;
120
128
  console.log(specificInstance);
121
129
  ```
122
130
 
123
- ### Trigger an Event on all DCs
131
+ ### Trigger an Event
124
132
 
125
133
  ```javascript
126
134
  const target = document.querySelector( 'div' );
@@ -132,7 +140,7 @@ DC.trigger( target, '<eventName>', data | null, bubble );
132
140
 
133
141
  # Methods you can use in your Micro Component Instances
134
142
 
135
- ## Retrieving Inner Micro Components
143
+ ## Retrieve Inner Micro Components
136
144
 
137
145
  You can retrieve an inner micro component by using the ._mc property.
138
146
 
@@ -144,7 +152,7 @@ console.log(innerComponent);
144
152
  **The following methods hop over HTMLElements that DO NOT contain micro components.**
145
153
 
146
154
 
147
- ## Navigating Parent and Ancestor Micro Components
155
+ ## Navigate Parent and Ancestor Micro Components
148
156
 
149
157
  The `.parent()` and `.ancestors()` methods allow you to retrieve micro components attached to parent elements.
150
158
 
@@ -161,7 +169,7 @@ To retrieve specific micro component(s) attached to ancestors:
161
169
  const specificAncestorMc = this.ancestors('myComponent');
162
170
  ```
163
171
 
164
- ## Retrieving Child and Descendant Micro Components
172
+ ## Retrieve Child and Descendant Micro Components
165
173
 
166
174
  The `.children()` and `.descendants()` methods retrieve micro components attached to child elements or any descendants.
167
175
  ```javascript
@@ -175,7 +183,7 @@ console.log(descendantComponents); // an array of all descendant micro componen
175
183
  const specificMcs = this.descenants('specificMc');
176
184
  ```
177
185
 
178
- ### Trigger Events on MCs
186
+ ## Trigger an Event
179
187
  ```javascript
180
188
  // trigger an event on yourself
181
189
  this
@@ -206,7 +214,7 @@ this
206
214
 
207
215
  ## Automatically attach Listener Methods to the DOM
208
216
 
209
- On any **DC** instance, you can call **.autoAttachListeners()** in the constructor.
217
+ On any **MC** and **DC** instance, the Superclass McBase calls **autoAttachListeners()** in the constructor.
210
218
 
211
219
  Any methods you define in your code that start with **"on"** or **"one"**, and also match DOM event names, will be called accordingly:
212
220
 
@@ -226,3 +234,14 @@ let myFirstDiv = document.querySelector('div');
226
234
  DC.add( myFirstDiv, 'myEventTarget', new MyEventTarget( myFirstDiv ) );
227
235
  // now wait for somebody to click on that <div>
228
236
  ```
237
+ # Lifecycle Events on **MC** and **DC**
238
+
239
+ ## Init
240
+ - "this" first
241
+ - traverses recursively into the _mc structure
242
+ - requires **method .oneInit()** to be present in your class definition.
243
+
244
+ ## Destroy ( TBD )
245
+ - recursive "_mc" first
246
+ - then "this"
247
+ - requires **method .oneDestroy()** to be present in your class definition.
package/assets/test.html CHANGED
@@ -7,7 +7,6 @@
7
7
  <link rel="icon" type="image/svg+xml" sizes="any" href="MicroComponents.svg" />
8
8
  <link href="./my-tag.css" rel="stylesheet" />
9
9
  <script type="module" src="./test.js"></script>
10
- <script src="./customSelectors.min.js"></script>
11
10
  </head>
12
11
  <body>
13
12
  Open the debugger, read console, then:&nbsp;
package/dist/MC.d.ts CHANGED
@@ -14,12 +14,17 @@ declare class McBase {
14
14
  get target(): any;
15
15
  }
16
16
  declare class MC extends McBase {
17
+ _mc: {
18
+ [key: string]: any;
19
+ };
17
20
  constructor(target: any);
18
21
  static trigger: typeof trigger;
19
22
  trigger(ev: McEvent | string, data?: any, bubble?: string): this | undefined;
20
- autoAttachListeners(): void;
21
23
  }
22
24
  declare class DC extends McBase {
25
+ protected __mc: {
26
+ [key: string]: any;
27
+ };
23
28
  constructor(target: HTMLElement);
24
29
  static debug: boolean;
25
30
  static add: Function;
@@ -29,7 +34,6 @@ declare class DC extends McBase {
29
34
  [key: string]: any;
30
35
  };
31
36
  trigger(ev: McEvent | string, data?: any, bubble?: string): void;
32
- autoAttachListeners(): void;
33
37
  parent(search?: string): any[];
34
38
  ancestors(search?: string): any[];
35
39
  children(search?: string): any[];
package/dist/MC.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"MC.d.ts","sourceRoot":"","sources":["../src/MC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAWvC,MAAM,WAAW,aAAc,SAAQ,WAAW;IACjD,GAAG,EAAE,WAAW,CAAC;CACjB;AA6CD,iBAAS,WAAW,CAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,IAAI,GAAE,OAAe,QAe1J;AAED,iBAAS,cAAc,CAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI,QAE5G;AA+CD,iBAAS,OAAO,CAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,QAUtE;AAED,cAAM,MAAM;;gBAME,MAAM,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE;IAY1C,IAAI,MAAM,IAAI,GAAG,CAEhB;CAED;AAED,cAAM,EAAG,SAAQ,MAAM;gBAEV,MAAM,EAAE,GAAG;IA8BpB,MAAM,CAAC,OAAO,iBAAW;IAE5B,OAAO,CAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,CAAC,EAAE,MAAM;IAiF9D,mBAAmB;CA2CnB;AAED,cAAM,EAAG,SAAQ,MAAM;gBAEV,MAAM,EAAE,WAAW;IAkC/B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAS;IAE9B,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAO;IAC3B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAU;IACjC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAW;IAEnC,IAAI,GAAG,IAAI;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAE/B;IAED,OAAO,CAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,CAAC,EAAE,MAAM;IAI9D,mBAAmB;IAInB,MAAM,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMlC,SAAS,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMrC,QAAQ,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAYpC,WAAW,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;CAOvC;AAED,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"MC.d.ts","sourceRoot":"","sources":["../src/MC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAWvC,MAAM,WAAW,aAAc,SAAQ,WAAW;IACjD,GAAG,EAAE,WAAW,CAAC;CACjB;AA6CD,iBAAS,WAAW,CAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI,EAAE,OAAO,GAAE,OAAe,EAAE,IAAI,GAAE,OAAe,QAe1J;AAED,iBAAS,cAAc,CAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI,QAE5G;AA+CD,iBAAS,OAAO,CAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,QAUtE;AA4ED,cAAM,MAAM;;gBAIE,MAAM,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE;IAY1C,IAAI,MAAM,IAAI,GAAG,CAEhB;CAED;AAED,cAAM,EAAG,SAAQ,MAAM;IAEtB,GAAG,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAAM;gBAEpB,MAAM,EAAE,GAAG;IAIpB,MAAM,CAAC,OAAO,iBAAW;IAE5B,OAAO,CAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,CAAC,EAAE,MAAM;CAiF9D;AAED,cAAM,EAAG,SAAQ,MAAM;IAEtB,SAAS,CAAC,IAAI,EAAE;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAAM;gBAE/B,MAAM,EAAE,WAAW;IAI/B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAS;IAE9B,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAO;IAC3B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAU;IACjC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAW;IAEnC,IAAI,GAAG,IAAI;QAAE,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAE,CAE/B;IAED,OAAO,CAAE,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,CAAC,EAAE,MAAM;IAI9D,MAAM,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMlC,SAAS,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMrC,QAAQ,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAYpC,WAAW,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;CAOvC;AAED,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC"}
package/dist/MC.min.js CHANGED
@@ -244,45 +244,77 @@ function trigger(target, ev, data = {}) {
244
244
  });
245
245
  return;
246
246
  }
247
+ // run the "init" lifecycle event on the completemcr structure
248
+ function init(element) {
249
+ let isDomMcInstance = element.constructor === DC;
250
+ setTimeout(() => {
251
+ element.trigger('Init');
252
+ if (!isDomMcInstance) {
253
+ setTimeout(() => {
254
+ let keys = Object.keys(element?._mc);
255
+ if (keys.length) {
256
+ //console.log( 'inner Inits on [', mc.constructor.name, ']', keys );
257
+ keys?.forEach((key) => {
258
+ let mc = element?._mc?.[key];
259
+ //console.log( key, typeof mc?.oneInit, mc );
260
+ if (mc['oneInit'] && typeof mc.oneInit == 'function') {
261
+ mc.oneInit(new McEvent('Init'));
262
+ }
263
+ });
264
+ }
265
+ ;
266
+ }, 0);
267
+ }
268
+ }, 0);
269
+ }
270
+ function autoAttachListeners(element) {
271
+ if (!MC_isBrowser() || element.constructor === DC)
272
+ return;
273
+ const target = element.target;
274
+ if (target instanceof HTMLElement) {
275
+ let that = element;
276
+ Object
277
+ .getOwnPropertyNames(that.constructor.prototype)
278
+ .filter(key => /^on[A-Z]|one[A-Z]/.test(key) && typeof that.constructor.prototype[key] === 'function')
279
+ .forEach(key => {
280
+ let once = /^one/.test(key), withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
281
+ nativeEventName = withoutOnOne.toLowerCase(), listener = (ev) => { that.trigger(withoutOnOne, ev); };
282
+ ;
283
+ if (once) {
284
+ // console.log( '...is only called once', that.constructor.prototype[key] );
285
+ Object.defineProperty(element, 'on' + withoutOnOne, {
286
+ configurable: true,
287
+ enumerable: false,
288
+ writable: true,
289
+ value: (ev) => {
290
+ // console.log( 'onceHandler execute:', that.constructor.prototype[key] );
291
+ (that.constructor.prototype[key]).bind(that)(ev);
292
+ }
293
+ });
294
+ }
295
+ if (MC_nativeEventNames.has('on' + nativeEventName)) { // native event defined in HTMLElement
296
+ // console.log('added as native listener', target, nativeEventName );
297
+ addListener(target, nativeEventName, listener, false, once);
298
+ }
299
+ });
300
+ }
301
+ }
247
302
  class McBase {
248
303
  #target; // avoid circular reference
249
- #_mc = {};
250
304
  constructor(target) {
251
- let that = this;
305
+ let that = this, element = that;
252
306
  this.#target = new WeakRef(target);
253
- if (this.constructor !== DC) {
254
- Object.defineProperty(this, "_mc", {
255
- get() { return this.#_mc; }
256
- });
257
- }
258
- ;
307
+ init(element); // async lifecycle event
308
+ autoAttachListeners(element);
259
309
  }
260
310
  get target() {
261
311
  return this.#target.deref();
262
312
  }
263
313
  }
264
314
  class MC extends McBase {
315
+ _mc = {};
265
316
  constructor(target) {
266
317
  super(target);
267
- let that = this;
268
- setTimeout(() => {
269
- that.trigger('Init');
270
- setTimeout(() => {
271
- let keys = Object.keys(that?._mc);
272
- if (keys.length) {
273
- //console.log( 'inner Inits on [', that.constructor.name, ']', keys );
274
- keys?.forEach((key) => {
275
- let mc = that?._mc?.[key];
276
- //console.log( key, typeof mc?.oneInit, mc );
277
- if (mc?.oneInit && typeof mc?.oneInit == 'function') {
278
- mc.oneInit(new McEvent('Init'));
279
- }
280
- });
281
- }
282
- ;
283
- }, 0);
284
- }, 0);
285
- this.autoAttachListeners();
286
318
  }
287
319
  static trigger = trigger;
288
320
  trigger(ev, data = {}, bubble) {
@@ -345,80 +377,24 @@ class MC extends McBase {
345
377
  }
346
378
  }
347
379
  }
348
- autoAttachListeners() {
349
- if (!MC_isBrowser())
350
- return;
351
- const target = this.target;
352
- if (target instanceof HTMLElement) {
353
- let that = this;
354
- Object
355
- .getOwnPropertyNames(that.constructor.prototype)
356
- .filter(key => /^on[A-Z]|one[A-Z]/.test(key) && typeof that.constructor.prototype[key] === 'function')
357
- .forEach(key => {
358
- let once = /^one/.test(key), withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
359
- nativeEventName = withoutOnOne.toLowerCase(), listener = (ev) => { that.trigger(withoutOnOne, ev); };
360
- ;
361
- if (once) {
362
- // console.log( '...is only called once', that.constructor.prototype[key] );
363
- Object.defineProperty(this, 'on' + withoutOnOne, {
364
- configurable: true,
365
- enumerable: false,
366
- writable: true,
367
- value: (ev) => {
368
- // console.log( 'onceHandler execute:', that.constructor.prototype[key] );
369
- (that.constructor.prototype[key]).bind(that)(ev);
370
- }
371
- });
372
- }
373
- if (MC_nativeEventNames.has('on' + nativeEventName)) { // native event defined in HTMLElement
374
- // console.log('added as native listener', target, nativeEventName );
375
- addListener(target, nativeEventName, listener, false, once);
376
- }
377
- });
378
- }
379
- }
380
380
  }
381
381
  ;
382
382
  class DC extends McBase {
383
+ __mc = {};
383
384
  constructor(target) {
384
385
  super(target);
385
- let that = this, isDomMcInstance = that.constructor === DC;
386
- setTimeout(() => {
387
- that.trigger('Init');
388
- if (!isDomMcInstance) {
389
- setTimeout(() => {
390
- let keys = Object.keys(that?._mc);
391
- if (keys.length) {
392
- //console.log( 'inner Inits on [', that.constructor.name, ']', keys );
393
- keys?.forEach((key) => {
394
- let mc = that?._mc?.[key];
395
- //console.log( key, typeof mc?.oneInit, mc );
396
- if (mc?.oneInit && typeof mc?.oneInit == 'function') {
397
- mc.oneInit(new McEvent('Init'));
398
- }
399
- });
400
- }
401
- ;
402
- }, 0);
403
- }
404
- }, 0);
405
- this.autoAttachListeners();
406
386
  }
407
387
  static debug = false;
408
388
  static add = add;
409
389
  static remove = remove;
410
390
  static trigger = trigger;
411
391
  get _mc() {
412
- return this._mc;
392
+ return this.__mc;
413
393
  }
414
394
  trigger(ev, data = {}, bubble) {
415
395
  MC.prototype.trigger.call(this, ev, data, bubble);
416
396
  }
417
397
  ;
418
- autoAttachListeners() {
419
- MC.prototype.autoAttachListeners.call(this);
420
- }
421
- ;
422
398
  parent(search = '') {
423
399
  let target = this.target;
424
400
  if (!MC_isDOM(target))
package/dist/MC.ts CHANGED
@@ -137,22 +137,94 @@ function trigger( target: unknown, ev: McEvent | string, data: any = {}) {
137
137
  return;
138
138
  }
139
139
 
140
+ // run the "init" lifecycle event on the completemcr structure
141
+ function init( element: MC | DC ){
142
+ let isDomMcInstance = element.constructor === DC;
143
+
144
+ setTimeout(
145
+ () => {
146
+ element.trigger('Init');
147
+ if ( !isDomMcInstance ) {
148
+ setTimeout(
149
+ () => {
150
+ let keys = Object.keys( element?._mc );
151
+ if ( keys.length ){
152
+ //console.log( 'inner Inits on [', mc.constructor.name, ']', keys );
153
+ keys?.forEach( (key: string) => {
154
+ let mc = element?._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
+ }
166
+ , 0
167
+ );
168
+
169
+ }
170
+
171
+ function autoAttachListeners( element: MC | DC ){
172
+ if ( !isBrowser() || element.constructor === DC ) return;
173
+
174
+ const target = element.target;
175
+
176
+ if ( target instanceof HTMLElement ){
177
+ let that: LooseObject = element;
178
+ Object
179
+ .getOwnPropertyNames( that.constructor.prototype )
180
+ .filter( key => /^on[A-Z]|one[A-Z]/.test(key) && typeof that.constructor.prototype[key] === 'function' )
181
+ .forEach( key => {
182
+ let
183
+ once = /^one/.test(key),
184
+ withoutOnOne = key.replace( /^on[e]{0,1}/, '' ), // preserves upper/lowercase for non-native events
185
+ nativeEventName = withoutOnOne.toLowerCase(),
186
+ listener = ( ev: McEvent | Event | CustomEvent ) => { that.trigger( withoutOnOne, ev ); };
187
+ ;
188
+
189
+ if ( once ){
190
+ // console.log( '...is only called once', that.constructor.prototype[key] );
191
+ Object.defineProperty(
192
+ element,
193
+ 'on' + withoutOnOne,
194
+ {
195
+ configurable: true,
196
+ enumerable: false,
197
+ writable: true,
198
+ value: (ev: any) => {
199
+ // console.log( 'onceHandler execute:', that.constructor.prototype[key] );
200
+ ( that.constructor.prototype[key] ).bind(that)(ev);
201
+ }
202
+ }
203
+ );
204
+ }
205
+
206
+ if ( nativeEventNames.has( 'on' + nativeEventName ) ){ // native event defined in HTMLElement
207
+ // console.log('added as native listener', target, nativeEventName );
208
+ addListener( target, nativeEventName, listener, false, once );
209
+ }
210
+ });
211
+ }
212
+ }
213
+
140
214
  class McBase {
141
215
 
142
216
  #target: WeakRef<any>; // avoid circular reference
143
217
 
144
- #_mc: { [key:string]: any } = {};
145
-
146
218
  constructor( target: { [key:string]: any } ) {
147
- let that = this;
219
+ let that: unknown = this,
220
+ element = (that as MC | DC );
148
221
 
149
222
  this.#target = new WeakRef( target );
150
223
 
151
- if ( this.constructor !== DC){
152
- Object.defineProperty( this, "_mc", {
153
- get(){ return this.#_mc }
154
- });
155
- };
224
+
225
+ init( element ); // async lifecycle event
226
+
227
+ autoAttachListeners( element );
156
228
  }
157
229
 
158
230
  get target(): any {
@@ -163,34 +235,10 @@ class McBase {
163
235
 
164
236
  class MC extends McBase {
165
237
 
238
+ _mc: { [key:string]: any } = {};
239
+
166
240
  constructor(target: any) {
167
241
  super(target);
168
- let that = this;
169
-
170
- setTimeout(
171
- () => {
172
- that.trigger('Init');
173
- setTimeout(
174
- () => {
175
- let keys = Object.keys( (that as any)?._mc );
176
- if ( keys.length ){
177
- //console.log( 'inner Inits on [', that.constructor.name, ']', keys );
178
- keys?.forEach( (key: string) => {
179
- let mc = (that as any)?._mc?.[key];
180
- //console.log( key, typeof mc?.oneInit, mc );
181
- if ( mc?.oneInit && typeof mc?.oneInit == 'function' ){
182
- mc.oneInit( new McEvent('Init') );
183
- }
184
- });
185
- };
186
- }
187
- , 0
188
- );
189
- }
190
- ,0
191
- );
192
-
193
- this.autoAttachListeners();
194
242
  }
195
243
 
196
244
  static trigger = trigger;
@@ -276,85 +324,14 @@ class MC extends McBase {
276
324
 
277
325
  }
278
326
 
279
- autoAttachListeners(){
280
- if ( !isBrowser() ) return;
281
-
282
- const target = this.target;
283
-
284
- if ( target instanceof HTMLElement ){
285
- let that: LooseObject = this;
286
- Object
287
- .getOwnPropertyNames( that.constructor.prototype )
288
- .filter( key => /^on[A-Z]|one[A-Z]/.test(key) && typeof that.constructor.prototype[key] === 'function' )
289
- .forEach( key => {
290
- let
291
- once = /^one/.test(key),
292
- withoutOnOne = key.replace( /^on[e]{0,1}/, '' ), // preserves upper/lowercase for non-native events
293
- nativeEventName = withoutOnOne.toLowerCase(),
294
- listener = ( ev: McEvent | Event | CustomEvent ) => { that.trigger( withoutOnOne, ev ); };
295
- ;
296
-
297
- if ( once ){
298
- // console.log( '...is only called once', that.constructor.prototype[key] );
299
- Object.defineProperty(
300
- this,
301
- 'on' + withoutOnOne,
302
- {
303
- configurable: true,
304
- enumerable: false,
305
- writable: true,
306
- value: (ev: any) => {
307
- // console.log( 'onceHandler execute:', that.constructor.prototype[key] );
308
- ( that.constructor.prototype[key] ).bind(that)(ev);
309
- }
310
- }
311
- );
312
- }
313
-
314
- if ( nativeEventNames.has( 'on' + nativeEventName ) ){ // native event defined in HTMLElement
315
- // console.log('added as native listener', target, nativeEventName );
316
- addListener( target, nativeEventName, listener, false, once );
317
- }
318
- });
319
- }
320
- }
321
-
322
327
  };
323
328
 
324
329
  class DC extends McBase {
325
330
 
331
+ protected __mc: { [key:string]: any } = {};
332
+
326
333
  constructor(target: HTMLElement ) {
327
334
  super(target);
328
-
329
- let that = this,
330
- isDomMcInstance = that.constructor === DC;
331
-
332
- setTimeout(
333
- () => {
334
- that.trigger('Init');
335
- if ( !isDomMcInstance ) {
336
- setTimeout(
337
- () => {
338
- let keys = Object.keys( (that as any)?._mc );
339
- if ( keys.length ){
340
- //console.log( 'inner Inits on [', that.constructor.name, ']', keys );
341
- keys?.forEach( (key: string) => {
342
- let mc = (that as any)?._mc?.[key];
343
- //console.log( key, typeof mc?.oneInit, mc );
344
- if ( mc?.oneInit && typeof mc?.oneInit == 'function' ){
345
- mc.oneInit( new McEvent('Init') );
346
- }
347
- });
348
- };
349
- }
350
- , 0
351
- );
352
- }
353
- }
354
- , 0
355
- );
356
-
357
- this.autoAttachListeners();
358
335
  }
359
336
 
360
337
  static debug: boolean = false;
@@ -364,17 +341,13 @@ class DC extends McBase {
364
341
  static trigger: Function = trigger;
365
342
 
366
343
  get _mc(): { [key:string]: any } {
367
- return this._mc;
344
+ return this.__mc;
368
345
  }
369
346
 
370
347
  trigger( ev: McEvent | string, data: any = {}, bubble?: string ) {
371
348
  MC.prototype.trigger.call( this, ev, data, bubble );
372
349
  };
373
350
 
374
- autoAttachListeners() {
375
- MC.prototype.autoAttachListeners.call( this );
376
- };
377
-
378
351
  parent(search: string = ''): any[] {
379
352
  let target: HTMLElement = (this as any).target;
380
353
  if (!isDOM(target)) return [];