arrmatura 5.2.0 → 6.2.1

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.
Files changed (110) hide show
  1. package/index.ts +20 -0
  2. package/package.json +14 -44
  3. package/src/core/composition.ts +71 -0
  4. package/src/core/conditionals.ts +80 -0
  5. package/src/core/elementary.ts +40 -0
  6. package/src/core/fragment.ts +21 -0
  7. package/src/core/index.ts +19 -0
  8. package/src/core/iterations.ts +121 -0
  9. package/src/core/root.ts +46 -0
  10. package/src/core/routing.ts +37 -0
  11. package/src/core/selection.ts +57 -0
  12. package/src/core/slot.ts +36 -0
  13. package/src/ctx/Ctx.ts +424 -0
  14. package/src/ctx/CtxNode.ts +159 -0
  15. package/src/utils/compileExpression.ts +126 -0
  16. package/src/utils/stringify.ts +39 -0
  17. package/LICENSE +0 -21
  18. package/README.md +0 -54
  19. package/commons/auth/AuthService.ts +0 -111
  20. package/commons/auth/UserService.ts +0 -57
  21. package/commons/auth/index.ts +0 -5
  22. package/commons/auth/user.xml +0 -64
  23. package/commons/components/buttons.xml +0 -25
  24. package/commons/components/index.ts +0 -13
  25. package/commons/components/inputs.xml +0 -33
  26. package/commons/components/layouts.xml +0 -77
  27. package/commons/components/media.xml +0 -21
  28. package/commons/components/modal.xml +0 -37
  29. package/commons/components/navigation.xml +0 -73
  30. package/commons/components/popups.xml +0 -12
  31. package/commons/components/searchbar.xml +0 -54
  32. package/commons/components/table.xml +0 -140
  33. package/commons/components/toasts.xml +0 -18
  34. package/commons/components/viewport.xml +0 -48
  35. package/commons/forms/FieldItem.xml +0 -20
  36. package/commons/forms/FormController.ts +0 -87
  37. package/commons/forms/Item.ts +0 -132
  38. package/commons/forms/ItemCollectionController.ts +0 -113
  39. package/commons/forms/ItemController.ts +0 -91
  40. package/commons/forms/MultiEnumField.xml +0 -44
  41. package/commons/forms/MultivalueController.ts +0 -49
  42. package/commons/forms/NewItemController.ts +0 -46
  43. package/commons/forms/SmartareaField.xml +0 -51
  44. package/commons/forms/SuggestionController.ts +0 -80
  45. package/commons/forms/SuggestionField.xml +0 -28
  46. package/commons/forms/fields.xml +0 -151
  47. package/commons/forms/form.xml +0 -37
  48. package/commons/forms/index.ts +0 -29
  49. package/commons/index.ts +0 -6
  50. package/commons/services/ApiClientService.ts +0 -32
  51. package/commons/services/ErrorHandlingService.ts +0 -11
  52. package/commons/services/FirebaseService.ts +0 -185
  53. package/commons/services/GSheetsService.ts +0 -120
  54. package/commons/services/HeartbeatService.ts +0 -35
  55. package/commons/services/Invoke.ts +0 -29
  56. package/commons/services/JsonpService.ts +0 -18
  57. package/commons/services/Loader.ts +0 -17
  58. package/commons/services/MetadataService.ts +0 -50
  59. package/commons/services/NavigationService.ts +0 -74
  60. package/commons/services/Service.ts +0 -62
  61. package/commons/services/ServiceWorker.ts +0 -111
  62. package/commons/services/Storage.ts +0 -55
  63. package/commons/services/ToastService.ts +0 -61
  64. package/commons/services/index.ts +0 -13
  65. package/core/Arrmatura.ts +0 -79
  66. package/core/CNode.ts +0 -111
  67. package/core/Component.ts +0 -424
  68. package/core/cnodes/composition.ts +0 -100
  69. package/core/cnodes/conditionals.ts +0 -52
  70. package/core/cnodes/elementary.ts +0 -44
  71. package/core/cnodes/iterations.ts +0 -92
  72. package/core/cnodes/routing.ts +0 -25
  73. package/core/compileNode.ts +0 -39
  74. package/core/expression.ts +0 -73
  75. package/core/index.ts +0 -1
  76. package/core/register.ts +0 -43
  77. package/core/utils.ts +0 -23
  78. package/core-web/WebPlatform.ts +0 -25
  79. package/core-web/attributes.ts +0 -218
  80. package/core-web/elements.ts +0 -81
  81. package/core-web/index.ts +0 -28
  82. package/core-web/reflow.ts +0 -30
  83. package/core-web/support.ts +0 -27
  84. package/core-web/type.ts +0 -18
  85. package/docs/index.js +0 -485
  86. package/lib/array/arrayGroupBy.ts +0 -19
  87. package/lib/array/arraySortBy.ts +0 -49
  88. package/lib/array/arrayToObject.ts +0 -18
  89. package/lib/array/arrayish.ts +0 -7
  90. package/lib/array/index.ts +0 -4
  91. package/lib/crypto/index.ts +0 -25
  92. package/lib/date/index.ts +0 -127
  93. package/lib/func/curry.ts +0 -11
  94. package/lib/func/fx.ts +0 -56
  95. package/lib/func/identity.ts +0 -6
  96. package/lib/func/nextId.ts +0 -9
  97. package/lib/func/noop.ts +0 -6
  98. package/lib/geo/index.js +0 -22
  99. package/lib/index.ts +0 -17
  100. package/lib/object/index.ts +0 -69
  101. package/lib/parsing/codus.ts +0 -25
  102. package/lib/parsing/compiler.ts +0 -26
  103. package/lib/parsing/scalarParse.ts +0 -25
  104. package/lib/parsing/urls.ts +0 -91
  105. package/lib/parsing/xml.ts +0 -117
  106. package/lib/resources/l10n.ts +0 -40
  107. package/lib/resources/resources.ru.ts +0 -20
  108. package/lib/resources/resources.ts +0 -20
  109. package/lib/string/index.ts +0 -58
  110. package/lib/support/createListeners.ts +0 -12
package/core/Component.ts DELETED
@@ -1,424 +0,0 @@
1
- /* eslint-disable no-console */
2
- import { applyValue, methodName, stringifyState } from './utils';
3
- import { scalarParse } from '../lib';
4
- import { createListeners } from 'support/createListeners';
5
-
6
- /**
7
- * Runtime Component class.
8
- */
9
- export class Component<T extends INode = INode> implements IComponent, IScope {
10
- readonly $impl: IComponentImplementation;
11
-
12
- $children?: Map<Uid, IComponent>;
13
-
14
- readonly $scope: IScope;
15
- readonly #parent?: IComponent;
16
- readonly arrmatura: IArrmatura;
17
- #isInited: boolean = false;
18
- #isDone: boolean = false;
19
- #listeners?: Listeners<void>;
20
- #defered?: Array<ComponentProcedure> = [];
21
- #weak?: Map<any, any>;
22
- #refs?: Hash<Component>;
23
- #propFnMap?: Hash<Procedure>;
24
-
25
- constructor(readonly _node: INode, _parent?: IComponent, scope?: IScope) {
26
- this.$scope = scope || this;
27
- this.#parent = _parent;
28
- this.arrmatura = _parent?.arrmatura || (this as unknown as IArrmatura);
29
- this.$impl = this.createImplementation(this.getInitialState());
30
-
31
- if (this.refId) {
32
- this.$scope.addComponentReference(this.refId, this);
33
- }
34
- }
35
-
36
- get node(): T {
37
- return this._node as T;
38
- }
39
-
40
- get displayName(): string {
41
- return '🔹';
42
- }
43
-
44
- get uid() {
45
- return this.node.uid;
46
- }
47
-
48
- createImplementation(initials: Hash): IComponentImplementation {
49
- return { ...initials };
50
- }
51
-
52
- // --- State
53
-
54
- getInitialState(): Hash {
55
- return this.node.resolveInitialProps(this);
56
- }
57
-
58
- up(Δ: Delta | Promise<any>, force: boolean = false): null | Promise<any> {
59
- if (!Δ || this.#isDone) {
60
- return null;
61
- }
62
- if (Δ.then && Δ.catch) {
63
- return this.upAsync(Δ as Promise<any>);
64
- }
65
- let prom: Promise<any>[] | null = null;
66
- const changes = new Map<string, unknown>();
67
- Object.entries(Δ).forEach(([k, v]) => {
68
- if (v && v.then && v.catch) {
69
- const pv = v as Promise<any>;
70
- (prom || (prom = [])).push(this.upAsync(pv, k));
71
- } else if (k && typeof v !== 'undefined' && v !== this.$impl[k]) {
72
- changes.set(k, v);
73
- }
74
- });
75
-
76
- if (changes.size || force) {
77
- this.stateChanged(changes);
78
- this.recontent();
79
- if (this.refId) {
80
- this.notify();
81
- }
82
- }
83
- if (prom) {
84
- return Promise.all(prom).then((arr: object[]) => arr.reduce((a, b) => ({ ...a, ...b }), {}));
85
- }
86
- return null;
87
- }
88
-
89
- upAsync(promise: Promise<any>, key?: string): Promise<any> {
90
- const racer = this.raceCondition('set:' + key);
91
- if (key && key[0] !== '*') {
92
- const akey = key.replace('Promise', '');
93
- promise.then((val) => racer(() => this.up({ [akey]: val })));
94
- } else {
95
- promise.then((r: Delta) => racer(() => this.up(r)));
96
- }
97
- return promise;
98
- }
99
-
100
- stateChanged(changes: Map<string, unknown>) {
101
- if (this.$impl.stateChanged) {
102
- this.$impl.stateChanged(changes);
103
- } else {
104
- changes.forEach((v, k) => {
105
- const setter = this.$impl[methodName(k, 'set')];
106
- if (typeof setter === 'function') {
107
- setter.call(this.$impl, v);
108
- } else {
109
- this.$impl[k] = v;
110
- }
111
- });
112
- }
113
- }
114
-
115
- get(propId: string): unknown {
116
- const map = this.#propFnMap || (this.#propFnMap = {});
117
- let fn = map[propId];
118
- if (fn) {
119
- return fn();
120
- }
121
-
122
- const impl = this.$impl;
123
- const instant = impl[propId];
124
- if (instant && typeof instant === 'function') {
125
- const bound = instant.bind(impl);
126
- fn = () => bound;
127
- } else {
128
- const [pk, ...path] = propId.split('.');
129
- const gettr = impl[methodName(pk, 'get')];
130
-
131
- const fn0 = typeof gettr === 'function' ? () => gettr.call(impl) : () => impl[pk];
132
-
133
- fn = !path.length ? fn0 : () => path.reduce((r, p) => (r && p in r ? r[p] : undefined), fn0());
134
- }
135
-
136
- map[propId] = fn;
137
-
138
- return fn();
139
- }
140
-
141
- getFromScope(propId: string): unknown {
142
- return this.$scope.get(propId);
143
- }
144
-
145
- // --- Left Arrow.
146
-
147
- notify() {
148
- this.#listeners?.notify();
149
- }
150
-
151
- subscribe(target: Component, fn: (src: Component) => Delta): ComponentSubsription {
152
- const listeners = this.#listeners || (this.#listeners = createListeners());
153
- return {
154
- payload: fn(this),
155
- cancel: listeners.add(() => {
156
- try {
157
- const r = fn(this);
158
- // this.log('subscribe', r);
159
- target.up(r);
160
- } catch (ex) {
161
- this.logError('Notify ', ex);
162
- }
163
- }),
164
- };
165
- }
166
-
167
- connect(key: string, applicator: (x: unknown) => unknown): undefined | ComponentSubsription {
168
- const [refId, propId = '*'] = key.split('.');
169
- const ref = this.$scope.getByRef(refId) as Component;
170
- if (!ref) {
171
- this.logError('Connect: No such ref: ' + refId);
172
- return;
173
- }
174
- return ref.subscribe(this, (c: Component) => applyValue(propId === '*' ? c.$impl : c.get(propId), applicator));
175
- }
176
-
177
- // --- Right Arrow.
178
-
179
- emit(key: string, data: Delta): null | Promise<any> {
180
- if (!key || !key.includes('.')) {
181
- this.log('update:' + key, data, this.$impl);
182
- return this.up(key ? { [key]: data } : data);
183
- }
184
-
185
- const [refId, target] = key.split('.');
186
- try {
187
- const ref = this.getByRef(refId);
188
- if (!ref) {
189
- throw new Error('No such reference: ' + refId);
190
- }
191
-
192
- const propId = methodName(target, 'on');
193
- const impl = ref.$impl;
194
-
195
- const method = impl[propId];
196
- if (!method || !(typeof method === 'function')) {
197
- throw new Error('No such method ' + refId + '.' + propId);
198
- }
199
-
200
- const result = method.call(impl, data, impl, ref);
201
-
202
- this.log(refId + ':' + propId, result, data, impl);
203
- if (result) {
204
- const ret = ref.up(result);
205
- return ret;
206
- }
207
- } catch (ex) {
208
- this.logError('emit ' + key + ':', ex);
209
- }
210
- return null;
211
- }
212
-
213
- // --- Life-cycle hooks.
214
-
215
- init(initials: Delta) {
216
- if (this.#isDone || this.#isInited) {
217
- return;
218
- }
219
- this.#isInited = true;
220
- const all: Array<Promise<any>> = [];
221
- const initializers = this.node.initializers;
222
- if (initializers?.length) {
223
- initializers
224
- .map((f) => f(this))
225
- .forEach((r) => {
226
- if (!r) return;
227
- const { payload, cancel } = r;
228
- if (cancel) {
229
- this.defer(cancel);
230
- }
231
- if (payload && payload.then) {
232
- all.push(payload as unknown as Promise<any>);
233
- } else {
234
- Object.assign(initials, payload);
235
- }
236
- });
237
- }
238
-
239
- if (all.length) {
240
- Promise.all(all).then((args) => {
241
- this.up(
242
- args.reduce((r, e) => Object.assign(r, e), initials),
243
- true
244
- );
245
- if (this.$impl.init) {
246
- const d = this.$impl.init(this);
247
- if (d) {
248
- this.up(d);
249
- }
250
- }
251
- });
252
- } else {
253
- this.up(initials, true);
254
- if (this.$impl.init) {
255
- const d = this.$impl.init(this);
256
- if (d) {
257
- this.up(d);
258
- }
259
- }
260
- }
261
- return this;
262
- }
263
-
264
- done() {
265
- if (this.#isDone) {
266
- return;
267
- }
268
- this.#isDone = true;
269
-
270
- this.$impl.done?.(this);
271
-
272
- const parent = this.#parent;
273
- this.#parent = undefined;
274
-
275
- this.$children?.forEach((c) => c.done());
276
-
277
- parent?.$children?.delete(this.uid);
278
-
279
- this.#defered?.forEach((f) => f(this));
280
- this.#defered = undefined;
281
-
282
- this.$impl.$ = null;
283
- }
284
-
285
- // -- Contents --------------------------------------------------------
286
-
287
- get content(): ComponentContent | undefined {
288
- return this.node.content;
289
- }
290
-
291
- get recontentScope(): IScope {
292
- return this.$scope;
293
- }
294
-
295
- setupChildren(children: ComponentChildren) {
296
- this.$children = children;
297
-
298
- children.forEach((e) => e.settleAsChild());
299
- }
300
-
301
- settleAsChild() {
302
- if (!this.#isInited) {
303
- this.init(this.node.resolveInitialProps(this));
304
- } else {
305
- this.up(this.node.resolveProps(this), true);
306
- }
307
- }
308
-
309
- recontent() {
310
- const scope = this.recontentScope;
311
- const nodes = this.content;
312
-
313
- this.arrmatura.requestReflow();
314
-
315
- this.$children?.forEach((e, uid) => {
316
- if (!nodes?.get(uid)) {
317
- e.done();
318
- }
319
- });
320
-
321
- const children = new Map<Uid, IComponent>();
322
-
323
- nodes?.forEach((node, uid) => {
324
- const e = this.$children?.get(uid) || node.createComponent(this, scope);
325
- children.set(e.uid, e);
326
- });
327
-
328
- this.setupChildren(children);
329
- }
330
-
331
- // --- Referencing.
332
-
333
- get refId() {
334
- return this._node.refId;
335
- }
336
-
337
- get refs(): Hash<Component> {
338
- return this.#refs || (this.#refs = {});
339
- }
340
-
341
- getByRef(refId: string): Component | null {
342
- if (refId === 'this') {
343
- return this;
344
- }
345
- const local = this.refs[refId] || null;
346
- if (local) {
347
- return local as Component;
348
- }
349
- const ref = this === this.$scope ? null : this.$scope.getByRef(refId);
350
- return ref as Component;
351
- }
352
-
353
- addComponentReference(refId: string, c: Component) {
354
- this.refs[refId] = c;
355
- }
356
-
357
- // --- Pipes ----------------------------------------------------------------
358
-
359
- pipe(key: string) {
360
- return this.arrmatura.pipe(key);
361
- }
362
-
363
- applyPipe(key: string, value: unknown) {
364
- try {
365
- const [id, ...args] = key.split(':');
366
- const fn = this.pipe(id);
367
- return fn.apply(this, [
368
- value,
369
- ...args.map((a) => (a[0] === '@' ? this.getFromScope(a.slice(1)) : scalarParse(a))),
370
- ]);
371
- } catch (ex) {
372
- this.logError('ERROR: pipe ' + key, ex);
373
- return value;
374
- }
375
- }
376
-
377
- // --- Routines -------------------------
378
-
379
- raceCondition(key: string) {
380
- const COUNTERS = this.#weak || (this.#weak = new Map());
381
- let counter = 1 + (COUNTERS.get(key) || 0);
382
- COUNTERS.set(key, counter);
383
- return (fn: Procedure) => {
384
- if (counter === COUNTERS.get(key)) {
385
- counter = 0;
386
- return fn();
387
- }
388
- };
389
- }
390
-
391
- defer(fn: ComponentProcedure) {
392
- if (fn && typeof fn === 'function') {
393
- (this.#defered || (this.#defered = [])).push(fn);
394
- }
395
- }
396
-
397
- log(val: any, ...args: unknown[]) {
398
- console.log('' + this.displayName + ':' + this.uid, val, ...args);
399
- return val;
400
- }
401
-
402
- logError(...args: unknown[]) {
403
- console.error('⛔ ERROR: ' + this.displayName + ':' + this.uid, ...args);
404
- }
405
-
406
- res(key: string) {
407
- return this.arrmatura.res(key);
408
- }
409
-
410
- stringify(tab = '') {
411
- const { uid, displayName: tag = uid, $impl: impl, $children: children } = this;
412
- if (tag === '#text') {
413
- return `${tab}` + impl.text;
414
- }
415
- const ssubs: string = children?.size
416
- ? [...children.values()].map((c) => (c as Component).stringify(` ${tab}`)).join('\n')
417
- : '';
418
- return `${tab}<${tag}${stringifyState(impl)}` + (!ssubs ? '/>' : `>\n${ssubs}\n${tab}</${tag}>`);
419
- }
420
-
421
- toString() {
422
- return this.stringify();
423
- }
424
- }
@@ -1,100 +0,0 @@
1
- import { CNode } from '../CNode';
2
- import { compileNodes } from '../compileNode';
3
- import { Component } from '../Component';
4
- import { ComponentDefinition, getByTag } from '../register';
5
-
6
- const compileSlots = (tag: string, nodes?: XmlNode[]) => {
7
- const slots =
8
- nodes?.reduce((groups, e) => {
9
- const isSlot = e.tag.startsWith(tag + ':');
10
- const gId = isSlot ? e.tag.split(':')[1] : 'default';
11
- groups[gId] = (groups[gId] || []).concat(isSlot ? e.nodes || [] : e);
12
- return groups;
13
- }, {} as Hash<XmlNode[]>) || {};
14
-
15
- return Object.entries(slots).reduce((groups, [gId, nodes]) => {
16
- groups[gId] = compileNodes(nodes);
17
- return groups;
18
- }, {} as Hash<ComponentContent>);
19
- };
20
-
21
- export class SlotComponent extends Component {
22
- get displayName(): string {
23
- return '🔸';
24
- }
25
-
26
- get compositeScope(): CompositeComponent {
27
- return this.$scope as CompositeComponent;
28
- }
29
-
30
- get content(): ComponentContent {
31
- return this.compositeScope.slotContent((this.node as CSlotNode).id);
32
- }
33
-
34
- get recontentScope(): IScope {
35
- return this.compositeScope.$scope;
36
- }
37
- }
38
-
39
- export class CSlotNode extends CNode<SlotComponent> {
40
- id?: string;
41
-
42
- constructor(x: XmlNode) {
43
- super();
44
- this.id = x.attrs?.id as string;
45
- }
46
-
47
- get ComponentConstructor() {
48
- return SlotComponent;
49
- }
50
- }
51
-
52
- export class CompositeComponent extends Component<CCompositeNode> {
53
- get displayName(): string {
54
- return '💠' + this.node.definition.tag;
55
- }
56
-
57
- get content() {
58
- return this.node.definition.content;
59
- }
60
-
61
- get recontentScope(): Component {
62
- return this;
63
- }
64
-
65
- slotContent(slotId?: string): ComponentContent {
66
- return this.node.slotContent[slotId || 'default'];
67
- }
68
-
69
- createImplementation(initials: Hash) {
70
- return new this.node.definition.Ctor(initials, this);
71
- }
72
- }
73
-
74
- export class CCompositeNode extends CNode<CompositeComponent> {
75
- Ctor: any;
76
- slotContent: Hash<ComponentContent>;
77
- definition: ComponentDefinition;
78
-
79
- constructor({ tag, attrs, nodes }: XmlNode) {
80
- super();
81
- this.definition = getByTag(tag);
82
- this.compileAttributes(attrs);
83
- this.slotContent = compileSlots(tag, nodes);
84
- }
85
-
86
- get ComponentConstructor() {
87
- return CompositeComponent;
88
- }
89
- }
90
-
91
- export class CFragmentNode extends CNode<Component> {
92
- constructor({ nodes }: XmlNode) {
93
- super();
94
- this.content = compileNodes(nodes);
95
- }
96
-
97
- get ComponentConstructor() {
98
- return Component;
99
- }
100
- }
@@ -1,52 +0,0 @@
1
- import { CNode } from '../CNode';
2
- import { compileExpression } from '../expression';
3
- import { compileNodes } from '../compileNode';
4
- import { CompositeComponent } from './composition';
5
- import { Component } from '../Component';
6
-
7
- class IfComponent extends Component<CIfNode> {
8
- get content() {
9
- return !!this.$impl.condition ? this.node.then : this.node.else;
10
- }
11
- }
12
-
13
- export class CIfNode extends CNode<IfComponent> {
14
- else?: ComponentContent;
15
- then?: ComponentContent;
16
- constructor(x: XmlNode, expr: string) {
17
- super();
18
- this.compileCondition(expr);
19
- this.compileBranches(x);
20
- }
21
- get ComponentConstructor() {
22
- return IfComponent;
23
- }
24
- compileBranches(x: XmlNode) {
25
- const { nodes } = x;
26
-
27
- let $then: XmlNode[] | undefined = [x];
28
- if (nodes?.length) {
29
- const ifElse = nodes.find((e) => e.tag === 'ui:else');
30
- const ifThen = nodes.find((e) => e.tag === 'ui:then');
31
- if (ifElse) {
32
- this.else = compileNodes(ifElse.nodes);
33
- $then = ifThen ? ifThen.nodes : [Object.assign(x, { nodes: nodes.filter((e) => e !== ifElse) })];
34
- } else if (ifThen) {
35
- $then = ifThen.nodes;
36
- }
37
- }
38
- this.then = compileNodes($then);
39
- }
40
- compileCondition(expr: string): void {
41
- if (expr[0] === '<' && expr[1] === '-') {
42
- this.addPropertyConnector(expr.slice(2), (condition: unknown) => ({ condition }));
43
- } else if (expr.slice(0, 5) === 'slot(') {
44
- const slotId = expr.slice(5, -1);
45
- // DO NOT place inside iterations.
46
- this.addPropertyResolver((c: IComponent) => (c.$scope as CompositeComponent).slotContent?.(slotId), 'condition');
47
- } else {
48
- const resolver = compileExpression(expr[0] === '{' ? expr : `{${expr}}`);
49
- this.addPropertyResolver((c) => !!resolver(c), 'condition');
50
- }
51
- }
52
- }
@@ -1,44 +0,0 @@
1
- import { CNode } from '../CNode';
2
- import { compileNodes } from '../compileNode';
3
- import { Component } from '../Component';
4
-
5
- export class ElementComponent extends Component<CElementNode> {
6
- get displayName(): string {
7
- return this.node.tag;
8
- }
9
-
10
- createImplementation(initials: Hash): IComponentImplementation {
11
- return this.arrmatura.platform.createElement(this.node.tag, initials, this);
12
- }
13
- }
14
-
15
- export class TextElementComponent extends Component<CTextElementNode> {
16
- createImplementation(initials: Hash) {
17
- return this.arrmatura.platform.createTextElement(initials, this);
18
- }
19
- }
20
-
21
- export class CElementNode extends CNode<ElementComponent> {
22
- constructor(x: XmlNode) {
23
- super();
24
- this.tag = x.tag;
25
- this.content = compileNodes(x.nodes);
26
- this.compileAttributes(x.attrs);
27
- }
28
-
29
- get ComponentConstructor() {
30
- return ElementComponent;
31
- }
32
- }
33
-
34
- export class CTextElementNode extends CNode<TextElementComponent> {
35
- constructor(x: XmlNode) {
36
- super();
37
- this.tag = x.tag;
38
- this.compileAttributes(x.attrs);
39
- }
40
-
41
- get ComponentConstructor() {
42
- return TextElementComponent;
43
- }
44
- }
@@ -1,92 +0,0 @@
1
- import { CNode } from '../CNode';
2
- import { compileNodes } from '../compileNode';
3
- import { Component } from '../Component';
4
-
5
- class ForComponent extends Component<CForNode> {
6
- pkHash: Hash<Datum> = {};
7
-
8
- get displayName(): string {
9
- return '🔹';
10
- }
11
-
12
- get content() {
13
- const each: any = this.$impl.each;
14
- const itemNode = this.node.itemNode;
15
- const nodes: ComponentContent = new Map();
16
- this.pkHash = {};
17
- if (each?.length) {
18
- if (!each.forEach) {
19
- throw new Error('[ui:for] Items has no forEach() ' + each);
20
- }
21
- each.forEach((datum: Datum) => {
22
- const id = datum.id;
23
- if (id == null) {
24
- console.error('ERROR: empty item id: ', datum);
25
- return;
26
- }
27
- const pk = String(id);
28
- if (this.pkHash[pk]) {
29
- console.error('ERROR: duplicate item id: ' + pk, datum);
30
- return;
31
- }
32
- this.pkHash[pk] = datum;
33
- const inode = itemNode.cloneWithDatum(datum).addPropertyResolver(() => this.pkHash[pk], itemNode.itemName);
34
- nodes.set(inode.uid, inode);
35
- });
36
- }
37
- return nodes;
38
- }
39
- }
40
-
41
- export class CForNode extends CNode<ForComponent> {
42
- itemNode: CItemNode;
43
- constructor(x: XmlNode, [itemName, prep, expr = prep]: string[]) {
44
- super();
45
- this.itemNode = new CItemNode(itemName, compileNodes([x]));
46
- this.compileAttribute('each', '{:<'.includes(expr[0]) ? expr : `{${expr}}`);
47
- }
48
-
49
- get ComponentConstructor() {
50
- return ForComponent;
51
- }
52
- }
53
-
54
- class ItemComponent extends Component<CItemNode> {
55
- get displayName(): string {
56
- return '🔹';
57
- }
58
- get recontentScope(): Component {
59
- return this;
60
- }
61
-
62
- emit(key: string, data: Delta): void {
63
- return this.$scope.emit(key, data);
64
- }
65
-
66
- get(propId: string) {
67
- const iName: string = this.node.itemName;
68
- const value = propId.startsWith(iName + '.') || propId === iName ? super.get(propId) : this.$scope.get(propId);
69
- // this.log(propId, value);
70
- return value;
71
- }
72
- }
73
-
74
- export class CItemNode extends CNode<ItemComponent> {
75
- itemName: string;
76
- constructor(itemName: string, content?: ComponentContent) {
77
- super();
78
- this.itemName = itemName;
79
- this.content = content;
80
- }
81
-
82
- cloneWithDatum(datum: Datum) {
83
- const uid = this.uid + '#' + datum.id;
84
- return Object.assign(new CItemNode(this.itemName, this.content), {
85
- uid,
86
- });
87
- }
88
-
89
- get ComponentConstructor() {
90
- return ItemComponent;
91
- }
92
- }