@twobirds/microcomponents 0.0.33 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/dist/MC.d.ts +2 -3
- package/dist/MC.d.ts.map +1 -1
- package/dist/MC.min.js +45 -43
- package/dist/MC.ts +173 -175
- 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 +354 -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 +133 -157
- package/klemmstein.png +0 -0
- package/package.json +52 -52
- package/public/MC.js +46 -44
- package/public/MC.js.map +1 -1
- package/public/MC.min.js +45 -43
- 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/observables.js +255 -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 +376 -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 +354 -0
- package/public/src/test.ts +187 -0
- package/public/test.js +99 -115
- 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 +173 -175
- 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 +354 -0
- package/src/selectors.ts +1634 -0
- package/src/test.ts +133 -157
- 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
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
LooseObject,
|
|
5
|
+
parse,
|
|
6
|
+
debounce,
|
|
7
|
+
deepEqual,
|
|
8
|
+
nameSpace,
|
|
9
|
+
flattenObject,
|
|
10
|
+
} from './helpers.js';
|
|
11
|
+
|
|
12
|
+
import { DC, HTMLMcElement, McEvent } from './MC.js';
|
|
13
|
+
|
|
14
|
+
function isObservableObject(value: any): boolean {
|
|
15
|
+
return value != null && typeof value === 'object';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type Callback = (value: any) => void;
|
|
19
|
+
|
|
20
|
+
function getPlaceholders(target: HTMLElement): string[] {
|
|
21
|
+
let placeholders: Set<string> = new Set();
|
|
22
|
+
|
|
23
|
+
// scan attributes
|
|
24
|
+
target
|
|
25
|
+
.getAttributeNames()
|
|
26
|
+
.filter((attr) => target.getAttribute(attr)?.match(/\{[^\{\}]*\}/g)) // extract placeholder(s)
|
|
27
|
+
.forEach((attr) => {
|
|
28
|
+
let phs: Set<string> = new Set(
|
|
29
|
+
target.getAttribute(attr)?.match(/\{[^\{\}]*\}/g)
|
|
30
|
+
);
|
|
31
|
+
phs.forEach((placeholder) =>
|
|
32
|
+
placeholders.add(placeholder.replace(/[\{\}]/g, ''))
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// scan children text nodes
|
|
37
|
+
[...target.childNodes]
|
|
38
|
+
.filter((childNode) => {
|
|
39
|
+
return (
|
|
40
|
+
// is text node and has placeholders
|
|
41
|
+
childNode.nodeType === 3 &&
|
|
42
|
+
((childNode as any).nodeValue || '').match(/\{[^\{\}]*\}/g)
|
|
43
|
+
);
|
|
44
|
+
})
|
|
45
|
+
.forEach((childNode) => {
|
|
46
|
+
((childNode as any).nodeValue || '')
|
|
47
|
+
.match(/\{[^\{\}]*\}/g)
|
|
48
|
+
.forEach((placeholder: string) => {
|
|
49
|
+
placeholders.add(placeholder.replace(/[\{\}]/g, ''));
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// extract {}
|
|
54
|
+
let result: string[] = [...placeholders].map((placeholder) =>
|
|
55
|
+
placeholder.replace(/[\{\}]/g, '')
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
//console.log('getPlaceholders()', target, result);
|
|
59
|
+
|
|
60
|
+
return [...placeholders];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class Placeholders extends DC {
|
|
64
|
+
data: LooseObject = {};
|
|
65
|
+
placeholders: string[] = [];
|
|
66
|
+
|
|
67
|
+
constructor(target: HTMLElement) {
|
|
68
|
+
super(target);
|
|
69
|
+
let that = this;
|
|
70
|
+
getPlaceholders(target).forEach((property) => (that.data[property] = ''));
|
|
71
|
+
observe(that);
|
|
72
|
+
that.#attachCallbacks();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#attachCallbacks() {
|
|
76
|
+
let that = this,
|
|
77
|
+
target = that.target;
|
|
78
|
+
|
|
79
|
+
// console.log('attachCallbacks', that.target);
|
|
80
|
+
|
|
81
|
+
// scan attributes
|
|
82
|
+
target
|
|
83
|
+
.getAttributeNames()
|
|
84
|
+
.filter((attr: string) =>
|
|
85
|
+
target.getAttribute(attr)?.match(/\{[^\{\}]*\}/g)
|
|
86
|
+
) // extract placeholder(s)
|
|
87
|
+
.forEach((attr: string) => {
|
|
88
|
+
let phs: Set<string> = new Set(
|
|
89
|
+
target.getAttribute(attr)?.match(/\{[^\{\}]*\}/g)
|
|
90
|
+
);
|
|
91
|
+
// attach callback
|
|
92
|
+
that.data.observe(
|
|
93
|
+
((template: string) => (data: LooseObject) => {
|
|
94
|
+
let result: string = template;
|
|
95
|
+
phs.forEach((placeholder) => {
|
|
96
|
+
result = result.replace(
|
|
97
|
+
placeholder,
|
|
98
|
+
data[placeholder.replace(/[\{\}]/g, '')]
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
target.setAttribute(attr, result);
|
|
102
|
+
//console.log('cb setAttribute()', data, template, attr, result);
|
|
103
|
+
})(target.getAttribute(attr))
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// scan children text nodes
|
|
108
|
+
[...target.childNodes]
|
|
109
|
+
.filter((childNode) => {
|
|
110
|
+
return (
|
|
111
|
+
// is text node and has placeholders
|
|
112
|
+
childNode.nodeType === 3 &&
|
|
113
|
+
((childNode as any).nodeValue || '').match(/\{[^\{\}]*\}/g)
|
|
114
|
+
);
|
|
115
|
+
})
|
|
116
|
+
.forEach((childNode) => {
|
|
117
|
+
let phs: Set<string> = new Set(
|
|
118
|
+
childNode.nodeValue.match(/\{[^\{\}]*\}/g)
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// attach callback
|
|
122
|
+
that.data.observe(
|
|
123
|
+
((template: string) => (data: LooseObject) => {
|
|
124
|
+
let result: string = template;
|
|
125
|
+
phs.forEach((placeholder) => {
|
|
126
|
+
result = result.replace(
|
|
127
|
+
placeholder,
|
|
128
|
+
data[placeholder.replace(/[\{\}]/g, '')]
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
//console.log('cb nodeValue', phs, data, template, childNode, result);
|
|
132
|
+
childNode.nodeValue = result;
|
|
133
|
+
})(childNode.nodeValue)
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
onData(ev: McEvent) {
|
|
139
|
+
let that = this,
|
|
140
|
+
data: LooseObject = {};
|
|
141
|
+
Object.keys(ev.data).forEach((key) => {
|
|
142
|
+
if (that.data.hasOwnProperty(key)) data[key] = ev.data[key];
|
|
143
|
+
});
|
|
144
|
+
// console.log('onData()', ev, data, that.data);
|
|
145
|
+
if (JSON.stringify(data) !== JSON.stringify(that.data))
|
|
146
|
+
Object.assign(that.data, data); // will trigger callbacks
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function getPlaceholderElements(
|
|
151
|
+
target: HTMLElement | DocumentFragment | ShadowRoot
|
|
152
|
+
): HTMLElement[] {
|
|
153
|
+
let elements: Array<HTMLElement | DocumentFragment | ShadowRoot> = [target]
|
|
154
|
+
.concat([...(target.querySelectorAll('*') as unknown as HTMLElement[])])
|
|
155
|
+
.filter((e) => !!getPlaceholders(e as HTMLElement).length);
|
|
156
|
+
return elements as HTMLElement[];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function makePlaceHolders(
|
|
160
|
+
element: HTMLElement | DocumentFragment | ShadowRoot
|
|
161
|
+
): void {
|
|
162
|
+
getPlaceholderElements(element).forEach((e) =>
|
|
163
|
+
DC.add(e, '_placeholders', new Placeholders(e))
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type Observable = {
|
|
168
|
+
observe: (cb: Callback) => void;
|
|
169
|
+
notify: () => void;
|
|
170
|
+
bind: (target: HTMLElement | DocumentFragment | ShadowRoot) => void;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export const observe = (target: LooseObject, propertyName?: string) => {
|
|
174
|
+
let keys = !propertyName
|
|
175
|
+
? [...Object.getOwnPropertyNames(target)]
|
|
176
|
+
: [propertyName];
|
|
177
|
+
|
|
178
|
+
keys.forEach((key) => {
|
|
179
|
+
// console.log( 'co propname', key, typeof target[key], target[key] );
|
|
180
|
+
if (key[0] === '_' || target?.[key] === undefined) return;
|
|
181
|
+
let val: any = target[key],
|
|
182
|
+
Constructor: any;
|
|
183
|
+
|
|
184
|
+
if (!val.prototype) {
|
|
185
|
+
switch (typeof val) {
|
|
186
|
+
case 'string':
|
|
187
|
+
Constructor = String;
|
|
188
|
+
break;
|
|
189
|
+
case 'number':
|
|
190
|
+
Constructor = Number;
|
|
191
|
+
break;
|
|
192
|
+
case 'boolean':
|
|
193
|
+
Constructor = Boolean;
|
|
194
|
+
break;
|
|
195
|
+
case 'object':
|
|
196
|
+
if (val instanceof Array) {
|
|
197
|
+
Constructor = Array;
|
|
198
|
+
} else {
|
|
199
|
+
Constructor = Object;
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
default:
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let Observable = class extends Constructor {
|
|
208
|
+
constructor(val: any) {
|
|
209
|
+
super(val);
|
|
210
|
+
(this.constructor as LooseObject).callbacks = [];
|
|
211
|
+
if (isObservableObject(val)) {
|
|
212
|
+
// you cannot bind native values to the dom
|
|
213
|
+
(this.constructor as LooseObject).bound = [];
|
|
214
|
+
Object.getOwnPropertyNames(val).forEach((key) => {
|
|
215
|
+
this[key] = val[key];
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
observe(f: Function) {
|
|
221
|
+
//console.log('observe');
|
|
222
|
+
(this.constructor as any).callbacks.push(f);
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
bind(target: HTMLElement | DocumentFragment | ShadowRoot) {
|
|
227
|
+
const that = this,
|
|
228
|
+
iso = isObservableObject(that.valueOf()),
|
|
229
|
+
bound = (that.constructor as any).bound;
|
|
230
|
+
//console.log('bind', iso, target);
|
|
231
|
+
|
|
232
|
+
if (iso) {
|
|
233
|
+
makePlaceHolders(target);
|
|
234
|
+
(this.constructor as any).callbacks.push((data: LooseObject) => {
|
|
235
|
+
DC.trigger(target, 'data', flattenObject(data), 'ld');
|
|
236
|
+
});
|
|
237
|
+
that.notify();
|
|
238
|
+
} else {
|
|
239
|
+
console.warn(
|
|
240
|
+
'IGNORED - cannot bind a non-Object to the dom, IS:',
|
|
241
|
+
typeof that.valueOf(),
|
|
242
|
+
that
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
notify() {
|
|
250
|
+
let that = this,
|
|
251
|
+
data =
|
|
252
|
+
isObservableObject(that.valueOf()) &&
|
|
253
|
+
that.valueOf() instanceof Array === false
|
|
254
|
+
? structuredClone(Object.assign({}, that))
|
|
255
|
+
: that.valueOf();
|
|
256
|
+
// console.log('notify', that.constructor, (that.constructor as any).callbacks.length, (that.constructor as any)?.bound?.length, data );
|
|
257
|
+
(that.constructor as any).callbacks.forEach((f: Function) => {
|
|
258
|
+
// console.log( 'callback', f, data);
|
|
259
|
+
f(data);
|
|
260
|
+
});
|
|
261
|
+
if (isObservableObject(that.valueOf())) {
|
|
262
|
+
// console.log('bound', this.constructor);
|
|
263
|
+
(that.constructor as any).bound.forEach((f: Function) => {
|
|
264
|
+
// console.log( 'bound', f, data);
|
|
265
|
+
f(data);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
//(Observable.constructor as LooseObject).callbacks = [];
|
|
273
|
+
let o = new Observable(val);
|
|
274
|
+
|
|
275
|
+
Object.defineProperty(target, key, {
|
|
276
|
+
enumerable: true,
|
|
277
|
+
get() {
|
|
278
|
+
if (isObservableObject(o.valueOf())) {
|
|
279
|
+
let check = structuredClone(Object.assign({}, o));
|
|
280
|
+
setTimeout(
|
|
281
|
+
debounce(function checkChanges() {
|
|
282
|
+
let state = structuredClone(Object.assign({}, o));
|
|
283
|
+
//console.log( 'check changes', state, check );
|
|
284
|
+
if (!deepEqual(state, check)) {
|
|
285
|
+
//console.log( '-> not equal!' );
|
|
286
|
+
o.notify();
|
|
287
|
+
}
|
|
288
|
+
}, 0),
|
|
289
|
+
0
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
return o;
|
|
293
|
+
},
|
|
294
|
+
set(val: any) {
|
|
295
|
+
//console.log( 'SET:', isObservableObject( val.valueOf() ), 'set:', val, 'to', isObservableObject( o.valueOf() ), o, );
|
|
296
|
+
if (typeof val === typeof o.valueOf()) {
|
|
297
|
+
let iso =
|
|
298
|
+
isObservableObject(o.valueOf()) &&
|
|
299
|
+
o.valueOf() instanceof Array === false;
|
|
300
|
+
//let iso = o.constructor.prototype.__proto__.constructor === Object;
|
|
301
|
+
//console.log('target iso:', iso);
|
|
302
|
+
if (iso) {
|
|
303
|
+
let old = structuredClone(Object.assign({}, o));
|
|
304
|
+
val = structuredClone(Object.assign({}, val));
|
|
305
|
+
|
|
306
|
+
let hasFormHandler =
|
|
307
|
+
(o.constructor as LooseObject)?.hasFormHandler ?? false,
|
|
308
|
+
callbacks = (o.constructor as LooseObject).callbacks,
|
|
309
|
+
bound = (o.constructor as LooseObject).bound;
|
|
310
|
+
o = new Observable(structuredClone(Object.assign({}, val)));
|
|
311
|
+
|
|
312
|
+
//console.log('after set o=', o, 'check', old);
|
|
313
|
+
(o.constructor as LooseObject).callbacks = hasFormHandler;
|
|
314
|
+
(o.constructor as LooseObject).callbacks = callbacks;
|
|
315
|
+
(o.constructor as LooseObject).bound = bound;
|
|
316
|
+
|
|
317
|
+
setTimeout(
|
|
318
|
+
// check for changes
|
|
319
|
+
debounce(function checkChanges() {
|
|
320
|
+
let state = structuredClone(Object.assign({}, o));
|
|
321
|
+
//console.log( 'check changes', state, check );
|
|
322
|
+
if (!deepEqual(state, old)) {
|
|
323
|
+
//console.log( '-> not equal!' );
|
|
324
|
+
o.notify();
|
|
325
|
+
}
|
|
326
|
+
}, 0),
|
|
327
|
+
0
|
|
328
|
+
);
|
|
329
|
+
} else {
|
|
330
|
+
// simple native var
|
|
331
|
+
let old = o.valueOf(),
|
|
332
|
+
callbacks = (o.constructor as LooseObject).callbacks;
|
|
333
|
+
o = new Observable(val);
|
|
334
|
+
(o.constructor as LooseObject).callbacks = callbacks;
|
|
335
|
+
if (val !== old) {
|
|
336
|
+
o.notify();
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
console.warn(
|
|
341
|
+
'IGNORED - cannot change observable types, IS:',
|
|
342
|
+
typeof o.valueOf(),
|
|
343
|
+
o,
|
|
344
|
+
'- CANNOT BECOME:',
|
|
345
|
+
typeof val
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// replace old property with proxy (observable)
|
|
352
|
+
target[key] = val;
|
|
353
|
+
});
|
|
354
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
HTMLMcElement,
|
|
5
|
+
LooseObject,
|
|
6
|
+
MC,
|
|
7
|
+
DC,
|
|
8
|
+
McEvent,
|
|
9
|
+
defineCE,
|
|
10
|
+
getCE,
|
|
11
|
+
observe,
|
|
12
|
+
Observable,
|
|
13
|
+
} from './microcomponents.js';
|
|
14
|
+
|
|
15
|
+
//import { MC, DC, McEvent } from "./MC.js";
|
|
16
|
+
//import { defineCE, getCE } from "./elements.js";
|
|
17
|
+
//import { observe } from "./observables.js";
|
|
18
|
+
|
|
19
|
+
//MC.debug = true;
|
|
20
|
+
|
|
21
|
+
class Translator extends DC {
|
|
22
|
+
#translations: LooseObject = {};
|
|
23
|
+
|
|
24
|
+
Language: unknown = 'en';
|
|
25
|
+
Translation: unknown = {};
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
target: HTMLElement | ShadowRoot | DocumentFragment,
|
|
29
|
+
translations: LooseObject,
|
|
30
|
+
translationTargetObject: HTMLElement
|
|
31
|
+
) {
|
|
32
|
+
super(target as HTMLElement);
|
|
33
|
+
let that = this; // minifier help
|
|
34
|
+
|
|
35
|
+
// state
|
|
36
|
+
that.Language = 'en';
|
|
37
|
+
that.Translation = {};
|
|
38
|
+
|
|
39
|
+
observe(that);
|
|
40
|
+
|
|
41
|
+
// setup
|
|
42
|
+
that.#translations = translations;
|
|
43
|
+
|
|
44
|
+
// state
|
|
45
|
+
(that.Language as Observable).observe((lang) => {
|
|
46
|
+
if (that.#translations.hasOwnProperty(lang)) {
|
|
47
|
+
that.Translation = { lang: that.#translations[lang] }; // set translation
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
(that.Translation as Observable).bind(target);
|
|
52
|
+
|
|
53
|
+
this.target.setAttribute('language', 'en');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
oneInit() {
|
|
57
|
+
(this.Language as Observable).notify(); // trigger translation
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onAttributeChanged(ev: McEvent) {
|
|
61
|
+
if (!ev.data.newValue) return;
|
|
62
|
+
|
|
63
|
+
let that = this;
|
|
64
|
+
|
|
65
|
+
switch (ev.data.name) {
|
|
66
|
+
case 'language':
|
|
67
|
+
that.Language = ev.data.newValue;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
defineCE(
|
|
74
|
+
// equivalent to custom element registry .define()
|
|
75
|
+
'my-tag',
|
|
76
|
+
class MyTag extends DC {
|
|
77
|
+
#template: string = '{lang.click} {counter}';
|
|
78
|
+
|
|
79
|
+
#languages = {
|
|
80
|
+
en: {
|
|
81
|
+
click: 'click me',
|
|
82
|
+
},
|
|
83
|
+
de: {
|
|
84
|
+
click: 'klick mich',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
Dom: LooseObject = {};
|
|
89
|
+
|
|
90
|
+
constructor(target: HTMLElement) {
|
|
91
|
+
super(target);
|
|
92
|
+
|
|
93
|
+
let that = this; // minifier help
|
|
94
|
+
|
|
95
|
+
// render
|
|
96
|
+
target.innerHTML = this.#template;
|
|
97
|
+
|
|
98
|
+
// add public translator
|
|
99
|
+
DC.add(
|
|
100
|
+
target,
|
|
101
|
+
'translator',
|
|
102
|
+
new Translator(target, that.#languages, target)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
oneInit(ev: McEvent) {
|
|
107
|
+
let that = this;
|
|
108
|
+
|
|
109
|
+
// state
|
|
110
|
+
that.Dom = { counter: 0 };
|
|
111
|
+
|
|
112
|
+
// state: convert all props defined so far into observables
|
|
113
|
+
observe(that);
|
|
114
|
+
|
|
115
|
+
// bind Dom to target
|
|
116
|
+
(that.Dom as Observable).bind(that.target);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
onAttributeChanged(ev: McEvent) {
|
|
120
|
+
//console.log(ev);
|
|
121
|
+
this.target._mc.translator.Language = ev.data.newValue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
onClick(ev: McEvent) {
|
|
125
|
+
this.Dom.counter++;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
['language']
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
let MyTag: CustomElementConstructor = getCE('my-tag')!,
|
|
132
|
+
fragment = new DocumentFragment();
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
stress test
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
/*
|
|
139
|
+
let start = new Date().getTime();
|
|
140
|
+
|
|
141
|
+
// create 1000 elements
|
|
142
|
+
for (let x = 0; x < 1000; x++) {
|
|
143
|
+
let mt = new MyTag('my-data');
|
|
144
|
+
fragment.append(mt);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let end = new Date().getTime();
|
|
148
|
+
|
|
149
|
+
// and put them into the DOM
|
|
150
|
+
document.body.appendChild(fragment);
|
|
151
|
+
|
|
152
|
+
document.querySelectorAll('my-tag').forEach((e) => e.remove());
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
console test
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
console.clear();
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
console.log(
|
|
164
|
+
'%c \n\nStress Test:\n\n %cInstancing 1000 web components: %c %s ms.',
|
|
165
|
+
'font-weight: bold; color: black;',
|
|
166
|
+
'font-weight: normal;',
|
|
167
|
+
'font-weight: bold; color: blue;',
|
|
168
|
+
0
|
|
169
|
+
);
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
document.body.appendChild(new MyTag());
|
|
173
|
+
|
|
174
|
+
let element = document.querySelector('my-tag');
|
|
175
|
+
|
|
176
|
+
console.log(
|
|
177
|
+
"\n\n%cInspect this tag:%c \n( ...to see the inner structure in the '._mc' property )\n\n %O %c %s",
|
|
178
|
+
'font-weight: bold;',
|
|
179
|
+
'font-weight: normal;',
|
|
180
|
+
element,
|
|
181
|
+
'font-weight: bold;',
|
|
182
|
+
'\n\nLook up code in the debugger: test.js\n\n'
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// will trigger the event on all micro components contained in <my-tag>
|
|
186
|
+
DC.trigger(element, 'doSomething');
|
|
187
|
+
}, 20);
|