@twobirds/microcomponents 0.1.19 → 0.1.21
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/README.md +12 -16
- package/dist/MC.d.ts +31 -0
- package/dist/MC.d.ts.map +1 -0
- package/dist/MC.js +249 -0
- package/dist/MC.min.js +345 -0
- package/dist/MC.ts +269 -113
- package/dist/elements.d.ts +5 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +49 -0
- package/dist/elements.min.js +1 -0
- package/dist/elements.ts +26 -6
- package/dist/events.d.ts +11 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +55 -0
- package/dist/events.ts +158 -0
- package/dist/formValues.d.ts +3 -0
- package/dist/formValues.d.ts.map +1 -0
- package/dist/formValues.js +156 -0
- package/dist/formValues.min.js +1 -0
- package/dist/formValues.ts +168 -10
- package/dist/helpers.d.ts +15 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +113 -0
- package/dist/helpers.ts +82 -1
- package/dist/main.mjs +1 -0
- package/dist/microcomponents.d.ts +6 -0
- package/dist/microcomponents.d.ts.map +1 -0
- package/dist/microcomponents.js +6 -0
- package/dist/microcomponents.min.js +1 -0
- package/dist/observables.d.ts +11 -0
- package/dist/observables.d.ts.map +1 -0
- package/dist/observables.js +228 -0
- package/dist/observables.min.js +1 -0
- package/dist/observables.ts +132 -21
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -18,8 +18,6 @@ The distinguishing feature - compared to other frameworks - is its **minimalism*
|
|
|
18
18
|
|
|
19
19
|
## Status
|
|
20
20
|
|
|
21
|
-
For a quick glance try [this](https://gitlab.com/twoBirds/mc_template_webcomponents)...
|
|
22
|
-
|
|
23
21
|
In [manual testing](https://twobirds.gitlab.io/microcomponents/test/test.html) ( also a speed test).
|
|
24
22
|
|
|
25
23
|
Check the [typedoc API reference](https://twobirds.gitlab.io/microcomponents/typedoc/index.html) if you want to drill into the source code.
|
|
@@ -30,9 +28,9 @@ The progress of coding is being streamed on [twitch](https://twitch.tv/frankieth
|
|
|
30
28
|
|
|
31
29
|
### **Micro Components**
|
|
32
30
|
|
|
33
|
-
**Hint:**
|
|
31
|
+
**Hint:** The following code only shows how Micro Components are stored in the DOM.
|
|
34
32
|
|
|
35
|
-
before:
|
|
33
|
+
html before:
|
|
36
34
|
```HTML
|
|
37
35
|
<div></div>
|
|
38
36
|
```
|
|
@@ -69,7 +67,7 @@ element
|
|
|
69
67
|
.helloWorld();
|
|
70
68
|
```
|
|
71
69
|
|
|
72
|
-
after:
|
|
70
|
+
html after:
|
|
73
71
|
```HTML
|
|
74
72
|
<div data-mc></div>
|
|
75
73
|
```
|
|
@@ -134,7 +132,7 @@ class MyMC extends DC{
|
|
|
134
132
|
this.state.bind( target ); // links the state to DOM placeholders
|
|
135
133
|
|
|
136
134
|
// attach your own callbacks
|
|
137
|
-
this.state.
|
|
135
|
+
this.state.subscribe( (value) => {
|
|
138
136
|
console.log(value);
|
|
139
137
|
});
|
|
140
138
|
|
|
@@ -155,9 +153,10 @@ class MyMC extends DC{
|
|
|
155
153
|
constructor( target ){
|
|
156
154
|
super( target );
|
|
157
155
|
|
|
158
|
-
this.
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
this.target.innerHTML = /*HTML*/ `
|
|
157
|
+
<form>
|
|
158
|
+
<input name="textinput" value="Hallo Welt!"/>
|
|
159
|
+
</form>`;
|
|
161
160
|
|
|
162
161
|
// link the form property to the DOM input fields
|
|
163
162
|
formValues( this, 'form', this.target );
|
|
@@ -181,16 +180,13 @@ class MyMC extends DC{
|
|
|
181
180
|
constructor( target ){
|
|
182
181
|
super( target );
|
|
183
182
|
|
|
184
|
-
// attach event
|
|
185
|
-
|
|
186
|
-
// ...
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
this.one( 'click', () => {
|
|
183
|
+
// attach event handler programatically
|
|
184
|
+
let onHoverHandler = this.on( 'hover', () => {
|
|
190
185
|
// ...
|
|
191
186
|
});
|
|
192
187
|
|
|
193
|
-
|
|
188
|
+
// remove event handler
|
|
189
|
+
this.off( 'hover', onHoverHandler );
|
|
194
190
|
}
|
|
195
191
|
|
|
196
192
|
// this event handler is attached automatically
|
package/dist/MC.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LooseObject } from './helpers.js';
|
|
2
|
+
import { BubbleController } from './events.js';
|
|
3
|
+
export interface HTMLMcElement extends HTMLElement {
|
|
4
|
+
_mc: LooseObject;
|
|
5
|
+
}
|
|
6
|
+
declare class McBase {
|
|
7
|
+
private _target;
|
|
8
|
+
constructor(target?: {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
});
|
|
11
|
+
get target(): any;
|
|
12
|
+
}
|
|
13
|
+
declare class MC extends McBase {
|
|
14
|
+
constructor(target?: any);
|
|
15
|
+
}
|
|
16
|
+
declare class DC extends McBase {
|
|
17
|
+
constructor(target: HTMLElement);
|
|
18
|
+
static add(target: HTMLElement, key: string, element?: any): HTMLMcElement;
|
|
19
|
+
static remove(target: HTMLElement, key: string): void;
|
|
20
|
+
off(eventName: string, handler: EventListenerOrEventListenerObject): void;
|
|
21
|
+
on(eventName: string, handler: EventListenerOrEventListenerObject): EventListenerOrEventListenerObject;
|
|
22
|
+
one(eventName: string, handler: EventListenerOrEventListenerObject): EventListenerOrEventListenerObject;
|
|
23
|
+
trigger(eventName: string, data?: any, bubble?: string, controller?: BubbleController): void;
|
|
24
|
+
ancestors(): DC[] | null;
|
|
25
|
+
closest(): DC | null;
|
|
26
|
+
children(): DC[] | null;
|
|
27
|
+
descendants(): DC[] | null;
|
|
28
|
+
}
|
|
29
|
+
declare function autoload(enable?: boolean): boolean;
|
|
30
|
+
export { MC, DC, McBase, autoload };
|
|
31
|
+
//# sourceMappingURL=MC.d.ts.map
|
package/dist/MC.d.ts.map
ADDED
|
@@ -0,0 +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,EAAyB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAsBtE,MAAM,WAAW,aAAc,SAAQ,WAAW;IAajD,GAAG,EAAE,WAAW,CAAC;CACjB;AA+JD,cAAM,MAAM;IACX,OAAO,CAAC,OAAO,CAAe;gBAUlB,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE;IAmB3C,IAAI,MAAM,IAAI,GAAG,CAEhB;CACD;AAQD,cAAM,EAAG,SAAQ,MAAM;gBAMV,MAAM,CAAC,EAAE,GAAG;CAGxB;AASD,cAAM,EAAG,SAAQ,MAAM;gBACV,MAAM,EAAE,WAAW;IAgB/B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,GAAQ,GAAG,aAAa;IAc9E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM;IAK9C,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC;IAalE,EAAE,CACD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kCAAkC,GACzC,kCAAkC;IAarC,GAAG,CACF,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kCAAkC,GACzC,kCAAkC;IAcrC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,GAAE,MAAY,EAAE,UAAU,CAAC,EAAE,gBAAgB;IAc9F,SAAS,IAAI,EAAE,EAAE,GAAG,IAAI;IAsBxB,OAAO,IAAI,EAAE,GAAG,IAAI;IAcpB,QAAQ,IAAI,EAAE,EAAE,GAAG,IAAI;IAcvB,WAAW,IAAI,EAAE,EAAE,GAAG,IAAI;CAQ1B;AAwKD,iBAAS,QAAQ,CAAC,MAAM,GAAE,OAAc,GAAG,OAAO,CAuBjD;AAUD,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/MC.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { trigger, on, one, off } from './events.js';
|
|
3
|
+
const isBrowser = new Function('try {return this===window;}catch(e){ return false;}');
|
|
4
|
+
function isDOM(element) {
|
|
5
|
+
return element && element instanceof HTMLElement;
|
|
6
|
+
}
|
|
7
|
+
function add(target, key, element = {}) {
|
|
8
|
+
let node = target;
|
|
9
|
+
if (!node._mc) {
|
|
10
|
+
node._mc = new DC(target);
|
|
11
|
+
}
|
|
12
|
+
const _mc = node._mc;
|
|
13
|
+
if (key.length && !_mc[key]) {
|
|
14
|
+
_mc[key] = element;
|
|
15
|
+
if (target instanceof HTMLElement && !target.getAttribute('data-mc')) {
|
|
16
|
+
target.setAttribute('data-mc', '');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return node;
|
|
20
|
+
}
|
|
21
|
+
function remove(target, key) {
|
|
22
|
+
if (!key)
|
|
23
|
+
return;
|
|
24
|
+
const _mc = target?._mc || {};
|
|
25
|
+
if (_mc && _mc[key]) {
|
|
26
|
+
delete _mc[key];
|
|
27
|
+
}
|
|
28
|
+
if (!Object.keys(_mc).length && target instanceof HTMLElement && target.hasAttribute('data-mc')) {
|
|
29
|
+
target.removeAttribute('data-mc');
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
function init(element) {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
if (element.constructor === DC)
|
|
36
|
+
return;
|
|
37
|
+
element.trigger('Init');
|
|
38
|
+
}, 0);
|
|
39
|
+
}
|
|
40
|
+
function autoAttachListeners(element) {
|
|
41
|
+
if (!isBrowser() || element.constructor === DC)
|
|
42
|
+
return;
|
|
43
|
+
const target = element.target;
|
|
44
|
+
if (target instanceof HTMLElement) {
|
|
45
|
+
let that = element;
|
|
46
|
+
Object.getOwnPropertyNames(that.constructor.prototype)
|
|
47
|
+
.filter((key) => /^(on[A-Z]|one[A-Z])/.test(key) && typeof that.constructor.prototype[key] === 'function')
|
|
48
|
+
.forEach((key) => {
|
|
49
|
+
let once = /^one/.test(key), withoutOnOne = key.replace(/^on[e]{0,1}/, ''), nativeEventName = withoutOnOne.toLowerCase();
|
|
50
|
+
if ('on' + nativeEventName in target) {
|
|
51
|
+
let listener = (ev) => {
|
|
52
|
+
that[key](ev);
|
|
53
|
+
};
|
|
54
|
+
target.addEventListener(nativeEventName, listener);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
let listener = (ev) => {
|
|
58
|
+
that[key](ev);
|
|
59
|
+
};
|
|
60
|
+
on(target, withoutOnOne, listener, once);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function getMcChildNodes(domNode) {
|
|
66
|
+
const id = Math.random().toString().replace('.', '');
|
|
67
|
+
const selector = '[data-mc]:not([temp_id="' + id + '"] [data-mc] [data-mc])';
|
|
68
|
+
domNode.setAttribute('temp_id', id);
|
|
69
|
+
const mcArray = [...domNode.querySelectorAll(selector)]
|
|
70
|
+
.filter((e) => !!e._mc)
|
|
71
|
+
.map((e) => e._mc);
|
|
72
|
+
domNode.removeAttribute('temp_id');
|
|
73
|
+
return mcArray.length ? mcArray : null;
|
|
74
|
+
}
|
|
75
|
+
class McBase {
|
|
76
|
+
_target;
|
|
77
|
+
constructor(target) {
|
|
78
|
+
let element = this;
|
|
79
|
+
this._target = new WeakRef(target || {});
|
|
80
|
+
autoAttachListeners(element);
|
|
81
|
+
init(element);
|
|
82
|
+
}
|
|
83
|
+
get target() {
|
|
84
|
+
return this._target.deref();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
class MC extends McBase {
|
|
88
|
+
constructor(target) {
|
|
89
|
+
super(target);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
class DC extends McBase {
|
|
93
|
+
constructor(target) {
|
|
94
|
+
super(target);
|
|
95
|
+
}
|
|
96
|
+
static add(target, key, element = {}) {
|
|
97
|
+
return add(target, key, element);
|
|
98
|
+
}
|
|
99
|
+
static remove(target, key) {
|
|
100
|
+
remove(target, key);
|
|
101
|
+
}
|
|
102
|
+
off(eventName, handler) {
|
|
103
|
+
off(this.target, eventName, handler);
|
|
104
|
+
}
|
|
105
|
+
on(eventName, handler) {
|
|
106
|
+
return on(this.target, eventName, handler);
|
|
107
|
+
}
|
|
108
|
+
one(eventName, handler) {
|
|
109
|
+
return one(this.target, eventName, handler);
|
|
110
|
+
}
|
|
111
|
+
trigger(eventName, data = {}, bubble = 'l', controller) {
|
|
112
|
+
trigger(this.target, eventName, data, bubble, controller);
|
|
113
|
+
}
|
|
114
|
+
ancestors() {
|
|
115
|
+
let currentNode = this?.target, result = [];
|
|
116
|
+
if (!isDOM(currentNode))
|
|
117
|
+
return [];
|
|
118
|
+
while ((currentNode = currentNode.closest('[data-mc]'))) {
|
|
119
|
+
if (currentNode?._mc) {
|
|
120
|
+
result.push(currentNode?._mc);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return result.length ? result : null;
|
|
124
|
+
}
|
|
125
|
+
closest() {
|
|
126
|
+
let target = this.target;
|
|
127
|
+
if (!isDOM(target))
|
|
128
|
+
return null;
|
|
129
|
+
return target.closest('[data-mc]')?._mc || null;
|
|
130
|
+
}
|
|
131
|
+
children() {
|
|
132
|
+
let target = this?.target;
|
|
133
|
+
if (!isDOM(target))
|
|
134
|
+
return null;
|
|
135
|
+
return getMcChildNodes(target);
|
|
136
|
+
}
|
|
137
|
+
descendants() {
|
|
138
|
+
const target = this?.target;
|
|
139
|
+
if (!isDOM(target))
|
|
140
|
+
return [];
|
|
141
|
+
const mcArray = [...target.querySelectorAll('[data-mc]')]
|
|
142
|
+
.filter((e) => !!e._mc)
|
|
143
|
+
.map((e) => e._mc);
|
|
144
|
+
return mcArray.length ? mcArray : null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const loadingDCs = new Set();
|
|
148
|
+
function attachDC(element) {
|
|
149
|
+
return () => {
|
|
150
|
+
const elements = Array.from(document.querySelectorAll(`[data-mc*="${element}"]`)).filter((element) => element instanceof HTMLElement);
|
|
151
|
+
if (elements.length === 0)
|
|
152
|
+
return;
|
|
153
|
+
const Klass = customElements.get(element);
|
|
154
|
+
elements.forEach((node) => {
|
|
155
|
+
try {
|
|
156
|
+
DC.add(node, Klass.name, new Klass(node));
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
if (Klass['create']) {
|
|
160
|
+
let element = Klass.create(node);
|
|
161
|
+
element.setAttribute('data-mc', node.getAttribute('data-mc'));
|
|
162
|
+
node.replaceWith(element);
|
|
163
|
+
node = element;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
throw `Class ${Klass.name} doesn't have a callable constructor AND class doesn't have a static .create() method.`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const new_mc = node
|
|
170
|
+
.getAttribute('data-mc')
|
|
171
|
+
.split(' ')
|
|
172
|
+
.filter((name) => name !== element && name !== '')
|
|
173
|
+
.join(' ')
|
|
174
|
+
.trim();
|
|
175
|
+
node.setAttribute('data-mc', new_mc);
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function makeLoadScript(element) {
|
|
180
|
+
if (loadingDCs.has(element))
|
|
181
|
+
return;
|
|
182
|
+
loadingDCs.add(element);
|
|
183
|
+
const fileName = './' + element.split('-').join('/') + '.js';
|
|
184
|
+
const se = document.createElement('script');
|
|
185
|
+
se.setAttribute('src', fileName);
|
|
186
|
+
se.setAttribute('blocking', 'render');
|
|
187
|
+
se.async = true;
|
|
188
|
+
se.setAttribute('type', 'module');
|
|
189
|
+
se.setAttribute('data-name', element);
|
|
190
|
+
se.setAttribute('loading', '');
|
|
191
|
+
const loadedPromise = customElements.whenDefined(element);
|
|
192
|
+
loadedPromise.then(attachDC(element));
|
|
193
|
+
se.addEventListener('load', (ev) => {
|
|
194
|
+
loadingDCs.delete(element);
|
|
195
|
+
document.head.querySelector(`script[data-name="${element}"]`)?.remove();
|
|
196
|
+
});
|
|
197
|
+
se.addEventListener('error', (ev) => {
|
|
198
|
+
console.error('could not load DC code from', fileName);
|
|
199
|
+
});
|
|
200
|
+
document.head.append(se);
|
|
201
|
+
}
|
|
202
|
+
function loadUndefinedMCs() {
|
|
203
|
+
[...document.querySelectorAll(':not(:defined)')]
|
|
204
|
+
.filter((element) => !!element &&
|
|
205
|
+
!customElements.get(element.tagName.toLowerCase()) &&
|
|
206
|
+
!loadingDCs.has(element.tagName.toLowerCase()))
|
|
207
|
+
.forEach((el) => {
|
|
208
|
+
makeLoadScript(el.tagName.toLowerCase());
|
|
209
|
+
});
|
|
210
|
+
[...document.querySelectorAll('[data-mc]:not([data-mc=""]')]
|
|
211
|
+
.filter((element) => !!element)
|
|
212
|
+
.forEach((el) => {
|
|
213
|
+
const _mc = el
|
|
214
|
+
.getAttribute('data-mc')
|
|
215
|
+
?.split(' ')
|
|
216
|
+
.filter((name) => name !== '');
|
|
217
|
+
_mc?.forEach((element) => {
|
|
218
|
+
const isDefined = customElements.get(element);
|
|
219
|
+
if (!loadingDCs.has(element) && !isDefined) {
|
|
220
|
+
makeLoadScript(element);
|
|
221
|
+
}
|
|
222
|
+
else if (isDefined) {
|
|
223
|
+
attachDC(element)();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
let observer = null;
|
|
229
|
+
function autoload(enable = true) {
|
|
230
|
+
if (!enable) {
|
|
231
|
+
if (observer) {
|
|
232
|
+
observer.disconnect();
|
|
233
|
+
observer = null;
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
const wasEnabled = !!observer;
|
|
238
|
+
if (wasEnabled)
|
|
239
|
+
return true;
|
|
240
|
+
observer = new MutationObserver(loadUndefinedMCs);
|
|
241
|
+
setTimeout(() => {
|
|
242
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
243
|
+
loadUndefinedMCs();
|
|
244
|
+
}, 5);
|
|
245
|
+
window.autoload = window.autoload || autoload;
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
autoload.state = loadingDCs;
|
|
249
|
+
export { MC, DC, McBase, autoload };
|
package/dist/MC.min.js
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/******/ // The require scope
|
|
2
|
+
/******/ var __webpack_require__ = {};
|
|
3
|
+
/******/
|
|
4
|
+
/************************************************************************/
|
|
5
|
+
/******/ /* webpack/runtime/define property getters */
|
|
6
|
+
/******/ (() => {
|
|
7
|
+
/******/ // define getter functions for harmony exports
|
|
8
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
9
|
+
/******/ for(var key in definition) {
|
|
10
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
11
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
12
|
+
/******/ }
|
|
13
|
+
/******/ }
|
|
14
|
+
/******/ };
|
|
15
|
+
/******/ })();
|
|
16
|
+
/******/
|
|
17
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
18
|
+
/******/ (() => {
|
|
19
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
20
|
+
/******/ })();
|
|
21
|
+
/******/
|
|
22
|
+
/************************************************************************/
|
|
23
|
+
var __webpack_exports__ = {};
|
|
24
|
+
|
|
25
|
+
// EXPORTS
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
DC: () => (/* binding */ DC),
|
|
28
|
+
MC: () => (/* binding */ MC),
|
|
29
|
+
O: () => (/* binding */ McBase),
|
|
30
|
+
E: () => (/* binding */ autoload)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
;// ./build/events.js
|
|
34
|
+
|
|
35
|
+
function getMcEventName(eventName) {
|
|
36
|
+
return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
|
|
37
|
+
}
|
|
38
|
+
function off(domNode, eventName, handler) {
|
|
39
|
+
domNode.removeEventListener(getMcEventName(eventName), handler);
|
|
40
|
+
}
|
|
41
|
+
function on(domNode, eventName, handler, once = false) {
|
|
42
|
+
domNode.addEventListener(getMcEventName(eventName), handler, { capture: false, once });
|
|
43
|
+
return handler;
|
|
44
|
+
}
|
|
45
|
+
function one(domNode, eventName, handler) {
|
|
46
|
+
on(domNode, eventName, handler, true);
|
|
47
|
+
return handler;
|
|
48
|
+
}
|
|
49
|
+
class BubbleController {
|
|
50
|
+
stopped = false;
|
|
51
|
+
constructor() { }
|
|
52
|
+
stop() {
|
|
53
|
+
this.stopped = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function trigger(domNode, event, data = {}, bubble = 'l', controller) {
|
|
57
|
+
const eventName = /^_mc/.test(event) ? event : getMcEventName(event), bubbleController = controller ? controller : new BubbleController(), ev = new CustomEvent(eventName, {
|
|
58
|
+
detail: { data, control: bubbleController },
|
|
59
|
+
bubbles: false,
|
|
60
|
+
});
|
|
61
|
+
if (bubbleController.stopped)
|
|
62
|
+
return;
|
|
63
|
+
if (/l/.test(bubble)) {
|
|
64
|
+
domNode.dispatchEvent(ev);
|
|
65
|
+
ev.stopImmediatePropagation();
|
|
66
|
+
if (bubbleController.stopped)
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (/[ud]/.test(bubble)) {
|
|
70
|
+
if (bubble.indexOf('l') === -1) {
|
|
71
|
+
bubble += 'l';
|
|
72
|
+
}
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
if (bubble.indexOf('u') > -1) {
|
|
75
|
+
let parentMc = domNode.parentElement?.closest('[data-mc]');
|
|
76
|
+
if (parentMc) {
|
|
77
|
+
parentMc?._mc.trigger(eventName, data, bubble, bubbleController);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (bubble.indexOf('d') > -1) {
|
|
81
|
+
let childNodes = domNode._mc.children();
|
|
82
|
+
if (childNodes) {
|
|
83
|
+
childNodes.forEach((_mc) => _mc.trigger(eventName, data, bubble));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}, 0);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
;// ./build/MC.js
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
const isBrowser = new Function('try {return this===window;}catch(e){ return false;}');
|
|
94
|
+
function isDOM(element) {
|
|
95
|
+
return element && element instanceof HTMLElement;
|
|
96
|
+
}
|
|
97
|
+
function add(target, key, element = {}) {
|
|
98
|
+
let node = target;
|
|
99
|
+
if (!node._mc) {
|
|
100
|
+
node._mc = new DC(target);
|
|
101
|
+
}
|
|
102
|
+
const _mc = node._mc;
|
|
103
|
+
if (key.length && !_mc[key]) {
|
|
104
|
+
_mc[key] = element;
|
|
105
|
+
if (target instanceof HTMLElement && !target.getAttribute('data-mc')) {
|
|
106
|
+
target.setAttribute('data-mc', '');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return node;
|
|
110
|
+
}
|
|
111
|
+
function remove(target, key) {
|
|
112
|
+
if (!key)
|
|
113
|
+
return;
|
|
114
|
+
const _mc = target?._mc || {};
|
|
115
|
+
if (_mc && _mc[key]) {
|
|
116
|
+
delete _mc[key];
|
|
117
|
+
}
|
|
118
|
+
if (!Object.keys(_mc).length && target instanceof HTMLElement && target.hasAttribute('data-mc')) {
|
|
119
|
+
target.removeAttribute('data-mc');
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
function init(element) {
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
if (element.constructor === DC)
|
|
126
|
+
return;
|
|
127
|
+
element.trigger('Init');
|
|
128
|
+
}, 0);
|
|
129
|
+
}
|
|
130
|
+
function autoAttachListeners(element) {
|
|
131
|
+
if (!isBrowser() || element.constructor === DC)
|
|
132
|
+
return;
|
|
133
|
+
const target = element.target;
|
|
134
|
+
if (target instanceof HTMLElement) {
|
|
135
|
+
let that = element;
|
|
136
|
+
Object.getOwnPropertyNames(that.constructor.prototype)
|
|
137
|
+
.filter((key) => /^(on[A-Z]|one[A-Z])/.test(key) && typeof that.constructor.prototype[key] === 'function')
|
|
138
|
+
.forEach((key) => {
|
|
139
|
+
let once = /^one/.test(key), withoutOnOne = key.replace(/^on[e]{0,1}/, ''), nativeEventName = withoutOnOne.toLowerCase();
|
|
140
|
+
if ('on' + nativeEventName in target) {
|
|
141
|
+
let listener = (ev) => {
|
|
142
|
+
that[key](ev);
|
|
143
|
+
};
|
|
144
|
+
target.addEventListener(nativeEventName, listener);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
let listener = (ev) => {
|
|
148
|
+
that[key](ev);
|
|
149
|
+
};
|
|
150
|
+
on(target, withoutOnOne, listener, once);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function getMcChildNodes(domNode) {
|
|
156
|
+
const id = Math.random().toString().replace('.', '');
|
|
157
|
+
const selector = '[data-mc]:not([temp_id="' + id + '"] [data-mc] [data-mc])';
|
|
158
|
+
domNode.setAttribute('temp_id', id);
|
|
159
|
+
const mcArray = [...domNode.querySelectorAll(selector)]
|
|
160
|
+
.filter((e) => !!e._mc)
|
|
161
|
+
.map((e) => e._mc);
|
|
162
|
+
domNode.removeAttribute('temp_id');
|
|
163
|
+
return mcArray.length ? mcArray : null;
|
|
164
|
+
}
|
|
165
|
+
class McBase {
|
|
166
|
+
_target;
|
|
167
|
+
constructor(target) {
|
|
168
|
+
let element = this;
|
|
169
|
+
this._target = new WeakRef(target || {});
|
|
170
|
+
autoAttachListeners(element);
|
|
171
|
+
init(element);
|
|
172
|
+
}
|
|
173
|
+
get target() {
|
|
174
|
+
return this._target.deref();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
class MC extends McBase {
|
|
178
|
+
constructor(target) {
|
|
179
|
+
super(target);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
class DC extends McBase {
|
|
183
|
+
constructor(target) {
|
|
184
|
+
super(target);
|
|
185
|
+
}
|
|
186
|
+
static add(target, key, element = {}) {
|
|
187
|
+
return add(target, key, element);
|
|
188
|
+
}
|
|
189
|
+
static remove(target, key) {
|
|
190
|
+
remove(target, key);
|
|
191
|
+
}
|
|
192
|
+
off(eventName, handler) {
|
|
193
|
+
off(this.target, eventName, handler);
|
|
194
|
+
}
|
|
195
|
+
on(eventName, handler) {
|
|
196
|
+
return on(this.target, eventName, handler);
|
|
197
|
+
}
|
|
198
|
+
one(eventName, handler) {
|
|
199
|
+
return one(this.target, eventName, handler);
|
|
200
|
+
}
|
|
201
|
+
trigger(eventName, data = {}, bubble = 'l', controller) {
|
|
202
|
+
trigger(this.target, eventName, data, bubble, controller);
|
|
203
|
+
}
|
|
204
|
+
ancestors() {
|
|
205
|
+
let currentNode = this?.target, result = [];
|
|
206
|
+
if (!isDOM(currentNode))
|
|
207
|
+
return [];
|
|
208
|
+
while ((currentNode = currentNode.closest('[data-mc]'))) {
|
|
209
|
+
if (currentNode?._mc) {
|
|
210
|
+
result.push(currentNode?._mc);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return result.length ? result : null;
|
|
214
|
+
}
|
|
215
|
+
closest() {
|
|
216
|
+
let target = this.target;
|
|
217
|
+
if (!isDOM(target))
|
|
218
|
+
return null;
|
|
219
|
+
return target.closest('[data-mc]')?._mc || null;
|
|
220
|
+
}
|
|
221
|
+
children() {
|
|
222
|
+
let target = this?.target;
|
|
223
|
+
if (!isDOM(target))
|
|
224
|
+
return null;
|
|
225
|
+
return getMcChildNodes(target);
|
|
226
|
+
}
|
|
227
|
+
descendants() {
|
|
228
|
+
const target = this?.target;
|
|
229
|
+
if (!isDOM(target))
|
|
230
|
+
return [];
|
|
231
|
+
const mcArray = [...target.querySelectorAll('[data-mc]')]
|
|
232
|
+
.filter((e) => !!e._mc)
|
|
233
|
+
.map((e) => e._mc);
|
|
234
|
+
return mcArray.length ? mcArray : null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const loadingDCs = new Set();
|
|
238
|
+
function attachDC(element) {
|
|
239
|
+
return () => {
|
|
240
|
+
const elements = Array.from(document.querySelectorAll(`[data-mc*="${element}"]`)).filter((element) => element instanceof HTMLElement);
|
|
241
|
+
if (elements.length === 0)
|
|
242
|
+
return;
|
|
243
|
+
const Klass = customElements.get(element);
|
|
244
|
+
elements.forEach((node) => {
|
|
245
|
+
try {
|
|
246
|
+
DC.add(node, Klass.name, new Klass(node));
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (Klass['create']) {
|
|
250
|
+
let element = Klass.create(node);
|
|
251
|
+
element.setAttribute('data-mc', node.getAttribute('data-mc'));
|
|
252
|
+
node.replaceWith(element);
|
|
253
|
+
node = element;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
throw `Class ${Klass.name} doesn't have a callable constructor AND class doesn't have a static .create() method.`;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const new_mc = node
|
|
260
|
+
.getAttribute('data-mc')
|
|
261
|
+
.split(' ')
|
|
262
|
+
.filter((name) => name !== element && name !== '')
|
|
263
|
+
.join(' ')
|
|
264
|
+
.trim();
|
|
265
|
+
node.setAttribute('data-mc', new_mc);
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function makeLoadScript(element) {
|
|
270
|
+
if (loadingDCs.has(element))
|
|
271
|
+
return;
|
|
272
|
+
loadingDCs.add(element);
|
|
273
|
+
const fileName = './' + element.split('-').join('/') + '.js';
|
|
274
|
+
const se = document.createElement('script');
|
|
275
|
+
se.setAttribute('src', fileName);
|
|
276
|
+
se.setAttribute('blocking', 'render');
|
|
277
|
+
se.async = true;
|
|
278
|
+
se.setAttribute('type', 'module');
|
|
279
|
+
se.setAttribute('data-name', element);
|
|
280
|
+
se.setAttribute('loading', '');
|
|
281
|
+
const loadedPromise = customElements.whenDefined(element);
|
|
282
|
+
loadedPromise.then(attachDC(element));
|
|
283
|
+
se.addEventListener('load', (ev) => {
|
|
284
|
+
loadingDCs.delete(element);
|
|
285
|
+
document.head.querySelector(`script[data-name="${element}"]`)?.remove();
|
|
286
|
+
});
|
|
287
|
+
se.addEventListener('error', (ev) => {
|
|
288
|
+
console.error('could not load DC code from', fileName);
|
|
289
|
+
});
|
|
290
|
+
document.head.append(se);
|
|
291
|
+
}
|
|
292
|
+
function loadUndefinedMCs() {
|
|
293
|
+
[...document.querySelectorAll(':not(:defined)')]
|
|
294
|
+
.filter((element) => !!element &&
|
|
295
|
+
!customElements.get(element.tagName.toLowerCase()) &&
|
|
296
|
+
!loadingDCs.has(element.tagName.toLowerCase()))
|
|
297
|
+
.forEach((el) => {
|
|
298
|
+
makeLoadScript(el.tagName.toLowerCase());
|
|
299
|
+
});
|
|
300
|
+
[...document.querySelectorAll('[data-mc]:not([data-mc=""]')]
|
|
301
|
+
.filter((element) => !!element)
|
|
302
|
+
.forEach((el) => {
|
|
303
|
+
const _mc = el
|
|
304
|
+
.getAttribute('data-mc')
|
|
305
|
+
?.split(' ')
|
|
306
|
+
.filter((name) => name !== '');
|
|
307
|
+
_mc?.forEach((element) => {
|
|
308
|
+
const isDefined = customElements.get(element);
|
|
309
|
+
if (!loadingDCs.has(element) && !isDefined) {
|
|
310
|
+
makeLoadScript(element);
|
|
311
|
+
}
|
|
312
|
+
else if (isDefined) {
|
|
313
|
+
attachDC(element)();
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
let observer = null;
|
|
319
|
+
function autoload(enable = true) {
|
|
320
|
+
if (!enable) {
|
|
321
|
+
if (observer) {
|
|
322
|
+
observer.disconnect();
|
|
323
|
+
observer = null;
|
|
324
|
+
}
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
const wasEnabled = !!observer;
|
|
328
|
+
if (wasEnabled)
|
|
329
|
+
return true;
|
|
330
|
+
observer = new MutationObserver(loadUndefinedMCs);
|
|
331
|
+
setTimeout(() => {
|
|
332
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
333
|
+
loadUndefinedMCs();
|
|
334
|
+
}, 5);
|
|
335
|
+
window.autoload = window.autoload || autoload;
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
autoload.state = loadingDCs;
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
var __webpack_exports__DC = __webpack_exports__.DC;
|
|
342
|
+
var __webpack_exports__MC = __webpack_exports__.MC;
|
|
343
|
+
var __webpack_exports__McBase = __webpack_exports__.O;
|
|
344
|
+
var __webpack_exports__autoload = __webpack_exports__.E;
|
|
345
|
+
export { __webpack_exports__DC as DC, __webpack_exports__MC as MC, __webpack_exports__McBase as McBase, __webpack_exports__autoload as autoload };
|