@twobirds/microcomponents 0.0.83 → 0.0.85
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 +22 -6
- package/assets/documentation/MC.md +60 -81
- package/assets/documentation/elements.md +6 -9
- package/assets/documentation/observables.md +97 -11
- package/assets/test/test.html +1 -1
- package/dist/MC.d.ts +14 -16
- package/dist/MC.d.ts.map +1 -1
- package/dist/MC.js +150 -218
- package/dist/MC.min.js +164 -308
- package/dist/MC.ts +213 -319
- package/dist/elements.d.ts.map +1 -1
- package/dist/elements.js +10 -4
- package/dist/elements.min.js +1 -1
- package/dist/elements.ts +17 -4
- package/dist/formValues.js +2 -2
- package/dist/formValues.min.js +1 -1
- package/dist/formValues.ts +3 -3
- package/dist/microcomponents.d.ts +0 -1
- package/dist/microcomponents.d.ts.map +1 -1
- package/dist/microcomponents.js +0 -1
- package/dist/microcomponents.min.js +1 -1
- package/dist/microcomponents.ts +1 -1
- package/dist/observables.d.ts.map +1 -1
- package/dist/observables.js +14 -12
- package/dist/observables.min.js +1 -1
- package/dist/observables.ts +32 -32
- package/package.json +1 -1
- package/public/MC.d.ts +14 -16
- package/public/MC.d.ts.map +1 -1
- package/public/MC.js +150 -218
- package/public/MC.js.map +1 -1
- package/public/MC.min.js +164 -308
- package/public/MC.ts +213 -319
- package/public/documentation/MC.md +60 -81
- package/public/documentation/elements.md +6 -9
- package/public/documentation/observables.md +97 -11
- package/public/elements.d.ts.map +1 -1
- package/public/elements.js +10 -4
- package/public/elements.js.map +1 -1
- package/public/elements.min.js +1 -1
- package/public/elements.ts +17 -4
- package/public/formValues.js +2 -2
- package/public/formValues.js.map +1 -1
- package/public/formValues.min.js +1 -1
- package/public/formValues.ts +3 -3
- package/public/microcomponents.d.ts +0 -1
- package/public/microcomponents.d.ts.map +1 -1
- package/public/microcomponents.js +0 -1
- package/public/microcomponents.js.map +1 -1
- package/public/microcomponents.min.js +1 -1
- package/public/microcomponents.ts +1 -1
- package/public/observables.d.ts.map +1 -1
- package/public/observables.js +14 -12
- package/public/observables.js.map +1 -1
- package/public/observables.min.js +1 -1
- package/public/observables.ts +32 -32
- package/public/src/MC.d.ts +14 -16
- package/public/src/MC.d.ts.map +1 -1
- package/public/src/MC.js +150 -218
- package/public/src/MC.js.map +1 -1
- package/public/src/MC.ts +213 -319
- package/public/src/elements.d.ts.map +1 -1
- package/public/src/elements.js +10 -4
- package/public/src/elements.js.map +1 -1
- package/public/src/elements.ts +17 -4
- package/public/src/formValues.js +2 -2
- package/public/src/formValues.js.map +1 -1
- package/public/src/formValues.ts +3 -3
- package/public/src/microcomponents.d.ts +0 -1
- package/public/src/microcomponents.d.ts.map +1 -1
- package/public/src/microcomponents.js +0 -1
- package/public/src/microcomponents.js.map +1 -1
- package/public/src/microcomponents.ts +1 -1
- package/public/src/observables.d.ts.map +1 -1
- package/public/src/observables.js +14 -12
- package/public/src/observables.js.map +1 -1
- package/public/src/observables.ts +32 -32
- package/public/src/test/test/grandparent.d.ts.map +1 -1
- package/public/src/test/test/grandparent.js +1 -1
- package/public/src/test/test/grandparent.js.map +1 -1
- package/public/src/test/test/grandparent.ts +12 -4
- package/public/src/test/test/testform.js +1 -1
- package/public/src/test/test/testform.js.map +1 -1
- package/public/src/test/test/testform.ts +6 -8
- package/public/src/test/test.js +6 -5
- package/public/src/test/test.js.map +1 -1
- package/public/src/test/test.ts +10 -9
- package/public/test/MC.d.ts +14 -16
- package/public/test/MC.d.ts.map +1 -1
- package/public/test/MC.js +150 -218
- package/public/test/MC.min.js +164 -308
- package/public/test/MC.ts +213 -319
- package/public/test/elements.d.ts.map +1 -1
- package/public/test/elements.js +10 -4
- package/public/test/elements.min.js +1 -1
- package/public/test/elements.ts +17 -4
- package/public/test/formValues.js +2 -2
- package/public/test/formValues.min.js +1 -1
- package/public/test/formValues.ts +3 -3
- package/public/test/microcomponents.d.ts +0 -1
- package/public/test/microcomponents.d.ts.map +1 -1
- package/public/test/microcomponents.js +0 -1
- package/public/test/microcomponents.min.js +1 -1
- package/public/test/microcomponents.ts +1 -1
- package/public/test/observables.d.ts.map +1 -1
- package/public/test/observables.js +14 -12
- package/public/test/observables.min.js +1 -1
- package/public/test/observables.ts +32 -32
- package/public/test/test/grandparent.d.ts.map +1 -1
- package/public/test/test/grandparent.js +1 -1
- package/public/test/test/grandparent.js.map +1 -1
- package/public/test/test/grandparent.ts +12 -4
- package/public/test/test/testform.js +1 -1
- package/public/test/test/testform.js.map +1 -1
- package/public/test/test/testform.ts +6 -8
- package/public/test/test.html +1 -1
- package/public/test/test.js +6 -5
- package/public/test/test.js.map +1 -1
- package/public/test/test.ts +10 -9
- package/public/typedoc/assets/navigation.js +1 -1
- package/public/typedoc/assets/search.js +1 -1
- package/public/typedoc/classes/MC.DC.html +7 -6
- package/public/typedoc/classes/MC.MC.html +3 -6
- package/public/typedoc/classes/MC.McBase.html +3 -4
- package/public/typedoc/functions/MC.autoload.html +1 -1
- package/public/typedoc/functions/MC.off.html +1 -0
- package/public/typedoc/functions/{selectors._d.html → MC.on.html} +1 -1
- package/public/typedoc/functions/MC.one.html +1 -0
- package/public/typedoc/functions/MC.trigger.html +1 -0
- package/public/typedoc/functions/elements.defineCE.html +1 -1
- package/public/typedoc/functions/elements.getCE.html +1 -1
- package/public/typedoc/functions/formValues.formValues.html +1 -1
- package/public/typedoc/functions/observables.observe.html +1 -1
- package/public/typedoc/index.html +21 -10
- package/public/typedoc/interfaces/MC.HTMLMcElement.html +2 -2
- package/public/typedoc/modules/MC.html +6 -5
- package/public/typedoc/modules/elements.html +1 -1
- package/public/typedoc/modules/formValues.html +1 -1
- package/public/typedoc/modules/observables.html +1 -1
- package/public/typedoc/modules.html +0 -1
- package/public/typedoc/types/observables.Observable.html +1 -1
- package/src/MC.ts +213 -319
- package/src/elements.ts +17 -4
- package/src/formValues.ts +3 -3
- package/src/microcomponents.ts +1 -1
- package/src/observables.ts +32 -32
- package/src/test/test/grandparent.ts +12 -4
- package/src/test/test/testform.ts +6 -8
- package/src/test/test.ts +10 -9
- package/tsconfig.json +2 -2
- package/typedoc.json +1 -1
- package/webpack.config.js +2 -2
- package/dist/McEvent.d.ts +0 -15
- package/dist/McEvent.d.ts.map +0 -1
- package/dist/McEvent.js +0 -71
- package/dist/selectors.d.ts +0 -106
- package/dist/selectors.d.ts.map +0 -1
- package/dist/selectors.js +0 -759
- package/dist/selectors.min.js +0 -1
- package/public/McEvent.d.ts +0 -15
- package/public/McEvent.d.ts.map +0 -1
- package/public/McEvent.js +0 -71
- package/public/McEvent.js.map +0 -1
- package/public/selectors.d.ts +0 -106
- package/public/selectors.d.ts.map +0 -1
- package/public/selectors.js +0 -759
- package/public/selectors.js.map +0 -1
- package/public/selectors.min.js +0 -1
- package/public/src/McEvent.d.ts +0 -15
- package/public/src/McEvent.d.ts.map +0 -1
- package/public/src/McEvent.js +0 -71
- package/public/src/McEvent.js.map +0 -1
- package/public/src/selectors.d.ts +0 -106
- package/public/src/selectors.d.ts.map +0 -1
- package/public/src/selectors.js +0 -759
- package/public/src/selectors.js.map +0 -1
- package/public/test/McEvent.d.ts +0 -15
- package/public/test/McEvent.d.ts.map +0 -1
- package/public/test/McEvent.js +0 -71
- package/public/test/McEvent.ts +0 -96
- package/public/test/selectors.d.ts +0 -106
- package/public/test/selectors.d.ts.map +0 -1
- package/public/test/selectors.js +0 -759
- package/public/test/selectors.min.js +0 -1
- package/public/test/selectors.ts +0 -1269
- package/public/typedoc/classes/MC.McEvent.html +0 -9
- package/public/typedoc/functions/MC.addListener.html +0 -1
- package/public/typedoc/functions/MC.removeListener.html +0 -1
- package/public/typedoc/functions/selectors._t.html +0 -1
- package/public/typedoc/interfaces/selectors.DSelector.html +0 -48
- package/public/typedoc/interfaces/selectors.TSelector.html +0 -34
- package/public/typedoc/modules/selectors.html +0 -7
- package/public/typedoc/types/selectors.selection.html +0 -1
- package/public/typedoc/types/selectors.singleSelector.html +0 -1
- package/src/McEvent.ts +0 -96
- package/src/selectors.ts +0 -1269
- /package/{dist/McEvent.ts → public/McEvent._ts} +0 -0
- /package/{dist/selectors.ts → public/selectors._ts} +0 -0
- /package/public/{McEvent.ts → src/McEvent._ts} +0 -0
- /package/public/{selectors.ts → src/selectors._ts} +0 -0
- /package/{public/src/McEvent.ts → src/McEvent._ts} +0 -0
- /package/{public/src/selectors.ts → src/selectors._ts} +0 -0
package/dist/MC.ts
CHANGED
|
@@ -1,108 +1,37 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import { LooseObject } from './helpers.js';
|
|
4
|
-
import { McEvent } from './McEvent.js';
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
const isBrowser = new Function(
|
|
7
6
|
'try {return this===window;}catch(e){ return false;}'
|
|
8
7
|
);
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (isBrowser()) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
// get HTMLElement native event names
|
|
10
|
+
function getNativeEventNames( domNode: HTMLElement ): string[] {
|
|
11
|
+
let nativeEventNames: Array<string> = [];
|
|
12
|
+
if (isBrowser()) {
|
|
13
|
+
Object.keys(HTMLElement.prototype)
|
|
14
|
+
.filter((key) => /^on/.test(key))
|
|
15
|
+
.forEach((eventName) => nativeEventNames.push(eventName));
|
|
16
|
+
}
|
|
17
|
+
return nativeEventNames;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export interface HTMLMcElement extends HTMLElement {
|
|
20
21
|
_mc: LooseObject;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
// get all microcomponents from a list of HTMLElements
|
|
24
|
-
function getMicroComponents(elements: any[], search: string): any[] {
|
|
25
|
-
let mcValues: any[] = [];
|
|
26
|
-
|
|
27
|
-
elements.forEach((e) => {
|
|
28
|
-
if (e) {
|
|
29
|
-
if (e instanceof HTMLElement) {
|
|
30
|
-
const _mc = (e as any)?._mc;
|
|
31
|
-
if (!search && _mc) {
|
|
32
|
-
mcValues = mcValues.concat(Object.values((e as any)._mc));
|
|
33
|
-
} else if (search && _mc && _mc[search]) {
|
|
34
|
-
mcValues.push(_mc[search]);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
return mcValues;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// get all ancestor DOM nodes up to the document root
|
|
43
|
-
function traverseNodes(
|
|
44
|
-
node: { [key: string]: any },
|
|
45
|
-
search: string,
|
|
46
|
-
firstonly = true
|
|
47
|
-
): any[] {
|
|
48
|
-
let mcValues: any[] = [];
|
|
49
|
-
while (node) {
|
|
50
|
-
if (node._mc) {
|
|
51
|
-
if (!search) {
|
|
52
|
-
mcValues = mcValues.concat(Object.values(node._mc));
|
|
53
|
-
} else if (search && node._mc[search]) {
|
|
54
|
-
mcValues.push(node._mc[search]);
|
|
55
|
-
}
|
|
56
|
-
if (firstonly) return mcValues;
|
|
57
|
-
}
|
|
58
|
-
node = node.parentNode;
|
|
59
|
-
}
|
|
60
|
-
return mcValues;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
24
|
function isDOM(element: { [key: string]: any }) {
|
|
64
25
|
return element && element instanceof HTMLElement;
|
|
65
26
|
}
|
|
66
27
|
|
|
67
|
-
function addListener(
|
|
68
|
-
domNode: Node,
|
|
69
|
-
eventName: string,
|
|
70
|
-
handler: EventListenerOrEventListenerObject | null,
|
|
71
|
-
capture: boolean = false,
|
|
72
|
-
once: boolean = false
|
|
73
|
-
) {
|
|
74
|
-
let options: EventListenerOptions & { once: boolean } = { once: false };
|
|
75
|
-
if (capture) {
|
|
76
|
-
options.capture = capture;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (once) {
|
|
80
|
-
options.once = once;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
//console.log( 'addEventListener', eventName, ( handler as Function ).name, options );
|
|
84
|
-
domNode.addEventListener(eventName, handler, options);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function removeListener(
|
|
88
|
-
domNode: Node,
|
|
89
|
-
eventName: string,
|
|
90
|
-
handler: EventListenerOrEventListenerObject | null
|
|
91
|
-
) {
|
|
92
|
-
domNode.removeEventListener(eventName, handler);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
28
|
// add a microcomponent to a target DOM node
|
|
96
|
-
function add(target: HTMLElement, key: string, element = {}):
|
|
29
|
+
function add( target: HTMLElement, key: string, element: any = {} ): HTMLMcElement {
|
|
97
30
|
let node = target as HTMLMcElement;
|
|
98
31
|
|
|
99
32
|
// create the _mc property if necessary
|
|
100
33
|
if (!node._mc) {
|
|
101
|
-
let debug = (DC as any)?.debug;
|
|
102
|
-
(DC as any).debug = false;
|
|
103
34
|
node._mc = new (DC as any)(target);
|
|
104
|
-
(DC as any).debug = debug;
|
|
105
|
-
delete node._mc._mc; // NOT NEEDED on the top level _mc property of a DOM HTMLElement
|
|
106
35
|
}
|
|
107
36
|
|
|
108
37
|
const _mc = node._mc;
|
|
@@ -111,11 +40,12 @@ function add(target: HTMLElement, key: string, element = {}): any {
|
|
|
111
40
|
if (key.length && !_mc[key]) {
|
|
112
41
|
_mc[key] = element;
|
|
113
42
|
// add attribute if HTMLElement
|
|
114
|
-
if (target instanceof HTMLElement && ! target.getAttribute('
|
|
115
|
-
target.setAttribute('
|
|
43
|
+
if (target instanceof HTMLElement && ! target.getAttribute('data-mc') ) {
|
|
44
|
+
target.setAttribute('data-mc', '');
|
|
116
45
|
}
|
|
117
46
|
}
|
|
118
|
-
|
|
47
|
+
|
|
48
|
+
return node;
|
|
119
49
|
}
|
|
120
50
|
|
|
121
51
|
// remove a micro component from the DOM
|
|
@@ -133,63 +63,90 @@ function remove(target: HTMLMcElement, key: string) {
|
|
|
133
63
|
if (
|
|
134
64
|
!Object.keys(_mc).length &&
|
|
135
65
|
target instanceof HTMLElement &&
|
|
136
|
-
target.hasAttribute('
|
|
66
|
+
target.hasAttribute('data-mc')
|
|
137
67
|
) {
|
|
138
|
-
target.removeAttribute('
|
|
68
|
+
target.removeAttribute('data-mc');
|
|
139
69
|
}
|
|
140
70
|
return;
|
|
141
71
|
}
|
|
142
72
|
|
|
143
|
-
//
|
|
144
|
-
function
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
let _mc = (target as any)?._mc;
|
|
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) => {
|
|
161
|
-
//console.log( 'mc [', mc.constructor.name, ']', mc.constructor.prototype?.oneInit );
|
|
162
|
-
if ((mc as any)?.trigger && typeof (mc as any)?.trigger === 'function') {
|
|
163
|
-
(mc as any)?.trigger(event);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
73
|
+
// run the "init" lifecycle event on the complete _mc structure
|
|
74
|
+
function init(element: DC) {
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
if (element.constructor === DC) return;
|
|
77
|
+
element.trigger('Init');
|
|
78
|
+
}, 0);
|
|
79
|
+
}
|
|
166
80
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
81
|
+
// 'eventName' => '_mcEventName'
|
|
82
|
+
function getMcEventName( eventName: string ): string {
|
|
83
|
+
return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
|
|
84
|
+
}
|
|
170
85
|
|
|
171
|
-
|
|
86
|
+
/*
|
|
87
|
+
CustomEvent Section...
|
|
88
|
+
*/
|
|
89
|
+
function off( domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject ){
|
|
90
|
+
domNode.removeEventListener( getMcEventName(eventName), handler );
|
|
172
91
|
}
|
|
173
92
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
93
|
+
function on( domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject, once: boolean = false ) {
|
|
94
|
+
domNode.addEventListener( getMcEventName(eventName), handler, { capture: false, once });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function one( domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject ) {
|
|
98
|
+
on(domNode, eventName, handler, true );
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// create and dispatch custom event
|
|
102
|
+
function trigger(
|
|
103
|
+
domNode: HTMLElement,
|
|
104
|
+
event: CustomEvent | string,
|
|
105
|
+
data: any = {},
|
|
106
|
+
bubble: string = 'l'
|
|
107
|
+
){
|
|
108
|
+
const ev = typeof event === 'string'
|
|
109
|
+
? new CustomEvent( getMcEventName( event ), { detail: {data, bubble} } )
|
|
110
|
+
: event;
|
|
111
|
+
|
|
112
|
+
// execute locally if 'l' or nothing is given as bubble
|
|
113
|
+
if( bubble.length && bubble.indexOf('l') > -1 ){
|
|
114
|
+
domNode.dispatchEvent( ev );
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// bubble if up or down is indicated
|
|
118
|
+
if( /[u|d]/.test( bubble ) ){
|
|
119
|
+
bubbleEvent( domNode, ev );
|
|
120
|
+
}
|
|
121
|
+
}
|
|
177
122
|
|
|
123
|
+
function bubbleEvent( domNode: HTMLElement, ev: CustomEvent) {
|
|
124
|
+
// at this point, either 'u' or 'd' bubbling should be indicated
|
|
125
|
+
// event bubbling is asynchronous!
|
|
178
126
|
setTimeout(() => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
127
|
+
|
|
128
|
+
// add missing 'l', or else no handlers are executed
|
|
129
|
+
if (ev.detail.bubble.indexOf('l') === -1) {
|
|
130
|
+
ev.detail.bubble += 'l';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// bubble up towards root
|
|
134
|
+
if (ev.detail.bubble.indexOf('u') > -1 ) {
|
|
135
|
+
domNode.closest('[data-mc]')?.dispatchEvent( ev );
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// bubble down
|
|
139
|
+
if (ev.detail.bubble.indexOf('d') > -1) {
|
|
140
|
+
let targets = new Set<HTMLMcElement>(
|
|
141
|
+
(domNode as HTMLMcElement)._mc
|
|
142
|
+
.children()
|
|
143
|
+
.map((c: unknown) => (c as any)?.target)
|
|
144
|
+
);
|
|
145
|
+
targets.forEach((target: HTMLMcElement) => {
|
|
146
|
+
if (target) target._mc.trigger(target, ev);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
193
150
|
}, 0);
|
|
194
151
|
}
|
|
195
152
|
|
|
@@ -209,74 +166,46 @@ function autoAttachListeners(element: MC | DC) {
|
|
|
209
166
|
.forEach((key) => {
|
|
210
167
|
let once = /^one/.test(key),
|
|
211
168
|
withoutOnOne = key.replace(/^on[e]{0,1}/, ''), // preserves upper/lowercase for non-native events
|
|
212
|
-
nativeEventName = withoutOnOne.toLowerCase()
|
|
213
|
-
listener = (ev: McEvent | Event | CustomEvent) => {
|
|
214
|
-
that.trigger(withoutOnOne, ev);
|
|
215
|
-
};
|
|
216
|
-
if (once) {
|
|
217
|
-
// console.log( '...is only called once', that.constructor.prototype[key] );
|
|
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
|
-
});
|
|
227
|
-
}
|
|
169
|
+
nativeEventName = withoutOnOne.toLowerCase(); // lowercase for native event names
|
|
228
170
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
171
|
+
let listener = (ev: Event | CustomEvent) => {
|
|
172
|
+
that[key]( ev );
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if ( !!( target as any )['on' + nativeEventName] ) {
|
|
176
|
+
// it is a native HTML event
|
|
177
|
+
//console.log( 'AAL: attach native event listener', nativeEventName, 'to', target );
|
|
178
|
+
target.addEventListener( nativeEventName, listener);
|
|
179
|
+
} else {
|
|
180
|
+
// it is a customEvent
|
|
181
|
+
//console.log( 'AAL: attach custom event listener', '_mc' + withoutOnOne , 'to key', key, 'in', element );
|
|
182
|
+
on( target, withoutOnOne, listener, once );
|
|
233
183
|
}
|
|
234
184
|
});
|
|
235
185
|
}
|
|
236
186
|
}
|
|
237
187
|
|
|
238
|
-
function
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
}
|
|
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
|
-
}
|
|
188
|
+
function getMcChildNodes(domNode: HTMLElement): DC[] | null {
|
|
189
|
+
const id = Math.random().toString().replace('.', '');
|
|
190
|
+
const selector = '[data-mc]:not([temp_id="' + id + '"] [data-mc] [data-mc])';
|
|
191
|
+
domNode.setAttribute('temp_id', id);
|
|
192
|
+
const mcArray: unknown[] =
|
|
193
|
+
( [ ...domNode.querySelectorAll(selector) ] as HTMLMcElement[])
|
|
194
|
+
.filter( (e) => !!e._mc )
|
|
195
|
+
.map( e => e._mc );
|
|
196
|
+
domNode.removeAttribute('temp_id');
|
|
197
|
+
return mcArray.length ? mcArray as DC[] : null;
|
|
267
198
|
}
|
|
268
199
|
|
|
269
200
|
class McBase {
|
|
270
201
|
private _target: WeakRef<any>; // avoid circular reference
|
|
271
|
-
private __mc: LooseObject = {};
|
|
272
202
|
|
|
273
|
-
constructor(target?: { [key: string]: any }
|
|
274
|
-
let
|
|
275
|
-
element = that as MC | DC;
|
|
203
|
+
constructor(target?: { [key: string]: any } ) {
|
|
204
|
+
let element = this as unknown as MC | DC;
|
|
276
205
|
|
|
277
206
|
this._target = new WeakRef(target || {});
|
|
278
207
|
|
|
279
|
-
init(element); // async lifecycle event
|
|
208
|
+
init(element as DC); // async lifecycle event
|
|
280
209
|
|
|
281
210
|
autoAttachListeners(element);
|
|
282
211
|
}
|
|
@@ -285,85 +214,12 @@ class McBase {
|
|
|
285
214
|
return this._target.deref();
|
|
286
215
|
}
|
|
287
216
|
|
|
288
|
-
get _mc(): any {
|
|
289
|
-
return this.__mc;
|
|
290
|
-
}
|
|
291
217
|
}
|
|
292
218
|
|
|
293
219
|
class MC extends McBase {
|
|
294
220
|
constructor(target?: any) {
|
|
295
221
|
super(target);
|
|
296
222
|
}
|
|
297
|
-
|
|
298
|
-
static trigger = trigger;
|
|
299
|
-
|
|
300
|
-
trigger(ev: McEvent | string, data: any = {}, bubble: string = 'l') {
|
|
301
|
-
let that = this;
|
|
302
|
-
|
|
303
|
-
//console.log( that, '.trigger(', ev, data, bubble, ')' );
|
|
304
|
-
|
|
305
|
-
// run all triggers
|
|
306
|
-
if (that.constructor === MC || that.constructor === DC) {
|
|
307
|
-
let event =
|
|
308
|
-
ev instanceof McEvent
|
|
309
|
-
? new McEvent(ev.type, ev.data, 'l')
|
|
310
|
-
: new McEvent(ev, data, 'l'),
|
|
311
|
-
mcEvent: McEvent =
|
|
312
|
-
typeof ev !== 'string'
|
|
313
|
-
? (ev as McEvent)
|
|
314
|
-
: new McEvent(ev, data, bubble);
|
|
315
|
-
[...Object.getOwnPropertyNames(that)].forEach((mc) => {
|
|
316
|
-
if (
|
|
317
|
-
(that as any)[mc]?.trigger &&
|
|
318
|
-
typeof (that as any)[mc]?.trigger === 'function'
|
|
319
|
-
) {
|
|
320
|
-
(that as any)[mc]?.trigger(event);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
if (/[ud]/.test(mcEvent.bubble)) {
|
|
325
|
-
bubbleEvent(that.target, mcEvent);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return; // must return here!
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// only this instance
|
|
332
|
-
if ((that as any) instanceof MC || (that as any) instanceof DC) {
|
|
333
|
-
const that = this,
|
|
334
|
-
mcEvent: McEvent =
|
|
335
|
-
typeof ev !== 'string'
|
|
336
|
-
? (ev as McEvent)
|
|
337
|
-
: new McEvent(ev, data, bubble),
|
|
338
|
-
handlerName =
|
|
339
|
-
'on' + mcEvent.type[0].toUpperCase() + mcEvent.type.slice(1);
|
|
340
|
-
// console.log('trigger', handlerName, mcEvent, data, bubble );
|
|
341
|
-
|
|
342
|
-
if (mcEvent.bubble.indexOf('l') > -1) {
|
|
343
|
-
if (
|
|
344
|
-
!mcEvent.immediateStopped &&
|
|
345
|
-
typeof (that as any)[handlerName] === 'function'
|
|
346
|
-
) {
|
|
347
|
-
// console.log( 'execute handler:', handlerName );
|
|
348
|
-
(that as any)[handlerName](mcEvent);
|
|
349
|
-
if ((that as any).hasOwnProperty(handlerName)) {
|
|
350
|
-
// it is a once handler
|
|
351
|
-
delete (that as any)[handlerName]; // remove after first execution
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// if event stopped or local only, handling is cancelled
|
|
357
|
-
if (mcEvent.stopped || mcEvent.bubble === 'l') {
|
|
358
|
-
return that;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
//console.log('bubble', mcEvent);
|
|
362
|
-
if (/[ud]/.test(mcEvent.bubble)) {
|
|
363
|
-
bubbleEvent(that.target, mcEvent);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
223
|
}
|
|
368
224
|
|
|
369
225
|
class DC extends McBase {
|
|
@@ -373,69 +229,77 @@ class DC extends McBase {
|
|
|
373
229
|
|
|
374
230
|
static add: Function = add;
|
|
375
231
|
static remove: Function = remove;
|
|
376
|
-
static trigger: Function = trigger;
|
|
377
232
|
|
|
378
|
-
|
|
379
|
-
|
|
233
|
+
/* event handling */
|
|
234
|
+
off( eventName: string, handler: EventListenerOrEventListenerObject ) {
|
|
235
|
+
off( this.target, eventName, handler );
|
|
380
236
|
}
|
|
381
237
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (!isDOM(target)) return [];
|
|
385
|
-
return traverseNodes((target as any).parentNode, search, true);
|
|
238
|
+
on( eventName: string, handler: EventListenerOrEventListenerObject ) {
|
|
239
|
+
on( this.target, eventName, handler );
|
|
386
240
|
}
|
|
387
241
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (!isDOM(target)) return [];
|
|
391
|
-
return traverseNodes((this as any).target.parentNode, search, false);
|
|
242
|
+
one( eventName: string, handler: EventListenerOrEventListenerObject ) {
|
|
243
|
+
one( this.target, eventName, handler );
|
|
392
244
|
}
|
|
393
245
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if (!isDOM(target)) return [];
|
|
397
|
-
const id = Math.random().toString().replace('.', '');
|
|
398
|
-
const selector = '[_mc]:not([temp_id="' + id + '"] [_mc] [_mc])';
|
|
399
|
-
target.setAttribute('temp_id', id);
|
|
400
|
-
const myDomElements = target.querySelectorAll(selector);
|
|
401
|
-
const mcValues = getMicroComponents([...myDomElements], search);
|
|
402
|
-
target.removeAttribute('temp_id');
|
|
403
|
-
return mcValues;
|
|
246
|
+
trigger( eventName: string, data: any = {}, bubble: string = 'l') {
|
|
247
|
+
trigger( this.target, eventName, data, bubble);
|
|
404
248
|
}
|
|
405
249
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
250
|
+
/* DOM traversal */
|
|
251
|
+
parent(): DC | null {
|
|
252
|
+
let
|
|
253
|
+
target: HTMLElement = (this as DC).target;
|
|
254
|
+
if (!isDOM(target)) return null;
|
|
255
|
+
return (target.closest('[data-mc]') as HTMLMcElement)?._mc as DC || null;
|
|
411
256
|
}
|
|
412
|
-
}
|
|
413
257
|
|
|
414
|
-
|
|
258
|
+
ancestors(): DC[] | null {
|
|
259
|
+
let
|
|
260
|
+
currentNode: HTMLElement | null = (this as DC)?.target as HTMLMcElement,
|
|
261
|
+
result: DC[] = [];
|
|
415
262
|
|
|
416
|
-
|
|
263
|
+
if (!isDOM( currentNode )) return [];
|
|
417
264
|
|
|
418
|
-
|
|
265
|
+
while ( currentNode = (currentNode.closest('[data-mc]') ) ){
|
|
266
|
+
if ( (currentNode as HTMLMcElement)?._mc ){
|
|
267
|
+
result.push( (currentNode as HTMLMcElement)?._mc as DC );
|
|
268
|
+
}
|
|
269
|
+
}
|
|
419
270
|
|
|
420
|
-
|
|
271
|
+
return result.length ? result : null;
|
|
272
|
+
}
|
|
421
273
|
|
|
422
|
-
|
|
423
|
-
|
|
274
|
+
children(): DC[] | null {
|
|
275
|
+
let target: any = (this as any)?.target;
|
|
276
|
+
if (!isDOM(target)) return null;
|
|
277
|
+
return getMcChildNodes(target);
|
|
278
|
+
}
|
|
424
279
|
|
|
425
|
-
|
|
280
|
+
descendants(): DC[] | null {
|
|
281
|
+
const target: any = (this as DC)?.target;
|
|
282
|
+
if (!isDOM(target)) return [];
|
|
283
|
+
const mcArray: unknown[] =
|
|
284
|
+
( [ ...target.querySelectorAll( '[data-mc]' ) ] as HTMLMcElement[])
|
|
285
|
+
.filter( (e) => !!e._mc )
|
|
286
|
+
.map( e => e._mc );
|
|
287
|
+
return mcArray.length ? mcArray as DC[] : null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
426
290
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
se.setAttribute('type', 'module');
|
|
431
|
-
se.setAttribute( 'data-name', element);
|
|
432
|
-
se.setAttribute( 'loading', '');
|
|
291
|
+
/*
|
|
292
|
+
Autoload Section...
|
|
293
|
+
*/
|
|
433
294
|
|
|
434
|
-
|
|
295
|
+
const loadingDCs = new Set<string>();
|
|
435
296
|
|
|
436
|
-
|
|
297
|
+
function attachDC(element: string): Function {
|
|
298
|
+
|
|
299
|
+
//@ts-ignore
|
|
300
|
+
return () => {
|
|
437
301
|
const elements: HTMLElement[] = Array
|
|
438
|
-
.from(document.querySelectorAll(`[
|
|
302
|
+
.from(document.querySelectorAll(`[data-mc*="${element}"]`))
|
|
439
303
|
.filter( element => element instanceof HTMLElement );
|
|
440
304
|
|
|
441
305
|
if ( elements.length === 0 ) return;
|
|
@@ -450,28 +314,53 @@ function makeLoadScript( element: string ) {
|
|
|
450
314
|
|
|
451
315
|
//@ts-ignore
|
|
452
316
|
const new_mc = node
|
|
453
|
-
.getAttribute( '
|
|
317
|
+
.getAttribute( 'data-mc' )
|
|
454
318
|
.split(' ')
|
|
455
319
|
.filter( (name) => name !== element && name !== '' )
|
|
456
|
-
.join(' ')
|
|
320
|
+
.join(' ')
|
|
321
|
+
.trim();
|
|
457
322
|
|
|
458
323
|
//@ts-ignore
|
|
459
324
|
node.setAttribute(
|
|
460
|
-
'
|
|
325
|
+
'data-mc',
|
|
461
326
|
//@ts-ignore
|
|
462
327
|
new_mc
|
|
463
328
|
)
|
|
464
329
|
});
|
|
330
|
+
};
|
|
331
|
+
};
|
|
465
332
|
|
|
466
|
-
|
|
467
|
-
|
|
333
|
+
function makeLoadScript( element: string ) {
|
|
334
|
+
|
|
335
|
+
if ( loadingDCs.has( element ) ) return; // already loading
|
|
336
|
+
|
|
337
|
+
loadingDCs.add( element );
|
|
338
|
+
|
|
339
|
+
//console.log( 'makeLoadScript:', element);
|
|
340
|
+
const fileName: string = './' + element.split('-').join('/')+'.js';
|
|
341
|
+
|
|
342
|
+
const se: HTMLScriptElement = document.createElement('script');
|
|
343
|
+
|
|
344
|
+
se.setAttribute('src', fileName);
|
|
345
|
+
se.setAttribute('blocking', 'render');
|
|
346
|
+
se.async = true;
|
|
347
|
+
se.setAttribute('type', 'module');
|
|
348
|
+
se.setAttribute( 'data-name', element);
|
|
349
|
+
se.setAttribute( 'loading', '');
|
|
350
|
+
|
|
351
|
+
const loadedPromise = customElements.whenDefined( element );
|
|
352
|
+
|
|
353
|
+
//@ts-ignore
|
|
354
|
+
loadedPromise.then( attachDC( element ) );
|
|
468
355
|
|
|
469
|
-
|
|
470
|
-
|
|
356
|
+
se.addEventListener( 'load', (ev: Event) => {
|
|
357
|
+
loadingDCs.delete( element );
|
|
358
|
+
|
|
359
|
+
document.head.querySelector(`script[data-name="${element}"]`)?.remove();
|
|
471
360
|
});
|
|
472
361
|
|
|
473
|
-
|
|
474
|
-
console.error('could not load
|
|
362
|
+
se.addEventListener( 'error', (ev: Event) => {
|
|
363
|
+
console.error('could not load DC code from', fileName);
|
|
475
364
|
});
|
|
476
365
|
|
|
477
366
|
document.head.append(se);
|
|
@@ -483,21 +372,26 @@ function loadUndefinedMCs() {
|
|
|
483
372
|
[ ...document.querySelectorAll(':not(:defined)') ]
|
|
484
373
|
.filter( (element) => !!element
|
|
485
374
|
&& !customElements.get(element.tagName.toLowerCase()) // not in CustomElementsRegistry
|
|
486
|
-
&& !
|
|
375
|
+
&& !loadingDCs.has(element.tagName.toLowerCase()) // not in loading list
|
|
487
376
|
)
|
|
488
377
|
.forEach((el) => {
|
|
489
378
|
//console.log( 'detected CE', el.tagName.toLowerCase() );
|
|
490
|
-
makeLoadScript( el.tagName.toLowerCase() );
|
|
379
|
+
makeLoadScript( el.tagName.toLowerCase() ); // will automatically be instanciated
|
|
491
380
|
});
|
|
492
381
|
|
|
493
|
-
//
|
|
494
|
-
[ ...document.querySelectorAll('[
|
|
382
|
+
// if defined in _mc attribute: instanciate DCs, load if necessary
|
|
383
|
+
[ ...document.querySelectorAll('[data-mc]:not([data-mc=""]') ]
|
|
495
384
|
.filter( (element) => !!element )
|
|
496
385
|
.forEach((el) => {
|
|
497
|
-
const _mc = el.getAttribute('
|
|
498
|
-
_mc?.forEach(
|
|
386
|
+
const _mc = el.getAttribute('data-mc')?.split(' ').filter( name => name !== '' );
|
|
387
|
+
_mc?.forEach( element => {
|
|
499
388
|
//console.log( 'detected DC', dc );
|
|
500
|
-
|
|
389
|
+
const isDefined = customElements.get(element);
|
|
390
|
+
if ( !loadingDCs.has(element) && !isDefined ) {
|
|
391
|
+
makeLoadScript( element );
|
|
392
|
+
} else if ( isDefined ) {
|
|
393
|
+
attachDC(element)();
|
|
394
|
+
}
|
|
501
395
|
});
|
|
502
396
|
});
|
|
503
397
|
}
|
|
@@ -526,7 +420,7 @@ function autoload(enable: boolean = true): boolean {
|
|
|
526
420
|
return autoloadEnabled;
|
|
527
421
|
}
|
|
528
422
|
|
|
529
|
-
(autoload as LooseObject).state =
|
|
423
|
+
(autoload as LooseObject).state = loadingDCs;
|
|
530
424
|
|
|
531
|
-
export {
|
|
425
|
+
export { McBase, MC, DC, autoload, on, one, off, trigger };
|
|
532
426
|
|