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.
- package/index.ts +20 -0
- package/package.json +14 -44
- package/src/core/composition.ts +71 -0
- package/src/core/conditionals.ts +80 -0
- package/src/core/elementary.ts +40 -0
- package/src/core/fragment.ts +21 -0
- package/src/core/index.ts +19 -0
- package/src/core/iterations.ts +121 -0
- package/src/core/root.ts +46 -0
- package/src/core/routing.ts +37 -0
- package/src/core/selection.ts +57 -0
- package/src/core/slot.ts +36 -0
- package/src/ctx/Ctx.ts +424 -0
- package/src/ctx/CtxNode.ts +159 -0
- package/src/utils/compileExpression.ts +126 -0
- package/src/utils/stringify.ts +39 -0
- package/LICENSE +0 -21
- package/README.md +0 -54
- package/commons/auth/AuthService.ts +0 -111
- package/commons/auth/UserService.ts +0 -57
- package/commons/auth/index.ts +0 -5
- package/commons/auth/user.xml +0 -64
- package/commons/components/buttons.xml +0 -25
- package/commons/components/index.ts +0 -13
- package/commons/components/inputs.xml +0 -33
- package/commons/components/layouts.xml +0 -77
- package/commons/components/media.xml +0 -21
- package/commons/components/modal.xml +0 -37
- package/commons/components/navigation.xml +0 -73
- package/commons/components/popups.xml +0 -12
- package/commons/components/searchbar.xml +0 -54
- package/commons/components/table.xml +0 -140
- package/commons/components/toasts.xml +0 -18
- package/commons/components/viewport.xml +0 -48
- package/commons/forms/FieldItem.xml +0 -20
- package/commons/forms/FormController.ts +0 -87
- package/commons/forms/Item.ts +0 -132
- package/commons/forms/ItemCollectionController.ts +0 -113
- package/commons/forms/ItemController.ts +0 -91
- package/commons/forms/MultiEnumField.xml +0 -44
- package/commons/forms/MultivalueController.ts +0 -49
- package/commons/forms/NewItemController.ts +0 -46
- package/commons/forms/SmartareaField.xml +0 -51
- package/commons/forms/SuggestionController.ts +0 -80
- package/commons/forms/SuggestionField.xml +0 -28
- package/commons/forms/fields.xml +0 -151
- package/commons/forms/form.xml +0 -37
- package/commons/forms/index.ts +0 -29
- package/commons/index.ts +0 -6
- package/commons/services/ApiClientService.ts +0 -32
- package/commons/services/ErrorHandlingService.ts +0 -11
- package/commons/services/FirebaseService.ts +0 -185
- package/commons/services/GSheetsService.ts +0 -120
- package/commons/services/HeartbeatService.ts +0 -35
- package/commons/services/Invoke.ts +0 -29
- package/commons/services/JsonpService.ts +0 -18
- package/commons/services/Loader.ts +0 -17
- package/commons/services/MetadataService.ts +0 -50
- package/commons/services/NavigationService.ts +0 -74
- package/commons/services/Service.ts +0 -62
- package/commons/services/ServiceWorker.ts +0 -111
- package/commons/services/Storage.ts +0 -55
- package/commons/services/ToastService.ts +0 -61
- package/commons/services/index.ts +0 -13
- package/core/Arrmatura.ts +0 -79
- package/core/CNode.ts +0 -111
- package/core/Component.ts +0 -424
- package/core/cnodes/composition.ts +0 -100
- package/core/cnodes/conditionals.ts +0 -52
- package/core/cnodes/elementary.ts +0 -44
- package/core/cnodes/iterations.ts +0 -92
- package/core/cnodes/routing.ts +0 -25
- package/core/compileNode.ts +0 -39
- package/core/expression.ts +0 -73
- package/core/index.ts +0 -1
- package/core/register.ts +0 -43
- package/core/utils.ts +0 -23
- package/core-web/WebPlatform.ts +0 -25
- package/core-web/attributes.ts +0 -218
- package/core-web/elements.ts +0 -81
- package/core-web/index.ts +0 -28
- package/core-web/reflow.ts +0 -30
- package/core-web/support.ts +0 -27
- package/core-web/type.ts +0 -18
- package/docs/index.js +0 -485
- package/lib/array/arrayGroupBy.ts +0 -19
- package/lib/array/arraySortBy.ts +0 -49
- package/lib/array/arrayToObject.ts +0 -18
- package/lib/array/arrayish.ts +0 -7
- package/lib/array/index.ts +0 -4
- package/lib/crypto/index.ts +0 -25
- package/lib/date/index.ts +0 -127
- package/lib/func/curry.ts +0 -11
- package/lib/func/fx.ts +0 -56
- package/lib/func/identity.ts +0 -6
- package/lib/func/nextId.ts +0 -9
- package/lib/func/noop.ts +0 -6
- package/lib/geo/index.js +0 -22
- package/lib/index.ts +0 -17
- package/lib/object/index.ts +0 -69
- package/lib/parsing/codus.ts +0 -25
- package/lib/parsing/compiler.ts +0 -26
- package/lib/parsing/scalarParse.ts +0 -25
- package/lib/parsing/urls.ts +0 -91
- package/lib/parsing/xml.ts +0 -117
- package/lib/resources/l10n.ts +0 -40
- package/lib/resources/resources.ru.ts +0 -20
- package/lib/resources/resources.ts +0 -20
- package/lib/string/index.ts +0 -58
- package/lib/support/createListeners.ts +0 -12
package/core/cnodes/routing.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { CNode } from '../CNode';
|
|
2
|
-
import { compileNode } from '../compileNode';
|
|
3
|
-
import { Component } from '../Component';
|
|
4
|
-
|
|
5
|
-
export class DynamicTagComponent extends Component<CDynamicTagNode> {
|
|
6
|
-
get content(): ComponentContent | undefined {
|
|
7
|
-
const tag = this.$impl.tag;
|
|
8
|
-
const uid = this.node.uid + ':' + tag;
|
|
9
|
-
return new Map([[uid, Object.assign(compileNode(Object.assign(this.node.xml, { tag })), { uid })]]);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class CDynamicTagNode extends CNode<DynamicTagComponent> {
|
|
14
|
-
xml: XmlNode & { tag: string };
|
|
15
|
-
|
|
16
|
-
constructor(xml: XmlNode, expr: string) {
|
|
17
|
-
super();
|
|
18
|
-
this.compileAttribute('tag', expr);
|
|
19
|
-
this.xml = xml;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get ComponentConstructor() {
|
|
23
|
-
return DynamicTagComponent;
|
|
24
|
-
}
|
|
25
|
-
}
|
package/core/compileNode.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { CCompositeNode, CFragmentNode, CSlotNode } from './cnodes/composition';
|
|
2
|
-
import { CDynamicTagNode } from './cnodes/routing';
|
|
3
|
-
import { CElementNode, CTextElementNode } from './cnodes/elementary';
|
|
4
|
-
import { CForNode } from './cnodes/iterations';
|
|
5
|
-
import { CIfNode } from './cnodes/conditionals';
|
|
6
|
-
|
|
7
|
-
export const compileNode = (x: XmlNode): INode => {
|
|
8
|
-
const { tag, attrs } = x;
|
|
9
|
-
const each = attrs?.['ui:for'];
|
|
10
|
-
if (each) {
|
|
11
|
-
delete attrs['ui:for'];
|
|
12
|
-
return new CForNode(x, String(each).trim().split(' '));
|
|
13
|
-
}
|
|
14
|
-
const when = attrs?.['ui:if'];
|
|
15
|
-
if (when) {
|
|
16
|
-
delete attrs['ui:if'];
|
|
17
|
-
return new CIfNode(x, String(when));
|
|
18
|
-
}
|
|
19
|
-
if (tag === 'ui:tag') {
|
|
20
|
-
const expr = attrs?.['tag'] || tag;
|
|
21
|
-
delete attrs?.['tag'];
|
|
22
|
-
return new CDynamicTagNode(x, String(expr));
|
|
23
|
-
}
|
|
24
|
-
if (tag === 'ui:slot') {
|
|
25
|
-
return new CSlotNode(x);
|
|
26
|
-
}
|
|
27
|
-
if (tag === 'ui:fragment') {
|
|
28
|
-
return new CFragmentNode(x);
|
|
29
|
-
}
|
|
30
|
-
if (tag === '#text') {
|
|
31
|
-
return new CTextElementNode(x);
|
|
32
|
-
}
|
|
33
|
-
if (tag[0].match(/[A-Z]/)) return new CCompositeNode(x);
|
|
34
|
-
|
|
35
|
-
return new CElementNode(x);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const compileNodes = (x?: XmlNode[] | null): ComponentContent =>
|
|
39
|
-
new Map<Uid, INode>(x?.map(compileNode).map((c) => [c.uid, c]) || []);
|
package/core/expression.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { scalarParse } from '../lib';
|
|
2
|
-
|
|
3
|
-
const RE_SINGLE_PLACEHOLDER = /^\{([^}]+)\}$/;
|
|
4
|
-
|
|
5
|
-
const RE_PLACEHOLDER = /\{([^}]+)\}/g;
|
|
6
|
-
|
|
7
|
-
const withNoPipes = (_: unknown, v: unknown) => v;
|
|
8
|
-
|
|
9
|
-
const splitExpression = (v: Expression) => {
|
|
10
|
-
return v.split('|').map((s) => s.trim());
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export function withPipes(pipes: string[]) {
|
|
14
|
-
return !pipes.length
|
|
15
|
-
? withNoPipes
|
|
16
|
-
: (c: IComponent, initialValue: unknown) => pipes.reduce((r, pk) => c.applyPipe(pk, r), initialValue);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function compilePipeExpression(v: Expression) {
|
|
20
|
-
const [key, ...pipes] = splitExpression(v);
|
|
21
|
-
return { key, pipec: withPipes(pipes) };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function stringInterpolation(v: string, fnx: Array<(c: IComponent) => unknown> = []) {
|
|
25
|
-
const pattern = v.trim().replace(RE_PLACEHOLDER, (_: string, expr: string) => {
|
|
26
|
-
fnx.push(placeholder(expr));
|
|
27
|
-
return '{{' + (fnx.length - 1) + '}}';
|
|
28
|
-
});
|
|
29
|
-
return !fnx.length
|
|
30
|
-
? (_: IComponent) => pattern
|
|
31
|
-
: (c: IComponent) =>
|
|
32
|
-
pattern
|
|
33
|
-
.replace(/\{\{(\d+)\}\}/g, (_: string, idx: string) => {
|
|
34
|
-
const r = fnx[Number(idx)](c);
|
|
35
|
-
return !r && r !== 0 ? '' : String(r);
|
|
36
|
-
})
|
|
37
|
-
.replace(/\s+/g, ' ');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function resourceExpression(expr: string) {
|
|
41
|
-
const { key, pipec } = compilePipeExpression(expr);
|
|
42
|
-
const intrpltn = stringInterpolation(key);
|
|
43
|
-
return !pipec.length ? (c: IComponent) => c.res(intrpltn(c)) : (c: IComponent) => pipec(c, c.res(intrpltn(c)));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function placeholder(expr: string) {
|
|
47
|
-
const { key, pipec } = compilePipeExpression(expr);
|
|
48
|
-
const fn =
|
|
49
|
-
key[0] === ':'
|
|
50
|
-
? (
|
|
51
|
-
(k) => (c: IComponent) =>
|
|
52
|
-
c.res(k)
|
|
53
|
-
)(key.slice(1))
|
|
54
|
-
: (c: IComponent) => c.getFromScope(key);
|
|
55
|
-
return !pipec.length ? fn : (c: IComponent) => pipec(c, fn(c));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function compileExpression(v: unknown) {
|
|
59
|
-
if (typeof v !== 'string') {
|
|
60
|
-
return () => v;
|
|
61
|
-
}
|
|
62
|
-
if (v[0] === ':') {
|
|
63
|
-
return resourceExpression(v.slice(1).trim());
|
|
64
|
-
}
|
|
65
|
-
if (!v.includes('{')) {
|
|
66
|
-
const vv = scalarParse(v);
|
|
67
|
-
return () => vv;
|
|
68
|
-
}
|
|
69
|
-
if (v.match(RE_SINGLE_PLACEHOLDER)) {
|
|
70
|
-
return placeholder(v.slice(1, -1).trim());
|
|
71
|
-
}
|
|
72
|
-
return stringInterpolation(v);
|
|
73
|
-
}
|
package/core/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './Arrmatura';
|
package/core/register.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { compileNodes } from './compileNode';
|
|
2
|
-
import { xmlParse } from '../lib';
|
|
3
|
-
import { fnName } from './utils';
|
|
4
|
-
|
|
5
|
-
export class ComponentDefinition {
|
|
6
|
-
tag: string;
|
|
7
|
-
template?: string;
|
|
8
|
-
Ctor: any;
|
|
9
|
-
$templateContent?: ComponentContent;
|
|
10
|
-
|
|
11
|
-
constructor({ tag, template, Ctor }: ComponentDefinitionInfo) {
|
|
12
|
-
this.tag = tag;
|
|
13
|
-
this.template = template;
|
|
14
|
-
this.Ctor = Ctor || function () {};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
get content() {
|
|
18
|
-
return this.$templateContent || (this.$templateContent = compileNodes(xmlParse(this.template)));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const REGISTRY = new Map<string, ComponentDefinition>();
|
|
23
|
-
|
|
24
|
-
const notFound = (tag: string): ComponentDefinition =>
|
|
25
|
-
new ComponentDefinition({ tag, template: '<b>??' + tag + '??</b>' });
|
|
26
|
-
|
|
27
|
-
const setInfo = (ctr: ComponentDefinitionInfo) => REGISTRY.set(ctr.tag, new ComponentDefinition(ctr));
|
|
28
|
-
|
|
29
|
-
const registerType = (ctr: string | ComponentDefinitionInfo | Constructor) => {
|
|
30
|
-
if (typeof ctr === 'string') {
|
|
31
|
-
ctr.replace(/<component\s+id="(.+)">([\s\S]*?)<\/component>/gm, (_, tag, template) => {
|
|
32
|
-
setInfo({ tag, template: template.trim() });
|
|
33
|
-
return '';
|
|
34
|
-
});
|
|
35
|
-
} else {
|
|
36
|
-
setInfo(typeof ctr === 'function' ? { Ctor: ctr, tag: ctr.name || fnName(ctr) } : ctr);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const registerTypes = (types?: Array<string | ComponentDefinitionInfo | Constructor>) =>
|
|
41
|
-
types?.forEach(registerType);
|
|
42
|
-
|
|
43
|
-
export const getByTag = (tag: string) => REGISTRY.get(tag) || notFound(tag);
|
package/core/utils.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { nextId, identity, attributesToString } from '../lib';
|
|
2
|
-
|
|
3
|
-
export const applyValue = (value: any, fn = identity) => (value?.then ? value.then(fn) : fn(value));
|
|
4
|
-
|
|
5
|
-
export const fnName = (ctor: object) => (/^function\s+([\w$]+)\s*\(/.exec(ctor.toString()) || [])[1] || nextId('C');
|
|
6
|
-
|
|
7
|
-
export const methodName = (x: unknown, pre = '') => {
|
|
8
|
-
const s = `${x || ''}`;
|
|
9
|
-
return pre + s[0].toUpperCase() + s.slice(1);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const stringifyState = (attrs?: object | Hash) => {
|
|
13
|
-
if (!attrs) {
|
|
14
|
-
return '';
|
|
15
|
-
}
|
|
16
|
-
const r: string[] = [];
|
|
17
|
-
Object.entries(attrs).forEach(([k, v]) => {
|
|
18
|
-
if (v && k[0] !== '$') {
|
|
19
|
-
r.push(' ' + k + '="' + attributesToString(v) + '"');
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
return r.length ? r.join('') : '';
|
|
23
|
-
};
|
package/core-web/WebPlatform.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { DomElement, DomTextElement } from './elements';
|
|
2
|
-
import { reflow } from './reflow';
|
|
3
|
-
|
|
4
|
-
export class WebPlatform implements IPlatform {
|
|
5
|
-
rootElement: HTMLElement;
|
|
6
|
-
|
|
7
|
-
constructor(root: HTMLElement | string = 'root') {
|
|
8
|
-
if (typeof root === 'string') {
|
|
9
|
-
root = document.getElementById(root) || window.document.body;
|
|
10
|
-
}
|
|
11
|
-
this.rootElement = root || window.document.body;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
createTextElement(initials: Hash, _: IComponent): IComponentImplementation {
|
|
15
|
-
return new DomTextElement(initials);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
createElement(tag: string, initials: Hash, owner: IComponent): IComponentImplementation {
|
|
19
|
-
return new DomElement(tag, initials, owner);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
reflow(root: IComponent) {
|
|
23
|
-
reflow(root, this.rootElement);
|
|
24
|
-
}
|
|
25
|
-
}
|
package/core-web/attributes.ts
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import type { DomNode, IElement } from './type';
|
|
2
|
-
|
|
3
|
-
const camelize = (key: string, sep = '_', jn = ' ') =>
|
|
4
|
-
('' + key)
|
|
5
|
-
.split(sep)
|
|
6
|
-
.map((s, i) => (i ? s[0].toUpperCase() + s.slice(1) : s))
|
|
7
|
-
.join(jn);
|
|
8
|
-
|
|
9
|
-
const setListener = ($: IElement, key: string, e: DomNode, fn: unknown) => {
|
|
10
|
-
const fnKey = key.split(':')[0];
|
|
11
|
-
if (!fn) {
|
|
12
|
-
setAttribute($, key, null);
|
|
13
|
-
} else {
|
|
14
|
-
setAttribute($, key, (domEvent: Event) => {
|
|
15
|
-
// indirect reference. could be changed along the time.
|
|
16
|
-
$[fnKey]({ ...e.$dataset }, domEvent);
|
|
17
|
-
return false;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
export function setAttribute($: IElement, key: string, value: null | string | ((ev: any) => any)) {
|
|
22
|
-
if (value != null) {
|
|
23
|
-
if (typeof value === 'function') {
|
|
24
|
-
if (!$.$listeners) {
|
|
25
|
-
$.$listeners = new Map();
|
|
26
|
-
}
|
|
27
|
-
if (!$.$listeners.has(key)) {
|
|
28
|
-
const [akey, ekey = akey] = key.split(':');
|
|
29
|
-
$.$element.addEventListener(ekey, value, false);
|
|
30
|
-
$.$listeners.set(key, value);
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
$.$element.setAttribute(key, value);
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
if ($.$listeners?.has(key)) {
|
|
37
|
-
const [akey, ekey = akey] = key.split(':');
|
|
38
|
-
$.$element.removeEventListener(ekey, $.$listeners.get(key));
|
|
39
|
-
$.$listeners.delete(key);
|
|
40
|
-
} else {
|
|
41
|
-
$.$element.removeAttribute(key);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// DOM
|
|
47
|
-
export const ATTR_SETTERS: Hash<($: IElement, e: DomNode, v: unknown) => void> = {
|
|
48
|
-
disabled: (_, e, v) => (e.disabled = v ? true : null),
|
|
49
|
-
class: (_, e, v) => {
|
|
50
|
-
e.className = String(v || '');
|
|
51
|
-
},
|
|
52
|
-
selected: (_, e, v) => (e.selected = v ? true : null),
|
|
53
|
-
value: (_, e, v) => (e.value = v == null ? '' : v),
|
|
54
|
-
checked: (_, e, v) => (e.checked = !!v),
|
|
55
|
-
|
|
56
|
-
init: () => {
|
|
57
|
-
// do nothing
|
|
58
|
-
},
|
|
59
|
-
data: function (_, e, u) {
|
|
60
|
-
const v = u as Hash;
|
|
61
|
-
if (v && e.$dataset) {
|
|
62
|
-
Object.keys(e.$dataset).forEach((k) => {
|
|
63
|
-
if (v[k] == null) {
|
|
64
|
-
e.dataset[camelize(k, '-', '')] = null;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
e.$dataset = { ...e.$dataset, ...v };
|
|
68
|
-
} else {
|
|
69
|
-
e.$dataset = v ? { ...v } : e.$dataset || {};
|
|
70
|
-
}
|
|
71
|
-
if (v) {
|
|
72
|
-
Object.keys(v).forEach((k) => {
|
|
73
|
-
e.dataset[camelize(k, '-', '')] = v[k];
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
click: ($, e, v) => setListener($, 'click', e, v),
|
|
79
|
-
click2: ($, e, v) => setListener($, 'click2:click', e, v),
|
|
80
|
-
['bubble-click']: ($, e, v) => setListener($, 'bubble-click:click', e, v),
|
|
81
|
-
blur: ($, e, v) => setListener($, 'blur', e, v),
|
|
82
|
-
focus: ($, e, v) => setListener($, 'focus', e, v),
|
|
83
|
-
dblclick: ($, e, v) => setListener($, 'dblclick', e, v),
|
|
84
|
-
scroll: ($, e, v) =>
|
|
85
|
-
setAttribute(
|
|
86
|
-
$,
|
|
87
|
-
'scroll',
|
|
88
|
-
!v
|
|
89
|
-
? null
|
|
90
|
-
: (ev) => {
|
|
91
|
-
$.scroll({ value: e.scrollTop }, ev);
|
|
92
|
-
}
|
|
93
|
-
),
|
|
94
|
-
scrolledDown: ($, element, v) =>
|
|
95
|
-
setAttribute(
|
|
96
|
-
$,
|
|
97
|
-
'scrolledDown:scroll',
|
|
98
|
-
!v
|
|
99
|
-
? null
|
|
100
|
-
: (ev) => {
|
|
101
|
-
const gap = $.scrolledDownGap || 10;
|
|
102
|
-
const offset = element.clientHeight + element.scrollTop;
|
|
103
|
-
const isDown = Math.abs(element.scrollHeight - offset) < gap;
|
|
104
|
-
if (isDown && offset > ($._maxScrolledDownOffset || 0)) {
|
|
105
|
-
$._maxScrolledDownOffset = offset;
|
|
106
|
-
$.scrolledDown({ offset }, ev);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
),
|
|
110
|
-
|
|
111
|
-
touchstart: function ($, e, v) {
|
|
112
|
-
const h = !v
|
|
113
|
-
? null
|
|
114
|
-
: (ev: TouchEvent & { pageX: number; pageY: number }) => {
|
|
115
|
-
$.touchstart(
|
|
116
|
-
{
|
|
117
|
-
...e.$dataset,
|
|
118
|
-
x: ev.pageX || ev.changedTouches[0].screenX,
|
|
119
|
-
y: ev.pageY || ev.changedTouches[0].screenY,
|
|
120
|
-
},
|
|
121
|
-
ev
|
|
122
|
-
);
|
|
123
|
-
return false;
|
|
124
|
-
};
|
|
125
|
-
setAttribute($, 'touchstart:touchstart', h);
|
|
126
|
-
setAttribute($, 'touchstart:mousedown', h);
|
|
127
|
-
},
|
|
128
|
-
touch: function ($, e, v) {
|
|
129
|
-
const data = { ...e.$dataset };
|
|
130
|
-
const hs = !v
|
|
131
|
-
? null
|
|
132
|
-
: (ev: TouchEvent & { pageX: number; pageY: number }) => {
|
|
133
|
-
data.active = true;
|
|
134
|
-
data.x = ev.pageX || ev.changedTouches[0].screenX;
|
|
135
|
-
data.y = ev.pageY || ev.changedTouches[0].screenY;
|
|
136
|
-
return false;
|
|
137
|
-
};
|
|
138
|
-
setAttribute($, 'touch:touchstart', hs);
|
|
139
|
-
setAttribute($, 'touch:mousedown', hs);
|
|
140
|
-
const h = !v
|
|
141
|
-
? () => null
|
|
142
|
-
: (stop: boolean = false) =>
|
|
143
|
-
(ev: TouchEvent & { pageX: number; pageY: number }) => {
|
|
144
|
-
if (data.active) {
|
|
145
|
-
data.active = !stop;
|
|
146
|
-
|
|
147
|
-
data.xx = ev.pageX || ev.changedTouches[0].screenX;
|
|
148
|
-
data.yy = ev.pageY || ev.changedTouches[0].screenY;
|
|
149
|
-
data.dx = data.xx - data.x;
|
|
150
|
-
data.dy = data.yy - data.y;
|
|
151
|
-
$.touch(data, ev);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return false;
|
|
155
|
-
};
|
|
156
|
-
setAttribute($, 'touch:touchcancel', h(true));
|
|
157
|
-
setAttribute($, 'touch:touchend', h(true));
|
|
158
|
-
setAttribute($, 'touch:mouseup', h(true));
|
|
159
|
-
setAttribute($, 'touch:touchmove', h(false));
|
|
160
|
-
setAttribute($, 'touch:mousemove', h(false));
|
|
161
|
-
},
|
|
162
|
-
keypress: function ($, e, v) {
|
|
163
|
-
setAttribute(
|
|
164
|
-
$,
|
|
165
|
-
'keypress:keyup',
|
|
166
|
-
!v
|
|
167
|
-
? null
|
|
168
|
-
: (ev: KeyboardEvent) => {
|
|
169
|
-
if (ev.keyCode !== 13 && ev.keyCode !== 27) {
|
|
170
|
-
$.keypress?.({ value: e.value, ...e.$dataset }, ev);
|
|
171
|
-
setTimeout(() => e.focus(), 0);
|
|
172
|
-
}
|
|
173
|
-
return false;
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
},
|
|
177
|
-
enter: function ($, e, v) {
|
|
178
|
-
setAttribute(
|
|
179
|
-
$,
|
|
180
|
-
'enter:keyup',
|
|
181
|
-
!v
|
|
182
|
-
? null
|
|
183
|
-
: (ev: KeyboardEvent) => {
|
|
184
|
-
if (ev.keyCode === 13) {
|
|
185
|
-
$.enter({ value: e.value, ...e.$dataset }, ev);
|
|
186
|
-
}
|
|
187
|
-
if (ev.keyCode === 13 || ev.keyCode === 27) {
|
|
188
|
-
e.blur();
|
|
189
|
-
}
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
);
|
|
193
|
-
},
|
|
194
|
-
change: function ($, e, v) {
|
|
195
|
-
setAttribute(
|
|
196
|
-
$,
|
|
197
|
-
'change',
|
|
198
|
-
!v
|
|
199
|
-
? null
|
|
200
|
-
: (ev: Event) => {
|
|
201
|
-
$.change({ value: e.value, ...e.$dataset }, ev);
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
);
|
|
205
|
-
},
|
|
206
|
-
toggle: function ($, e, v) {
|
|
207
|
-
setAttribute(
|
|
208
|
-
$,
|
|
209
|
-
'toggle:change',
|
|
210
|
-
!v
|
|
211
|
-
? null
|
|
212
|
-
: (ev: Event) => {
|
|
213
|
-
$.toggle({ value: e.checked, ...e.$dataset }, ev);
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
);
|
|
217
|
-
},
|
|
218
|
-
};
|
package/core-web/elements.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { decodeXmlEntities } from '../lib';
|
|
2
|
-
import { ATTR_SETTERS, setAttribute } from './attributes';
|
|
3
|
-
import type { DomNode, IElement } from './type';
|
|
4
|
-
|
|
5
|
-
export class DomElement implements IComponentImplementation, IElement {
|
|
6
|
-
$: IComponent;
|
|
7
|
-
$element: DomNode;
|
|
8
|
-
$listeners: any;
|
|
9
|
-
$changes: Map<string, any> = new Map();
|
|
10
|
-
init?: () => any;
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
|
|
13
|
-
constructor(tag: string, _: Hash, $: IComponent) {
|
|
14
|
-
this.$ = $;
|
|
15
|
-
this.$element = document.createElement(tag) as DomNode;
|
|
16
|
-
this.$element.impl = this;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
done() {
|
|
20
|
-
this.$element?.parentElement?.removeChild(this.$element);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
stateChanged(changes: Map<string, any>) {
|
|
24
|
-
const attrs = this;
|
|
25
|
-
changes.forEach((value, key) => {
|
|
26
|
-
if (key[0] === '$') return;
|
|
27
|
-
if (value !== attrs[key]) {
|
|
28
|
-
this.$changes?.set(key, value);
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
applyStateChanges() {
|
|
34
|
-
const attrs = this;
|
|
35
|
-
const e = this.$element;
|
|
36
|
-
if (!this.$changes.size) return;
|
|
37
|
-
// this.$.log('changes', changes)
|
|
38
|
-
this.$changes.forEach((value, key) => {
|
|
39
|
-
if (key[0] === '$') return;
|
|
40
|
-
if (value !== attrs[key]) {
|
|
41
|
-
const setter = ATTR_SETTERS[key];
|
|
42
|
-
if (setter) {
|
|
43
|
-
setter(this, e, value);
|
|
44
|
-
} else if (key.slice(0, 5) === 'data-') {
|
|
45
|
-
ATTR_SETTERS.data(this, e, {
|
|
46
|
-
...e.$dataset,
|
|
47
|
-
[key.slice(5)]: value,
|
|
48
|
-
});
|
|
49
|
-
} else {
|
|
50
|
-
setAttribute(this, key, value);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
attrs[key] = value;
|
|
54
|
-
});
|
|
55
|
-
this.$changes.clear();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class DomTextElement implements IComponentImplementation {
|
|
60
|
-
$element: Text;
|
|
61
|
-
$string: string | null = null;
|
|
62
|
-
[key: string]: unknown;
|
|
63
|
-
|
|
64
|
-
constructor(attrs: Hash) {
|
|
65
|
-
this.$element = document.createTextNode(String(attrs.text || ''));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
done() {
|
|
69
|
-
this.$element.parentElement?.removeChild(this.$element);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
stateChanged(changes: Map<string, any>) {
|
|
73
|
-
if (changes.has('text')) {
|
|
74
|
-
this.$string = decodeXmlEntities(changes.get('text'));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
applyStateChanges() {
|
|
79
|
-
this.$element.textContent = this.$string;
|
|
80
|
-
}
|
|
81
|
-
}
|
package/core-web/index.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { CArrmaturaNode } from '../core';
|
|
2
|
-
import { WebPlatform } from './WebPlatform';
|
|
3
|
-
import * as lib from '../lib';
|
|
4
|
-
|
|
5
|
-
import commons from '../commons';
|
|
6
|
-
|
|
7
|
-
import support from './support';
|
|
8
|
-
|
|
9
|
-
export type ArrmaturaOptionsForWeb = ArrmaturaOptions & {
|
|
10
|
-
rootElement?: HTMLElement;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export function arrmatura(
|
|
14
|
-
template: string,
|
|
15
|
-
{ rootElement, pipes, functions = pipes, types = [], resources }: ArrmaturaOptionsForWeb & { pipes: Hash<Pipe> }
|
|
16
|
-
) {
|
|
17
|
-
const options: ArrmaturaOptions = {
|
|
18
|
-
functions: { ...lib, ...support(arrmatura), ...functions },
|
|
19
|
-
types: [...commons, ...types],
|
|
20
|
-
resources,
|
|
21
|
-
};
|
|
22
|
-
const node = new CArrmaturaNode(template, options, new WebPlatform(rootElement));
|
|
23
|
-
node.launch();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
arrmatura.lib = lib;
|
|
27
|
-
|
|
28
|
-
Object.defineProperty(window, 'arrmatura', { value: arrmatura });
|
package/core-web/reflow.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { DomElement } from './elements';
|
|
2
|
-
import type { DomNode } from './type';
|
|
3
|
-
|
|
4
|
-
function appendElt(e: DomNode, p: DomNode | HTMLElement, cursor?: DomNode): DomNode {
|
|
5
|
-
const before = cursor ? cursor.nextSibling : p.firstChild;
|
|
6
|
-
if (!before) {
|
|
7
|
-
if (p !== e.parentElement) {
|
|
8
|
-
p.appendChild(e);
|
|
9
|
-
}
|
|
10
|
-
} else if (e !== before) {
|
|
11
|
-
p.insertBefore(e, before);
|
|
12
|
-
}
|
|
13
|
-
return e;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function reflow($: IComponent, parent: DomNode | HTMLElement, cursor?: DomNode) {
|
|
17
|
-
if ($.$children) {
|
|
18
|
-
for (let p of $.$children.values()) {
|
|
19
|
-
const e = p.$impl.$element as DomNode;
|
|
20
|
-
if (e) {
|
|
21
|
-
reflow(p, e);
|
|
22
|
-
(p.$impl as DomElement).applyStateChanges();
|
|
23
|
-
cursor = appendElt(e, parent, cursor);
|
|
24
|
-
} else {
|
|
25
|
-
cursor = reflow(p, parent, cursor);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return cursor;
|
|
30
|
-
}
|
package/core-web/support.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const showCounts = (counts: Obj, nicNema = '⭕', neZnojdzeno = '⭕', loading = '…') => {
|
|
2
|
-
if (!counts) {
|
|
3
|
-
return loading;
|
|
4
|
-
}
|
|
5
|
-
const { total, actual } = counts;
|
|
6
|
-
if (!total) {
|
|
7
|
-
return nicNema;
|
|
8
|
-
}
|
|
9
|
-
if (!actual) {
|
|
10
|
-
return neZnojdzeno;
|
|
11
|
-
}
|
|
12
|
-
if (actual === total) {
|
|
13
|
-
return total;
|
|
14
|
-
}
|
|
15
|
-
return actual + ' / ' + total;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default (arrmatura: (m: string, opts: unknown) => void) => ({
|
|
19
|
-
showCounts,
|
|
20
|
-
|
|
21
|
-
sandbox: (markup: string) =>
|
|
22
|
-
function () {
|
|
23
|
-
try {
|
|
24
|
-
arrmatura(`<div>${markup}</div>`, { rootElement: this.$element });
|
|
25
|
-
} catch (err) {}
|
|
26
|
-
},
|
|
27
|
-
});
|
package/core-web/type.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface DomNode extends HTMLElement {
|
|
2
|
-
disabled: boolean | null;
|
|
3
|
-
selected: boolean | null;
|
|
4
|
-
value: unknown;
|
|
5
|
-
checked: boolean;
|
|
6
|
-
dataset: any;
|
|
7
|
-
focus(): void;
|
|
8
|
-
blur(): void;
|
|
9
|
-
$dataset: any;
|
|
10
|
-
impl?: IElement;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface IElement {
|
|
14
|
-
init?: () => any;
|
|
15
|
-
$listeners: any;
|
|
16
|
-
$element: DomNode;
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}
|