@twobirds/microcomponents 0.0.34 → 0.0.39
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 +40 -27
- package/assets/documentation/{MicroComponents.md → MC.md} +17 -17
- package/assets/documentation/comparision.md +0 -0
- package/assets/documentation/elements.md +276 -0
- package/assets/documentation/magic.md +10 -68
- package/assets/my-tag.css +6 -2
- package/dist/MC.d.ts +3 -4
- package/dist/MC.d.ts.map +1 -1
- package/dist/MC.min.js +89 -66
- package/dist/MC.ts +213 -178
- package/dist/autoloader.ts +1 -1
- package/dist/{customElements.d.ts → elements.d.ts} +1 -1
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.min.js +1 -0
- package/dist/{customElements.ts → elements.ts} +23 -14
- package/dist/helpers.d.ts +6 -4
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.ts +95 -128
- package/dist/microcomponents.d.ts +3 -3
- package/dist/microcomponents.d.ts.map +1 -1
- package/dist/microcomponents.min.js +1 -1
- package/dist/microcomponents.ts +3 -3
- package/dist/{customObservables.d.ts → observables.d.ts} +3 -3
- package/dist/observables.d.ts.map +1 -0
- package/dist/observables.min.js +1 -0
- package/dist/observables.ts +353 -0
- package/dist/{customSelectors.d.ts → selectors.d.ts} +1 -1
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.min.js +1 -0
- package/dist/test.ts +135 -156
- package/klemmstein.png +0 -0
- package/package.json +52 -52
- package/public/MC.js +90 -67
- package/public/MC.js.map +1 -1
- package/public/MC.min.js +89 -66
- package/public/assets/search.js +1 -1
- package/public/autoloader.js +1 -1
- package/public/autoloader.js.map +1 -1
- package/public/classes/{DC.html → MC.DC.html} +60 -59
- package/public/classes/{MC.html → MC.MC.html} +41 -35
- package/public/classes/{McBase.html → MC.McBase.html} +28 -20
- package/public/classes/{McEvent.html → MC.McEvent.html} +48 -42
- package/public/documentation/{MicroComponents.md → MC.md} +17 -17
- package/public/documentation/comparision.md +0 -0
- package/public/documentation/elements.md +276 -0
- package/public/documentation/magic.md +10 -68
- package/public/{customElements.js → elements.js} +9 -10
- package/public/elements.js.map +1 -0
- package/public/elements.min.js +1 -0
- package/public/functions/{addListener.html → MC.addListener.html} +18 -12
- package/public/functions/{removeListener.html → MC.removeListener.html} +18 -12
- package/public/functions/elements.defineCE.html +78 -0
- package/public/functions/elements.getCE.html +63 -0
- package/public/functions/formValues.formValues.html +68 -0
- package/public/functions/observables.observe.html +65 -0
- package/public/functions/selectors._d.html +69 -0
- package/public/functions/selectors._t.html +69 -0
- package/public/helpers.js +66 -89
- package/public/helpers.js.map +1 -1
- package/public/index.html +48 -33
- package/public/interfaces/{HTMLMcElement.html → MC.HTMLMcElement.html} +601 -595
- package/public/interfaces/selectors.DSelector.html +1013 -0
- package/public/interfaces/selectors.TSelector.html +712 -0
- package/public/microcomponents.js +3 -3
- package/public/microcomponents.js.map +1 -1
- package/public/microcomponents.min.js +1 -1
- package/public/modules/MC.html +78 -0
- package/public/modules/elements.html +62 -0
- package/public/modules/formValues.html +60 -0
- package/public/modules/observables.html +65 -0
- package/public/modules/selectors.html +76 -0
- package/public/modules.html +11 -23
- package/public/my-tag.css +6 -2
- package/public/observables.js +259 -0
- package/public/observables.js.map +1 -0
- package/public/observables.min.js +1 -0
- package/public/{customSelectors.js → selectors.js} +1 -1
- package/public/selectors.js.map +1 -0
- package/public/selectors.min.js +1 -0
- package/public/src/MC.ts +413 -0
- package/public/src/McEvent.ts +96 -0
- package/public/src/autoloader.ts +98 -0
- package/{src/customElements.ts → public/src/elements.ts} +23 -14
- package/public/src/formValues.ts +275 -0
- package/public/src/helpers.ts +140 -0
- package/public/src/microcomponents.ts +8 -0
- package/public/src/observables.ts +353 -0
- package/public/src/test.ts +190 -0
- package/public/test.js +93 -118
- package/public/test.js.map +1 -1
- package/public/types/observables.Observable.html +91 -0
- package/public/types/selectors.selection.html +58 -0
- package/public/types/selectors.singleSelector.html +58 -0
- package/src/MC.ts +213 -178
- package/src/autoloader.ts +1 -1
- package/src/elements.ts +76 -0
- package/src/helpers.ts +95 -128
- package/src/microcomponents.ts +3 -3
- package/src/observables.ts +353 -0
- package/src/selectors.ts +1634 -0
- package/src/test.ts +135 -156
- package/typedoc.json +1 -1
- package/webpack.config.js +9 -9
- package/dist/customElements.d.ts.map +0 -1
- package/dist/customElements.min.js +0 -1
- package/dist/customObservables.d.ts.map +0 -1
- package/dist/customObservables.min.js +0 -1
- package/dist/customObservables.ts +0 -348
- package/dist/customSelectors.d.ts.map +0 -1
- package/dist/customSelectors.min.js +0 -1
- package/public/customElements.js.map +0 -1
- package/public/customElements.min.js +0 -1
- package/public/customObservables.js +0 -256
- package/public/customObservables.js.map +0 -1
- package/public/customObservables.min.js +0 -1
- package/public/customSelectors.js.map +0 -1
- package/public/customSelectors.min.js +0 -1
- package/src/customObservables.ts +0 -348
- /package/dist/{customSelectors.ts → selectors.ts} +0 -0
- /package/{src/customSelectors.ts → public/src/selectors.ts} +0 -0
package/src/MC.ts
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
|
|
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(
|
|
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 (
|
|
12
|
-
Object.keys(
|
|
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(
|
|
24
|
+
function getMicroComponents(elements: any[], search: string): any[] {
|
|
21
25
|
let mcValues: any[] = [];
|
|
22
26
|
|
|
23
|
-
elements.forEach(
|
|
27
|
+
elements.forEach((e) => {
|
|
24
28
|
if (e) {
|
|
25
29
|
if (e instanceof HTMLElement) {
|
|
26
|
-
const _mc = (
|
|
27
|
-
if (
|
|
28
|
-
mcValues = mcValues.concat(Object.values((
|
|
29
|
-
}
|
|
30
|
-
|
|
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(
|
|
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(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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 (
|
|
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(
|
|
84
|
+
domNode.addEventListener(eventName, handler, options);
|
|
77
85
|
}
|
|
78
86
|
|
|
79
|
-
function removeListener(
|
|
80
|
-
domNode
|
|
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(
|
|
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
|
-
(
|
|
92
|
-
node._mc = new (
|
|
93
|
-
(
|
|
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 (
|
|
111
|
+
if (key.length && !_mc[key]) {
|
|
101
112
|
_mc[key] = element;
|
|
102
113
|
// add attribute if HTMLElement
|
|
103
|
-
if (
|
|
114
|
+
if (target instanceof HTMLElement) {
|
|
104
115
|
target.setAttribute('_mc', '');
|
|
105
116
|
}
|
|
106
117
|
}
|
|
@@ -108,239 +119,264 @@ function add( target: HTMLElement, key: string, element = {} ): any {
|
|
|
108
119
|
}
|
|
109
120
|
|
|
110
121
|
// remove a micro component from the DOM
|
|
111
|
-
function remove(
|
|
112
|
-
if (
|
|
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 (
|
|
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 (
|
|
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(
|
|
144
|
+
function trigger(
|
|
145
|
+
target: HTMLElement,
|
|
146
|
+
ev: McEvent | string,
|
|
147
|
+
data: any = {},
|
|
148
|
+
bubble: string = 'l'
|
|
149
|
+
) {
|
|
130
150
|
let _mc = (target as any)?._mc;
|
|
131
|
-
if (
|
|
132
|
-
|
|
151
|
+
if (!_mc) return;
|
|
152
|
+
|
|
153
|
+
let event =
|
|
154
|
+
ev instanceof McEvent
|
|
155
|
+
? new McEvent(ev.type, ev.data, 'l')
|
|
156
|
+
: new McEvent(ev, data, 'l'),
|
|
157
|
+
mcEvent: McEvent =
|
|
158
|
+
typeof ev !== 'string' ? (ev as McEvent) : new McEvent(ev, data, bubble);
|
|
159
|
+
|
|
160
|
+
[...Object.values(_mc)].forEach((mc: any) => {
|
|
133
161
|
//console.log( 'mc [', mc.constructor.name, ']', mc.constructor.prototype?.oneInit );
|
|
134
|
-
if (
|
|
135
|
-
(mc as any)?.trigger(
|
|
162
|
+
if ((mc as any)?.trigger && typeof (mc as any)?.trigger === 'function') {
|
|
163
|
+
(mc as any)?.trigger(event);
|
|
136
164
|
}
|
|
137
165
|
});
|
|
166
|
+
|
|
167
|
+
if (/[ud]/.test(mcEvent.bubble)) {
|
|
168
|
+
bubbleEvent(target, mcEvent);
|
|
169
|
+
}
|
|
170
|
+
|
|
138
171
|
return;
|
|
139
172
|
}
|
|
140
173
|
|
|
141
|
-
// run the "init" lifecycle event on the
|
|
142
|
-
function init(
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
setTimeout(
|
|
146
|
-
()
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
, 0
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
, 0
|
|
166
|
-
);
|
|
167
|
-
|
|
174
|
+
// run the "init" lifecycle event on the complete _mc structure
|
|
175
|
+
function init(element: MC | DC) {
|
|
176
|
+
if (element.constructor === DC) return;
|
|
177
|
+
|
|
178
|
+
setTimeout(() => {
|
|
179
|
+
element.trigger('Init');
|
|
180
|
+
/*
|
|
181
|
+
let keys = Object.keys( ( element as any)?._mc );
|
|
182
|
+
if ( keys.length ){
|
|
183
|
+
//console.log( 'inner Inits on [', mc.constructor.name, ']', keys );
|
|
184
|
+
keys?.forEach( (key: string) => {
|
|
185
|
+
let mc = ( element as any)?._mc?.[key];
|
|
186
|
+
//console.log( key, typeof mc?.oneInit, mc );
|
|
187
|
+
if ( ( mc as any )['oneInit'] && typeof ( mc as any ).oneInit == 'function' ){
|
|
188
|
+
( mc as any ).oneInit( new McEvent('Init') );
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
*/
|
|
193
|
+
}, 0);
|
|
168
194
|
}
|
|
169
195
|
|
|
170
|
-
function autoAttachListeners(
|
|
171
|
-
if (
|
|
196
|
+
function autoAttachListeners(element: MC | DC) {
|
|
197
|
+
if (!isBrowser() || element.constructor === DC) return;
|
|
172
198
|
|
|
173
199
|
const target = element.target;
|
|
174
200
|
|
|
175
|
-
if (
|
|
201
|
+
if (target instanceof HTMLElement) {
|
|
176
202
|
let that: LooseObject = element;
|
|
177
|
-
Object
|
|
178
|
-
.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
203
|
+
Object.getOwnPropertyNames(that.constructor.prototype)
|
|
204
|
+
.filter(
|
|
205
|
+
(key) =>
|
|
206
|
+
/^on[A-Z]|one[A-Z]/.test(key) &&
|
|
207
|
+
typeof that.constructor.prototype[key] === 'function'
|
|
208
|
+
)
|
|
209
|
+
.forEach((key) => {
|
|
210
|
+
let once = /^one/.test(key),
|
|
211
|
+
withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
|
|
184
212
|
nativeEventName = withoutOnOne.toLowerCase(),
|
|
185
|
-
listener = (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (
|
|
213
|
+
listener = (ev: McEvent | Event | CustomEvent) => {
|
|
214
|
+
that.trigger(withoutOnOne, ev);
|
|
215
|
+
};
|
|
216
|
+
if (once) {
|
|
189
217
|
// console.log( '...is only called once', that.constructor.prototype[key] );
|
|
190
|
-
Object.defineProperty(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
( that.constructor.prototype[key] ).bind(that)(ev);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
);
|
|
218
|
+
Object.defineProperty(element, 'on' + withoutOnOne, {
|
|
219
|
+
configurable: true,
|
|
220
|
+
enumerable: false,
|
|
221
|
+
writable: true,
|
|
222
|
+
value: (ev: any) => {
|
|
223
|
+
// console.log( 'onceHandler execute:', that.constructor.prototype[key] );
|
|
224
|
+
that.constructor.prototype[key].bind(that)(ev);
|
|
225
|
+
},
|
|
226
|
+
});
|
|
203
227
|
}
|
|
204
228
|
|
|
205
|
-
if (
|
|
229
|
+
if (nativeEventNames.has('on' + nativeEventName)) {
|
|
230
|
+
// native event defined in HTMLElement
|
|
206
231
|
// console.log('added as native listener', target, nativeEventName );
|
|
207
|
-
addListener(
|
|
232
|
+
addListener(target, nativeEventName, listener, false, once);
|
|
208
233
|
}
|
|
209
234
|
});
|
|
210
235
|
}
|
|
211
236
|
}
|
|
212
237
|
|
|
213
|
-
|
|
238
|
+
function bubbleEvent(target: HTMLElement, ev: McEvent) {
|
|
239
|
+
// at this point, either 'u' or 'd' bubbling should be indicated
|
|
240
|
+
// mcEvent bubbling is asynchronous, and the order of target MC execution in case of multiple matches is not guaranteed!
|
|
241
|
+
if (/[ud]/.test(ev.bubble)) {
|
|
242
|
+
setTimeout(() => {
|
|
243
|
+
// bubbling must include 'l' for local, or else no handlers are executed'
|
|
244
|
+
if (ev.bubble.indexOf('l') === -1) {
|
|
245
|
+
ev.bubble += 'l';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// bubble up towards root
|
|
249
|
+
if (ev.bubble.indexOf('u') > -1) {
|
|
250
|
+
let parent = traverseNodes(target, '', true)?.[0].target;
|
|
251
|
+
if (parent) DC.trigger(parent, ev);
|
|
252
|
+
}
|
|
214
253
|
|
|
254
|
+
// bubble down
|
|
255
|
+
if (ev.bubble.indexOf('d') > -1) {
|
|
256
|
+
let targets = new Set<HTMLMcElement>(
|
|
257
|
+
(target as HTMLMcElement)._mc
|
|
258
|
+
.children()
|
|
259
|
+
.map((c: unknown) => (c as any)?.target)
|
|
260
|
+
);
|
|
261
|
+
targets.forEach((target: HTMLMcElement) => {
|
|
262
|
+
if (target) DC.trigger(target, ev);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}, 0);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
class McBase {
|
|
215
270
|
#target: WeakRef<any>; // avoid circular reference
|
|
216
271
|
|
|
217
|
-
constructor(
|
|
272
|
+
constructor(target?: { [key: string]: any }, debug: boolean = false) {
|
|
218
273
|
let that: unknown = this,
|
|
219
|
-
element
|
|
274
|
+
element = that as MC | DC;
|
|
220
275
|
|
|
221
|
-
this.#target = new WeakRef(
|
|
276
|
+
this.#target = new WeakRef(target || {});
|
|
222
277
|
|
|
223
|
-
init(
|
|
278
|
+
init(element); // async lifecycle event
|
|
224
279
|
|
|
225
|
-
autoAttachListeners(
|
|
280
|
+
autoAttachListeners(element);
|
|
226
281
|
}
|
|
227
282
|
|
|
228
283
|
get target(): any {
|
|
229
284
|
return this.#target.deref();
|
|
230
285
|
}
|
|
231
|
-
|
|
232
286
|
}
|
|
233
287
|
|
|
234
288
|
class MC extends McBase {
|
|
235
|
-
|
|
236
|
-
_mc: { [key:string]: any } = {};
|
|
289
|
+
_mc: { [key: string]: any } = {};
|
|
237
290
|
|
|
238
291
|
constructor(target?: any) {
|
|
239
292
|
super(target);
|
|
240
293
|
}
|
|
241
294
|
|
|
242
|
-
|
|
295
|
+
static trigger = trigger;
|
|
243
296
|
|
|
244
|
-
trigger(
|
|
297
|
+
trigger(ev: McEvent | string, data: any = {}, bubble: string = 'l') {
|
|
245
298
|
let that = this;
|
|
246
299
|
|
|
247
300
|
//console.log( that, '.trigger(', ev, data, bubble, ')' );
|
|
248
|
-
bubble = bubble || 'l';
|
|
249
301
|
|
|
250
302
|
// run all triggers
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
303
|
+
if (that.constructor === MC || that.constructor === DC) {
|
|
304
|
+
let event =
|
|
305
|
+
ev instanceof McEvent
|
|
306
|
+
? new McEvent(ev.type, ev.data, 'l')
|
|
307
|
+
: new McEvent(ev, data, 'l'),
|
|
308
|
+
mcEvent: McEvent =
|
|
309
|
+
typeof ev !== 'string'
|
|
310
|
+
? (ev as McEvent)
|
|
311
|
+
: new McEvent(ev, data, bubble);
|
|
312
|
+
[...Object.getOwnPropertyNames(that)].forEach((mc) => {
|
|
313
|
+
if (
|
|
314
|
+
(that as any)[mc]?.trigger &&
|
|
315
|
+
typeof (that as any)[mc]?.trigger === 'function'
|
|
316
|
+
) {
|
|
317
|
+
(that as any)[mc]?.trigger(event);
|
|
255
318
|
}
|
|
256
319
|
});
|
|
320
|
+
|
|
321
|
+
if (/[ud]/.test(mcEvent.bubble)) {
|
|
322
|
+
bubbleEvent(that.target, mcEvent);
|
|
323
|
+
}
|
|
324
|
+
|
|
257
325
|
return; // must return here!
|
|
258
326
|
}
|
|
259
327
|
|
|
260
328
|
// only this instance
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
329
|
+
if ((that as any) instanceof MC || (that as any) instanceof DC) {
|
|
330
|
+
const that = this,
|
|
331
|
+
mcEvent: McEvent =
|
|
332
|
+
typeof ev !== 'string'
|
|
333
|
+
? (ev as McEvent)
|
|
334
|
+
: new McEvent(ev, data, bubble),
|
|
335
|
+
handlerName =
|
|
336
|
+
'on' + mcEvent.type[0].toUpperCase() + mcEvent.type.slice(1);
|
|
269
337
|
// console.log('trigger', handlerName, mcEvent, data, bubble );
|
|
270
338
|
|
|
271
|
-
if (
|
|
272
|
-
if (
|
|
273
|
-
&&
|
|
274
|
-
|
|
339
|
+
if (mcEvent.bubble.indexOf('l') > -1) {
|
|
340
|
+
if (
|
|
341
|
+
!mcEvent.immediateStopped &&
|
|
342
|
+
typeof (that as any)[handlerName] === 'function'
|
|
343
|
+
) {
|
|
275
344
|
// console.log( 'execute handler:', handlerName );
|
|
276
|
-
(
|
|
277
|
-
if (
|
|
278
|
-
|
|
345
|
+
(that as any)[handlerName](mcEvent);
|
|
346
|
+
if ((that as any).hasOwnProperty(handlerName)) {
|
|
347
|
+
// it is a once handler
|
|
348
|
+
delete (that as any)[handlerName]; // remove after first execution
|
|
279
349
|
}
|
|
280
350
|
}
|
|
281
351
|
}
|
|
282
352
|
|
|
283
353
|
// if event stopped or local only, handling is cancelled
|
|
284
|
-
if (
|
|
354
|
+
if (mcEvent.stopped || mcEvent.bubble === 'l') {
|
|
285
355
|
return that;
|
|
286
356
|
}
|
|
287
357
|
|
|
288
|
-
//
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
);
|
|
358
|
+
//console.log('bubble', mcEvent);
|
|
359
|
+
if (/[ud]/.test(mcEvent.bubble)) {
|
|
360
|
+
bubbleEvent(that.target, mcEvent);
|
|
319
361
|
}
|
|
320
|
-
|
|
321
362
|
}
|
|
322
|
-
|
|
323
363
|
}
|
|
324
|
-
|
|
325
|
-
};
|
|
364
|
+
}
|
|
326
365
|
|
|
327
366
|
class DC extends McBase {
|
|
367
|
+
_mc: { [key: string]: any } = {};
|
|
328
368
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
constructor(target: HTMLElement ) {
|
|
369
|
+
constructor(target: HTMLElement, debug: boolean = false) {
|
|
332
370
|
super(target);
|
|
333
371
|
}
|
|
334
372
|
|
|
335
|
-
static debug: boolean = false;
|
|
336
|
-
|
|
337
373
|
static add: Function = add;
|
|
338
374
|
static remove: Function = remove;
|
|
339
375
|
static trigger: Function = trigger;
|
|
340
376
|
|
|
341
|
-
trigger(
|
|
342
|
-
MC.prototype.trigger.call(
|
|
343
|
-
}
|
|
377
|
+
trigger(ev: McEvent | string, data: any = {}, bubble?: string) {
|
|
378
|
+
MC.prototype.trigger.call(this, ev, data, bubble);
|
|
379
|
+
}
|
|
344
380
|
|
|
345
381
|
parent(search: string = ''): any[] {
|
|
346
382
|
let target: HTMLElement = (this as any).target;
|
|
@@ -372,7 +408,6 @@ class DC extends McBase {
|
|
|
372
408
|
const myDomElements = target.querySelectorAll('*[_mc]');
|
|
373
409
|
return getMicroComponents([...myDomElements], search);
|
|
374
410
|
}
|
|
375
|
-
|
|
376
|
-
};
|
|
411
|
+
}
|
|
377
412
|
|
|
378
413
|
export { addListener, removeListener, McBase, MC, DC, McEvent };
|
package/src/autoloader.ts
CHANGED
package/src/elements.ts
ADDED
|
@@ -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
|
+
}
|