arrmatura 5.0.2 → 5.0.6
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/core/Arrmatura.ts +8 -3
- package/core/CNode.ts +1 -1
- package/core/Component.ts +40 -45
- package/core/cnodes/composition.ts +2 -2
- package/core/cnodes/conditionals.ts +2 -2
- package/core/cnodes/elementary.ts +2 -3
- package/core/cnodes/iterations.ts +3 -5
- package/core/cnodes/routing.ts +1 -1
- package/core/index.ts +0 -1
- package/core/utils.ts +1 -1
- package/core-web/attributes.ts +20 -27
- package/core-web/elements.ts +15 -15
- package/core-web/index.ts +3 -6
- package/core-web/reflow.ts +5 -7
- package/core-web/type.ts +3 -4
- package/docs/index.js +119 -55
- package/lib/arraySortBy.ts +3 -3
- package/lib/geospatial.js +22 -0
- package/lib/obj.ts +2 -0
- package/lib/xml.ts +1 -1
- package/package.json +3 -2
- package/core/Platform.ts +0 -3
package/core/Arrmatura.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { CNode } from './CNode';
|
|
|
2
2
|
import { compileNodes } from './compileNode';
|
|
3
3
|
import { Component } from './Component';
|
|
4
4
|
import { xmlParse } from '../lib/xml';
|
|
5
|
-
import { Platform } from './Platform';
|
|
6
5
|
import { registerTypes } from './register';
|
|
7
6
|
|
|
8
7
|
export class Arrmatura extends Component<CArrmaturaNode> implements IArrmatura {
|
|
@@ -16,10 +15,14 @@ export class Arrmatura extends Component<CArrmaturaNode> implements IArrmatura {
|
|
|
16
15
|
return this;
|
|
17
16
|
}
|
|
18
17
|
|
|
18
|
+
get platform(): IPlatform {
|
|
19
|
+
return this.node.platform;
|
|
20
|
+
}
|
|
21
|
+
|
|
19
22
|
requestReflow() {
|
|
20
23
|
if (this.reflowId) return;
|
|
21
24
|
this.reflowId = setTimeout(() => {
|
|
22
|
-
|
|
25
|
+
this.platform.reflow(this);
|
|
23
26
|
this.reflowId = undefined;
|
|
24
27
|
}, 10);
|
|
25
28
|
}
|
|
@@ -53,14 +56,16 @@ export class Arrmatura extends Component<CArrmaturaNode> implements IArrmatura {
|
|
|
53
56
|
export class CArrmaturaNode extends CNode<Arrmatura> {
|
|
54
57
|
functions?: Hash;
|
|
55
58
|
resources: Hash<any> | undefined;
|
|
59
|
+
platform: IPlatform;
|
|
56
60
|
|
|
57
|
-
constructor(template: string, { types, functions, resources }: ArrmaturaOptions) {
|
|
61
|
+
constructor(template: string, { types, functions, resources }: ArrmaturaOptions, platform: IPlatform) {
|
|
58
62
|
super();
|
|
59
63
|
|
|
60
64
|
registerTypes(types);
|
|
61
65
|
|
|
62
66
|
this.functions = functions;
|
|
63
67
|
this.resources = resources;
|
|
68
|
+
this.platform = platform;
|
|
64
69
|
|
|
65
70
|
this.content = compileNodes(xmlParse(template));
|
|
66
71
|
}
|
package/core/CNode.ts
CHANGED
|
@@ -58,7 +58,7 @@ export abstract class CNode<T extends Component = Component> implements INode<T>
|
|
|
58
58
|
addEmitter(expr: Expression, k: PropertyKey) {
|
|
59
59
|
const { key, pipec } = compilePipeExpression(expr);
|
|
60
60
|
this.initializers.push((c) => ({
|
|
61
|
-
payload: { [k]: (data: unknown) => c
|
|
61
|
+
payload: { [k]: (data: unknown) => c.$scope?.emit(key, pipec(c, data) as Delta) },
|
|
62
62
|
}));
|
|
63
63
|
}
|
|
64
64
|
|
package/core/Component.ts
CHANGED
|
@@ -7,18 +7,14 @@ import { createListeners } from 'createListeners';
|
|
|
7
7
|
* Runtime Component class.
|
|
8
8
|
*/
|
|
9
9
|
export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
10
|
-
impl: IComponentImplementation;
|
|
11
|
-
element?: any;
|
|
10
|
+
readonly $impl: IComponentImplementation;
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
children?: Map<Uid, IComponent>;
|
|
12
|
+
$children?: Map<Uid, IComponent>;
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
private _parent?: IComponent;
|
|
14
|
+
readonly $scope: IScope;
|
|
15
|
+
readonly #parent?: IComponent;
|
|
19
16
|
#isInited: boolean = false;
|
|
20
17
|
#isDone: boolean = false;
|
|
21
|
-
// #notifying: boolean = false;
|
|
22
18
|
#listeners?: Listeners<void>;
|
|
23
19
|
#defered?: Array<ComponentProcedure> = [];
|
|
24
20
|
#weak?: Map<any, any>;
|
|
@@ -26,17 +22,17 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
26
22
|
#propFnMap?: Hash<Procedure>;
|
|
27
23
|
|
|
28
24
|
constructor(readonly _node: INode, _parent?: IComponent, scope?: IScope) {
|
|
29
|
-
this
|
|
30
|
-
this
|
|
31
|
-
this
|
|
25
|
+
this.$scope = scope || this;
|
|
26
|
+
this.#parent = _parent;
|
|
27
|
+
this.$impl = this.createImplementation(this.getInitialState());
|
|
32
28
|
|
|
33
29
|
if (this.refId) {
|
|
34
|
-
this
|
|
30
|
+
this.$scope.addComponentReference(this.refId, this);
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
get parent(): IComponent {
|
|
39
|
-
return this
|
|
35
|
+
return this.#parent || this;
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
get node(): T {
|
|
@@ -79,9 +75,8 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
79
75
|
const pv = v as Promise<any>;
|
|
80
76
|
if (v && pv.then && pv.catch) {
|
|
81
77
|
this.upAsync(pv, k);
|
|
82
|
-
} else if (k && typeof v !== 'undefined' && v !== this
|
|
78
|
+
} else if (k && typeof v !== 'undefined' && v !== this.$impl[k]) {
|
|
83
79
|
changes.set(k, v);
|
|
84
|
-
this.state[k] = v;
|
|
85
80
|
}
|
|
86
81
|
});
|
|
87
82
|
|
|
@@ -107,15 +102,15 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
107
102
|
}
|
|
108
103
|
|
|
109
104
|
stateChanged(changes: Map<string, unknown>) {
|
|
110
|
-
if (this
|
|
111
|
-
this
|
|
105
|
+
if (this.$impl.stateChanged) {
|
|
106
|
+
this.$impl.stateChanged(changes);
|
|
112
107
|
} else {
|
|
113
108
|
changes.forEach((v, k) => {
|
|
114
|
-
const setter = this
|
|
109
|
+
const setter = this.$impl[methodName(k, 'set')];
|
|
115
110
|
if (typeof setter === 'function') {
|
|
116
|
-
setter.call(this
|
|
111
|
+
setter.call(this.$impl, v);
|
|
117
112
|
} else {
|
|
118
|
-
this
|
|
113
|
+
this.$impl[k] = v;
|
|
119
114
|
}
|
|
120
115
|
});
|
|
121
116
|
}
|
|
@@ -128,7 +123,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
128
123
|
return fn();
|
|
129
124
|
}
|
|
130
125
|
|
|
131
|
-
const impl = this
|
|
126
|
+
const impl = this.$impl;
|
|
132
127
|
const instant = impl[propId];
|
|
133
128
|
if (instant && typeof instant === 'function') {
|
|
134
129
|
const bound = instant.bind(impl);
|
|
@@ -148,7 +143,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
148
143
|
}
|
|
149
144
|
|
|
150
145
|
getFromScope(propId: string): unknown {
|
|
151
|
-
return this
|
|
146
|
+
return this.$scope.get(propId);
|
|
152
147
|
}
|
|
153
148
|
|
|
154
149
|
// --- Left Arrow.
|
|
@@ -175,12 +170,12 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
175
170
|
|
|
176
171
|
connect(key: string, applicator: (x: unknown) => unknown): undefined | ComponentSubsription {
|
|
177
172
|
const [refId, propId = '*'] = key.split('.');
|
|
178
|
-
const ref = this
|
|
173
|
+
const ref = this.$scope.getByRef(refId) as Component;
|
|
179
174
|
if (!ref) {
|
|
180
175
|
this.logError('Connect: No such ref: ' + refId);
|
|
181
176
|
return;
|
|
182
177
|
}
|
|
183
|
-
return ref.subscribe(this, (c: Component) => applyValue(propId === '*' ? c
|
|
178
|
+
return ref.subscribe(this, (c: Component) => applyValue(propId === '*' ? c.$impl : c.get(propId), applicator));
|
|
184
179
|
}
|
|
185
180
|
|
|
186
181
|
// --- Right Arrow.
|
|
@@ -188,7 +183,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
188
183
|
emit(key: string, data: Delta): void {
|
|
189
184
|
if (!key || !key.includes('.')) {
|
|
190
185
|
this.up(key ? { [key]: data } : data);
|
|
191
|
-
this.log('update:' + key, data, this
|
|
186
|
+
this.log('update:' + key, data, this.$impl);
|
|
192
187
|
return;
|
|
193
188
|
}
|
|
194
189
|
|
|
@@ -200,7 +195,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
200
195
|
}
|
|
201
196
|
|
|
202
197
|
const propId = methodName(target, 'on');
|
|
203
|
-
const impl = ref
|
|
198
|
+
const impl = ref.$impl;
|
|
204
199
|
|
|
205
200
|
const method = impl[propId];
|
|
206
201
|
if (!method || !(typeof method === 'function')) {
|
|
@@ -250,8 +245,8 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
250
245
|
args.reduce((r, e) => Object.assign(r, e), initials),
|
|
251
246
|
true
|
|
252
247
|
);
|
|
253
|
-
if (this
|
|
254
|
-
const d = this
|
|
248
|
+
if (this.$impl.init) {
|
|
249
|
+
const d = this.$impl.init(this);
|
|
255
250
|
if (d) {
|
|
256
251
|
this.up(d);
|
|
257
252
|
}
|
|
@@ -259,8 +254,8 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
259
254
|
});
|
|
260
255
|
} else {
|
|
261
256
|
this.up(initials, true);
|
|
262
|
-
if (this
|
|
263
|
-
const d = this
|
|
257
|
+
if (this.$impl.init) {
|
|
258
|
+
const d = this.$impl.init(this);
|
|
264
259
|
if (d) {
|
|
265
260
|
this.up(d);
|
|
266
261
|
}
|
|
@@ -275,19 +270,19 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
275
270
|
}
|
|
276
271
|
this.#isDone = true;
|
|
277
272
|
|
|
278
|
-
this
|
|
273
|
+
this.$impl.done?.(this);
|
|
279
274
|
|
|
280
|
-
const parent = this
|
|
281
|
-
this
|
|
275
|
+
const parent = this.#parent;
|
|
276
|
+
this.#parent = undefined;
|
|
282
277
|
|
|
283
|
-
this
|
|
278
|
+
this.$children?.forEach((c) => c.done());
|
|
284
279
|
|
|
285
|
-
parent
|
|
280
|
+
parent?.$children?.delete(this.uid);
|
|
286
281
|
|
|
287
282
|
this.#defered?.forEach((f) => f(this));
|
|
288
283
|
this.#defered = undefined;
|
|
289
284
|
|
|
290
|
-
this
|
|
285
|
+
this.$impl.$ = null;
|
|
291
286
|
}
|
|
292
287
|
|
|
293
288
|
// -- Contents --------------------------------------------------------
|
|
@@ -297,11 +292,11 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
297
292
|
}
|
|
298
293
|
|
|
299
294
|
get recontentScope(): IScope {
|
|
300
|
-
return this
|
|
295
|
+
return this.$scope;
|
|
301
296
|
}
|
|
302
297
|
|
|
303
298
|
setupChildren(children: ComponentChildren) {
|
|
304
|
-
this
|
|
299
|
+
this.$children = children;
|
|
305
300
|
|
|
306
301
|
children.forEach((e) => e.settleAsChild());
|
|
307
302
|
}
|
|
@@ -320,7 +315,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
320
315
|
|
|
321
316
|
this.arrmatura.requestReflow();
|
|
322
317
|
|
|
323
|
-
this
|
|
318
|
+
this.$children?.forEach((e, uid) => {
|
|
324
319
|
if (!nodes?.get(uid)) {
|
|
325
320
|
e.done();
|
|
326
321
|
}
|
|
@@ -329,7 +324,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
329
324
|
const children = new Map<Uid, IComponent>();
|
|
330
325
|
|
|
331
326
|
nodes?.forEach((node, uid) => {
|
|
332
|
-
const e = this
|
|
327
|
+
const e = this.$children?.get(uid) || node.createComponent(this, scope);
|
|
333
328
|
children.set(e.uid, e);
|
|
334
329
|
});
|
|
335
330
|
|
|
@@ -354,7 +349,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
354
349
|
if (local) {
|
|
355
350
|
return local as Component;
|
|
356
351
|
}
|
|
357
|
-
const ref = this === this
|
|
352
|
+
const ref = this === this.$scope ? null : this.$scope.getByRef(refId);
|
|
358
353
|
return ref as Component;
|
|
359
354
|
}
|
|
360
355
|
|
|
@@ -372,7 +367,7 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
372
367
|
try {
|
|
373
368
|
const [id, ...args] = key.split(':');
|
|
374
369
|
const fn = this.pipe(id);
|
|
375
|
-
return fn.apply(this
|
|
370
|
+
return fn.apply(this, [
|
|
376
371
|
value,
|
|
377
372
|
...args.map((a) => (a[0] === '@' ? this.getFromScope(a.slice(1)) : scalarParse(a))),
|
|
378
373
|
]);
|
|
@@ -415,14 +410,14 @@ export class Component<T extends INode = INode> implements IComponent, IScope {
|
|
|
415
410
|
}
|
|
416
411
|
|
|
417
412
|
stringify(tab = '') {
|
|
418
|
-
const { uid, displayName: tag = uid,
|
|
413
|
+
const { uid, displayName: tag = uid, $impl: impl, $children: children } = this;
|
|
419
414
|
if (tag === '#text') {
|
|
420
|
-
return `${tab}` +
|
|
415
|
+
return `${tab}` + impl.text;
|
|
421
416
|
}
|
|
422
417
|
const ssubs: string = children?.size
|
|
423
418
|
? [...children.values()].map((c) => (c as Component).stringify(` ${tab}`)).join('\n')
|
|
424
419
|
: '';
|
|
425
|
-
return `${tab}<${tag}${stringifyState(
|
|
420
|
+
return `${tab}<${tag}${stringifyState(impl)}` + (!ssubs ? '/>' : `>\n${ssubs}\n${tab}</${tag}>`);
|
|
426
421
|
}
|
|
427
422
|
|
|
428
423
|
toString() {
|
|
@@ -24,7 +24,7 @@ export class SlotComponent extends Component {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
get compositeScope(): CompositeComponent {
|
|
27
|
-
return this
|
|
27
|
+
return this.$scope as CompositeComponent;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
get content(): ComponentContent {
|
|
@@ -32,7 +32,7 @@ export class SlotComponent extends Component {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
get recontentScope(): IScope {
|
|
35
|
-
return this.compositeScope
|
|
35
|
+
return this.compositeScope.$scope;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -6,7 +6,7 @@ import { Component } from '../Component';
|
|
|
6
6
|
|
|
7
7
|
class IfComponent extends Component<CIfNode> {
|
|
8
8
|
get content() {
|
|
9
|
-
return this.
|
|
9
|
+
return this.$impl.condition ? this.node.then : this.node.else;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -43,7 +43,7 @@ export class CIfNode extends CNode<IfComponent> {
|
|
|
43
43
|
} else if (expr.slice(0, 5) === 'slot(') {
|
|
44
44
|
const slotId = expr.slice(5, -1);
|
|
45
45
|
// DO NOT place inside iterations.
|
|
46
|
-
this.addPropertyResolver((c: IComponent) => (c
|
|
46
|
+
this.addPropertyResolver((c: IComponent) => (c.$scope as CompositeComponent).slotContent?.(slotId), 'condition');
|
|
47
47
|
} else {
|
|
48
48
|
this.addPropertyResolver(compileExpression(expr[0] === '{' ? expr : `{${expr}}`), 'condition');
|
|
49
49
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Platform } from '../Platform';
|
|
2
1
|
import { CNode } from '../CNode';
|
|
3
2
|
import { compileNodes } from '../compileNode';
|
|
4
3
|
import { Component } from '../Component';
|
|
@@ -9,13 +8,13 @@ export class ElementComponent extends Component<CElementNode> {
|
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
createImplementation(initials: Hash): IComponentImplementation {
|
|
12
|
-
return
|
|
11
|
+
return this.arrmatura.platform.createElement(this.node.tag, initials, this);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export class TextElementComponent extends Component<CTextElementNode> {
|
|
17
16
|
createImplementation(initials: Hash) {
|
|
18
|
-
return
|
|
17
|
+
return this.arrmatura.platform.createTextElement(initials, this);
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
|
|
@@ -10,9 +10,7 @@ class ForComponent extends Component<CForNode> {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
get content() {
|
|
13
|
-
const
|
|
14
|
-
state: { each },
|
|
15
|
-
} = this;
|
|
13
|
+
const each: any = this.$impl.each;
|
|
16
14
|
const itemNode = this.node.itemNode;
|
|
17
15
|
const nodes: ComponentContent = new Map();
|
|
18
16
|
this.pkHash = {};
|
|
@@ -62,12 +60,12 @@ class ItemComponent extends Component<CItemNode> {
|
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
emit(key: string, data: Delta): void {
|
|
65
|
-
return this
|
|
63
|
+
return this.$scope.emit(key, data);
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
get(propId: string) {
|
|
69
67
|
const iName: string = this.node.itemName;
|
|
70
|
-
const value = propId.startsWith(iName + '.') || propId === iName ? super.get(propId) : this
|
|
68
|
+
const value = propId.startsWith(iName + '.') || propId === iName ? super.get(propId) : this.$scope.get(propId);
|
|
71
69
|
// this.log(propId, value);
|
|
72
70
|
return value;
|
|
73
71
|
}
|
package/core/cnodes/routing.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { Component } from '../Component';
|
|
|
4
4
|
|
|
5
5
|
export class DynamicTagComponent extends Component<CDynamicTagNode> {
|
|
6
6
|
get content(): ComponentContent | undefined {
|
|
7
|
-
const
|
|
7
|
+
const tag = this.$impl.tag;
|
|
8
8
|
const uid = this.node.uid + ':' + tag;
|
|
9
9
|
return new Map([[uid, Object.assign(compileNode(Object.assign(this.node.xml, { tag })), { uid })]]);
|
|
10
10
|
}
|
package/core/index.ts
CHANGED
package/core/utils.ts
CHANGED
package/core-web/attributes.ts
CHANGED
|
@@ -12,37 +12,32 @@ const setListener = ($: IElement, key: string, e: DomNode, v: unknown) => {
|
|
|
12
12
|
setAttribute($, key, null);
|
|
13
13
|
} else {
|
|
14
14
|
setAttribute($, key, (ev: Event) => {
|
|
15
|
-
|
|
15
|
+
$[fnKey]({ ...e.$dataset }, ev);
|
|
16
16
|
return false;
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
export function setAttribute($: IElement, key: string, value: null | string |
|
|
20
|
+
export function setAttribute($: IElement, key: string, value: null | string | ((ev: any) => any)) {
|
|
21
21
|
if (value != null) {
|
|
22
22
|
if (typeof value === 'function') {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
value(...args);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
if (!$.listeners) {
|
|
29
|
-
$.listeners = new Map();
|
|
23
|
+
if (!$.$listeners) {
|
|
24
|
+
$.$listeners = new Map();
|
|
30
25
|
}
|
|
31
|
-
if (
|
|
26
|
+
if (!$.$listeners.has(key)) {
|
|
32
27
|
const [akey, ekey = akey] = key.split(':');
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
$.$element.addEventListener(ekey, value, false);
|
|
29
|
+
$.$listeners.set(key, value);
|
|
35
30
|
}
|
|
36
31
|
} else {
|
|
37
|
-
|
|
32
|
+
$.$element.setAttribute(key, value);
|
|
38
33
|
}
|
|
39
34
|
} else {
|
|
40
|
-
if (
|
|
35
|
+
if ($.$listeners?.has(key)) {
|
|
41
36
|
const [akey, ekey = akey] = key.split(':');
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
$.$element.removeEventListener(ekey, $.$listeners.get(key));
|
|
38
|
+
$.$listeners.delete(key);
|
|
44
39
|
} else {
|
|
45
|
-
|
|
40
|
+
$.$element.removeAttribute(key);
|
|
46
41
|
}
|
|
47
42
|
}
|
|
48
43
|
}
|
|
@@ -57,9 +52,8 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
57
52
|
value: (_, e, v) => (e.value = v == null ? '' : v),
|
|
58
53
|
checked: (_, e, v) => (e.checked = !!v),
|
|
59
54
|
|
|
60
|
-
init: (
|
|
61
|
-
|
|
62
|
-
$.init = () => fn(e, $);
|
|
55
|
+
init: () => {
|
|
56
|
+
// do nothing
|
|
63
57
|
},
|
|
64
58
|
data: function (_, e, u) {
|
|
65
59
|
const v = u as Hash;
|
|
@@ -90,7 +84,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
90
84
|
const h = !v
|
|
91
85
|
? null
|
|
92
86
|
: (ev: TouchEvent & { pageX: number; pageY: number }) => {
|
|
93
|
-
|
|
87
|
+
$.touchstart(
|
|
94
88
|
{
|
|
95
89
|
...e.$dataset,
|
|
96
90
|
x: ev.pageX || ev.changedTouches[0].screenX,
|
|
@@ -126,7 +120,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
126
120
|
data.yy = ev.pageY || ev.changedTouches[0].screenY;
|
|
127
121
|
data.dx = data.xx - data.x;
|
|
128
122
|
data.dy = data.yy - data.y;
|
|
129
|
-
|
|
123
|
+
$.touch(data, ev);
|
|
130
124
|
}
|
|
131
125
|
|
|
132
126
|
return false;
|
|
@@ -145,8 +139,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
145
139
|
? null
|
|
146
140
|
: (ev: KeyboardEvent) => {
|
|
147
141
|
if (ev.keyCode !== 13 && ev.keyCode !== 27) {
|
|
148
|
-
|
|
149
|
-
fn && fn({ value: e.value, ...e.$dataset }, ev);
|
|
142
|
+
$.keypress?.({ value: e.value, ...e.$dataset }, ev);
|
|
150
143
|
setTimeout(() => e.focus(), 0);
|
|
151
144
|
}
|
|
152
145
|
return false;
|
|
@@ -161,7 +154,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
161
154
|
? null
|
|
162
155
|
: (ev: KeyboardEvent) => {
|
|
163
156
|
if (ev.keyCode === 13) {
|
|
164
|
-
|
|
157
|
+
$.enter({ value: e.value, ...e.$dataset }, ev);
|
|
165
158
|
}
|
|
166
159
|
if (ev.keyCode === 13 || ev.keyCode === 27) {
|
|
167
160
|
e.blur();
|
|
@@ -177,7 +170,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
177
170
|
!v
|
|
178
171
|
? null
|
|
179
172
|
: (ev: Event) => {
|
|
180
|
-
|
|
173
|
+
$.change({ value: e.value, ...e.$dataset }, ev);
|
|
181
174
|
return false;
|
|
182
175
|
}
|
|
183
176
|
);
|
|
@@ -189,7 +182,7 @@ export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> =
|
|
|
189
182
|
!v
|
|
190
183
|
? null
|
|
191
184
|
: (ev: Event) => {
|
|
192
|
-
|
|
185
|
+
$.toggle({ value: e.checked, ...e.$dataset }, ev);
|
|
193
186
|
return false;
|
|
194
187
|
}
|
|
195
188
|
);
|
package/core-web/elements.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
+
import { decodeXmlEntities } from '../lib';
|
|
1
2
|
import { ATTR_SETTERS, setAttribute } from './attributes';
|
|
2
3
|
import { DomNode, IElement } from './type';
|
|
3
4
|
|
|
4
5
|
export class DomElement implements IComponentImplementation, IElement {
|
|
5
6
|
$: IComponent;
|
|
6
|
-
$
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
isDone: boolean = false;
|
|
10
|
-
listeners: any;
|
|
7
|
+
$element: DomNode;
|
|
8
|
+
$listeners: any;
|
|
9
|
+
|
|
11
10
|
init?: () => any;
|
|
11
|
+
[key: string]: unknown;
|
|
12
12
|
|
|
13
13
|
constructor(tag: string, _: Hash, $: IComponent) {
|
|
14
14
|
this.$ = $;
|
|
15
|
-
this
|
|
16
|
-
this
|
|
15
|
+
this.$element = document.createElement(tag) as DomNode;
|
|
16
|
+
this.$element.impl = this;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
done() {
|
|
20
|
-
this
|
|
21
|
-
this.$attributes = undefined;
|
|
20
|
+
this.$element?.parentElement?.removeChild(this.$element);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
stateChanged(changes: Map<string, any>) {
|
|
25
|
-
const attrs
|
|
26
|
-
const e = this
|
|
24
|
+
const attrs = this;
|
|
25
|
+
const e = this.$element;
|
|
27
26
|
// this.$.log('changes', changes)
|
|
28
27
|
changes.forEach((value, key) => {
|
|
28
|
+
if (key[0] === '$') return;
|
|
29
29
|
if (value !== attrs[key]) {
|
|
30
30
|
const setter = ATTR_SETTERS[key];
|
|
31
31
|
if (setter) {
|
|
@@ -45,20 +45,20 @@ export class DomElement implements IComponentImplementation, IElement {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export class DomTextElement implements IComponentImplementation {
|
|
48
|
-
element: Text;
|
|
48
|
+
$element: Text;
|
|
49
49
|
[key: string]: unknown;
|
|
50
50
|
|
|
51
51
|
constructor(attrs: Hash) {
|
|
52
|
-
this
|
|
52
|
+
this.$element = document.createTextNode(String(attrs.text || ''));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
done() {
|
|
56
|
-
this
|
|
56
|
+
this.$element.parentElement?.removeChild(this.$element);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
stateChanged(changes: Map<string, any>) {
|
|
60
60
|
if (changes.has('text')) {
|
|
61
|
-
this
|
|
61
|
+
this.$element.textContent = decodeXmlEntities(changes.get('text'));
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}
|
package/core-web/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CArrmaturaNode
|
|
1
|
+
import { CArrmaturaNode } from '../core';
|
|
2
2
|
import { WebPlatform } from './WebPlatform';
|
|
3
3
|
|
|
4
4
|
export type ArrmaturaOptionsForWeb = ArrmaturaOptions & {
|
|
@@ -7,12 +7,9 @@ export type ArrmaturaOptionsForWeb = ArrmaturaOptions & {
|
|
|
7
7
|
|
|
8
8
|
export function arrmatura(
|
|
9
9
|
template: string,
|
|
10
|
-
{ rootElement, pipes, functions = pipes, types, resources }: ArrmaturaOptionsForWeb
|
|
10
|
+
{ rootElement, pipes, functions = pipes, types, resources }: ArrmaturaOptionsForWeb & { pipes: Hash<Pipe> }
|
|
11
11
|
) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const node = new CArrmaturaNode(template, { functions, types, resources });
|
|
15
|
-
|
|
12
|
+
const node = new CArrmaturaNode(template, { functions, types, resources }, new WebPlatform(rootElement));
|
|
16
13
|
node.launch();
|
|
17
14
|
}
|
|
18
15
|
|
package/core-web/reflow.ts
CHANGED
|
@@ -13,14 +13,12 @@ function appendElt(e: DomNode, p: DomNode | HTMLElement, cursor?: DomNode): DomN
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function reflow($: IComponent, parent: DomNode | HTMLElement, cursor?: DomNode) {
|
|
16
|
-
if (
|
|
17
|
-
for (let p of
|
|
18
|
-
const e = p
|
|
16
|
+
if ($.$children) {
|
|
17
|
+
for (let p of $.$children.values()) {
|
|
18
|
+
const e = p.$impl.$element as DomNode;
|
|
19
19
|
if (e) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
cursor = appendElt(e, parent, cursor);
|
|
23
|
-
}
|
|
20
|
+
reflow(p, e);
|
|
21
|
+
cursor = appendElt(e, parent, cursor);
|
|
24
22
|
} else {
|
|
25
23
|
cursor = reflow(p, parent, cursor);
|
|
26
24
|
}
|
package/core-web/type.ts
CHANGED
|
@@ -11,9 +11,8 @@ export interface DomNode extends HTMLElement {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface IElement {
|
|
14
|
-
$attributes?: any;
|
|
15
14
|
init?: () => any;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
$listeners: any;
|
|
16
|
+
$element: DomNode;
|
|
17
|
+
[key: string]: any;
|
|
19
18
|
}
|