vasille 1.2.9 → 2.0.3
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/LICENSE.md +21 -0
- package/README.md +195 -129
- package/cdn/es2015.js +3231 -0
- package/cdn/es5.js +3675 -0
- package/flow-typed/vasille.js +839 -0
- package/lib/binding/attribute.js +32 -0
- package/lib/binding/binding.js +39 -0
- package/lib/binding/class.js +51 -0
- package/lib/binding/style.js +29 -0
- package/lib/core/core.js +186 -0
- package/lib/core/destroyable.js +45 -0
- package/lib/core/errors.js +16 -0
- package/lib/core/executor.js +154 -0
- package/lib/core/ivalue.js +56 -0
- package/lib/core/signal.js +50 -0
- package/lib/core/slot.js +47 -0
- package/lib/index.js +27 -22
- package/lib/models/array-model.js +208 -0
- package/lib/models/listener.js +130 -0
- package/lib/models/map-model.js +66 -0
- package/lib/models/model.js +1 -0
- package/lib/models/object-model.js +78 -0
- package/lib/models/set-model.js +62 -0
- package/lib/node/app.js +39 -0
- package/lib/node/interceptor.js +83 -0
- package/lib/node/node.js +1204 -0
- package/lib/node/watch.js +27 -0
- package/lib/value/expression.js +83 -0
- package/lib/value/mirror.js +58 -0
- package/lib/value/pointer.js +26 -0
- package/lib/value/reference.js +55 -0
- package/lib/views/array-view.js +21 -0
- package/lib/views/base-view.js +49 -0
- package/lib/views/map-view.js +19 -0
- package/lib/views/object-view.js +19 -0
- package/lib/views/repeat-node.js +106 -0
- package/lib/views/repeater.js +63 -0
- package/lib/views/set-view.js +22 -0
- package/package.json +26 -18
- package/types/binding/attribute.d.ts +23 -0
- package/types/binding/binding.d.ts +30 -0
- package/types/binding/class.d.ts +23 -0
- package/types/binding/style.d.ts +23 -0
- package/types/core/core.d.ts +144 -0
- package/types/core/destroyable.d.ts +15 -0
- package/types/core/errors.d.ts +4 -0
- package/types/core/executor.d.ts +87 -0
- package/types/core/ivalue.d.ts +45 -0
- package/types/core/signal.d.ts +35 -0
- package/types/core/slot.d.ts +45 -0
- package/types/index.d.ts +27 -21
- package/types/models/array-model.d.ts +103 -0
- package/types/models/listener.d.ts +74 -0
- package/types/models/map-model.d.ts +35 -0
- package/types/models/model.d.ts +19 -0
- package/types/models/object-model.d.ts +36 -0
- package/types/models/set-model.d.ts +34 -0
- package/types/node/app.d.ts +42 -0
- package/types/node/interceptor.d.ts +50 -0
- package/types/node/node.d.ts +741 -0
- package/types/node/watch.d.ts +23 -0
- package/types/value/expression.d.ts +60 -0
- package/types/value/mirror.d.ts +35 -0
- package/types/value/pointer.d.ts +19 -0
- package/types/value/reference.d.ts +30 -0
- package/types/views/array-view.d.ts +13 -0
- package/types/views/base-view.d.ts +43 -0
- package/types/views/map-view.d.ts +11 -0
- package/types/views/object-view.d.ts +11 -0
- package/types/views/repeat-node.d.ts +35 -0
- package/types/views/repeater.d.ts +38 -0
- package/types/views/set-view.d.ts +11 -0
- package/CHANGELOG.md +0 -23
- package/img/favicon.svg +0 -441
- package/img/getLocus.svg +0 -18
- package/img/logo.png +0 -0
- package/img/logo.svg +0 -550
- package/img/scores-o-log.png +0 -0
- package/img/scores-o.png +0 -0
- package/img/scores-wo-log.png +0 -0
- package/img/scores-wo.png +0 -0
- package/img/x1-x32.png +0 -0
- package/lib/attribute.js +0 -71
- package/lib/attribute.js.map +0 -1
- package/lib/bind.js +0 -286
- package/lib/bind.js.map +0 -1
- package/lib/class.js +0 -97
- package/lib/class.js.map +0 -1
- package/lib/executor.js +0 -167
- package/lib/executor.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/interfaces/core.js +0 -247
- package/lib/interfaces/core.js.map +0 -1
- package/lib/interfaces/destroyable.js +0 -39
- package/lib/interfaces/destroyable.js.map +0 -1
- package/lib/interfaces/errors.js +0 -49
- package/lib/interfaces/errors.js.map +0 -1
- package/lib/interfaces/ibind.js +0 -31
- package/lib/interfaces/ibind.js.map +0 -1
- package/lib/interfaces/idefinition.js +0 -64
- package/lib/interfaces/idefinition.js.map +0 -1
- package/lib/interfaces/ivalue.js +0 -60
- package/lib/interfaces/ivalue.js.map +0 -1
- package/lib/models.js +0 -579
- package/lib/models.js.map +0 -1
- package/lib/node.js +0 -2155
- package/lib/node.js.map +0 -1
- package/lib/property.js +0 -38
- package/lib/property.js.map +0 -1
- package/lib/style.js +0 -66
- package/lib/style.js.map +0 -1
- package/lib/value.js +0 -203
- package/lib/value.js.map +0 -1
- package/lib/views.js +0 -688
- package/lib/views.js.map +0 -1
- package/types/attribute.d.ts +0 -18
- package/types/bind.d.ts +0 -72
- package/types/class.d.ts +0 -19
- package/types/data.d.ts +0 -11
- package/types/event.d.ts +0 -10
- package/types/executor.d.ts +0 -57
- package/types/interfaces/core.d.ts +0 -129
- package/types/interfaces/destroyable.d.ts +0 -11
- package/types/interfaces/errors.d.ts +0 -24
- package/types/interfaces/ibind.d.ts +0 -19
- package/types/interfaces/idefinition.d.ts +0 -29
- package/types/interfaces/ivalue.d.ts +0 -40
- package/types/models.d.ts +0 -179
- package/types/node.d.ts +0 -906
- package/types/property.d.ts +0 -9
- package/types/style.d.ts +0 -28
- package/types/value.d.ts +0 -43
- package/types/views.d.ts +0 -135
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Fragment } from "./node";
|
|
2
|
+
import { Slot } from "../core/slot";
|
|
3
|
+
/**
|
|
4
|
+
* Watch Node
|
|
5
|
+
* @class Watch
|
|
6
|
+
* @extends Fragment
|
|
7
|
+
*/
|
|
8
|
+
export class Watch extends Fragment {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.slot = new Slot;
|
|
12
|
+
this.model = this.$ref(null);
|
|
13
|
+
this.$seal();
|
|
14
|
+
}
|
|
15
|
+
$createWatchers() {
|
|
16
|
+
this.$watch((value) => {
|
|
17
|
+
this.$children.forEach(child => {
|
|
18
|
+
child.$destroy();
|
|
19
|
+
});
|
|
20
|
+
this.$children.splice(0);
|
|
21
|
+
this.slot.release(this, value);
|
|
22
|
+
}, this.model);
|
|
23
|
+
}
|
|
24
|
+
$compose() {
|
|
25
|
+
this.slot.release(this, this.model.$);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Reference } from "./reference.js";
|
|
2
|
+
import { IValue } from "../core/ivalue";
|
|
3
|
+
/**
|
|
4
|
+
* Bind some values to one expression
|
|
5
|
+
* @class Expression
|
|
6
|
+
* @extends IValue
|
|
7
|
+
*/
|
|
8
|
+
export class Expression extends IValue {
|
|
9
|
+
constructor(func, link, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
|
|
10
|
+
super(false);
|
|
11
|
+
/**
|
|
12
|
+
* Expression will link different handler for each value of list
|
|
13
|
+
*/
|
|
14
|
+
this.linkedFunc = [];
|
|
15
|
+
const values = [v1, v2, v3, v4, v5, v6, v7, v8, v9].filter(v => v instanceof IValue);
|
|
16
|
+
const handler = (i) => {
|
|
17
|
+
if (i != null) {
|
|
18
|
+
this.valuesCache[i] = this.values[i].$;
|
|
19
|
+
}
|
|
20
|
+
this.sync.$ = func.apply(this, this.valuesCache);
|
|
21
|
+
};
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
this.valuesCache = values.map(iValue => iValue.$);
|
|
25
|
+
this.sync = new Reference(func.apply(this, this.valuesCache));
|
|
26
|
+
let i = 0;
|
|
27
|
+
values.forEach(() => {
|
|
28
|
+
this.linkedFunc.push(handler.bind(this, Number(i++)));
|
|
29
|
+
});
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
this.values = values;
|
|
33
|
+
this.func = handler;
|
|
34
|
+
if (link) {
|
|
35
|
+
this.enable();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
handler();
|
|
39
|
+
}
|
|
40
|
+
this.$seal();
|
|
41
|
+
}
|
|
42
|
+
get $() {
|
|
43
|
+
return this.sync.$;
|
|
44
|
+
}
|
|
45
|
+
set $(value) {
|
|
46
|
+
this.sync.$ = value;
|
|
47
|
+
}
|
|
48
|
+
on(handler) {
|
|
49
|
+
this.sync.on(handler);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
off(handler) {
|
|
53
|
+
this.sync.off(handler);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
enable() {
|
|
57
|
+
if (!this.isEnabled) {
|
|
58
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
59
|
+
this.values[i].on(this.linkedFunc[i]);
|
|
60
|
+
this.valuesCache[i] = this.values[i].$;
|
|
61
|
+
}
|
|
62
|
+
this.func();
|
|
63
|
+
this.isEnabled = true;
|
|
64
|
+
}
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
disable() {
|
|
68
|
+
if (this.isEnabled) {
|
|
69
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
70
|
+
this.values[i].off(this.linkedFunc[i]);
|
|
71
|
+
}
|
|
72
|
+
this.isEnabled = false;
|
|
73
|
+
}
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
$destroy() {
|
|
77
|
+
this.disable();
|
|
78
|
+
this.values.splice(0);
|
|
79
|
+
this.valuesCache.splice(0);
|
|
80
|
+
this.linkedFunc.splice(0);
|
|
81
|
+
super.$destroy();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Reference } from "./reference";
|
|
2
|
+
/**
|
|
3
|
+
* Declares a notifiable bind to a value
|
|
4
|
+
* @class Mirror
|
|
5
|
+
* @extends IValue
|
|
6
|
+
* @version 2
|
|
7
|
+
*/
|
|
8
|
+
export class Mirror extends Reference {
|
|
9
|
+
/**
|
|
10
|
+
* Constructs a notifiable bind to a value
|
|
11
|
+
* @param value {IValue} is initial value
|
|
12
|
+
* @param forwardOnly {boolean} ensure forward only synchronization
|
|
13
|
+
*/
|
|
14
|
+
constructor(value, forwardOnly = false) {
|
|
15
|
+
super(value.$);
|
|
16
|
+
this.handler = (v) => {
|
|
17
|
+
this.$ = v;
|
|
18
|
+
};
|
|
19
|
+
this.pointedValue = value;
|
|
20
|
+
this.forwardOnly = forwardOnly;
|
|
21
|
+
value.on(this.handler);
|
|
22
|
+
this.$seal();
|
|
23
|
+
}
|
|
24
|
+
get $() {
|
|
25
|
+
// this is a ts bug
|
|
26
|
+
// eslint-disable-next-line
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
return super.$;
|
|
29
|
+
}
|
|
30
|
+
set $(v) {
|
|
31
|
+
// this is a ts bug
|
|
32
|
+
// eslint-disable-next-line
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
super.$ = v;
|
|
35
|
+
if (!this.forwardOnly) {
|
|
36
|
+
this.pointedValue.$ = v;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
enable() {
|
|
40
|
+
if (!this.isEnabled) {
|
|
41
|
+
this.isEnabled = true;
|
|
42
|
+
this.pointedValue.on(this.handler);
|
|
43
|
+
this.$ = this.pointedValue.$;
|
|
44
|
+
}
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
disable() {
|
|
48
|
+
if (this.isEnabled) {
|
|
49
|
+
this.pointedValue.off(this.handler);
|
|
50
|
+
this.isEnabled = false;
|
|
51
|
+
}
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
$destroy() {
|
|
55
|
+
this.disable();
|
|
56
|
+
super.$destroy();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Mirror } from "./mirror";
|
|
2
|
+
/**
|
|
3
|
+
* r/w pointer to a value
|
|
4
|
+
* @class Pointer
|
|
5
|
+
* @extends Mirror
|
|
6
|
+
*/
|
|
7
|
+
export class Pointer extends Mirror {
|
|
8
|
+
/**
|
|
9
|
+
* @param value {IValue} value to point
|
|
10
|
+
* @param forwardOnly {boolean} forward only data flow
|
|
11
|
+
*/
|
|
12
|
+
constructor(value, forwardOnly = false) {
|
|
13
|
+
super(value, forwardOnly);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Point a new ivalue
|
|
17
|
+
* @param value {IValue} value to point
|
|
18
|
+
*/
|
|
19
|
+
point(value) {
|
|
20
|
+
if (this.pointedValue !== value) {
|
|
21
|
+
this.disable();
|
|
22
|
+
this.pointedValue = value;
|
|
23
|
+
this.enable();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { IValue } from "../core/ivalue";
|
|
2
|
+
/**
|
|
3
|
+
* Declares a notifiable value
|
|
4
|
+
* @class Reference
|
|
5
|
+
* @extends IValue
|
|
6
|
+
*/
|
|
7
|
+
export class Reference extends IValue {
|
|
8
|
+
/**
|
|
9
|
+
* @param value {any} the initial value
|
|
10
|
+
*/
|
|
11
|
+
constructor(value) {
|
|
12
|
+
super(true);
|
|
13
|
+
this.value = value;
|
|
14
|
+
this.onchange = new Set;
|
|
15
|
+
this.$seal();
|
|
16
|
+
}
|
|
17
|
+
get $() {
|
|
18
|
+
return this.value;
|
|
19
|
+
}
|
|
20
|
+
set $(value) {
|
|
21
|
+
if (this.value !== value) {
|
|
22
|
+
this.value = value;
|
|
23
|
+
if (this.isEnabled) {
|
|
24
|
+
this.onchange.forEach(handler => {
|
|
25
|
+
handler(value);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
enable() {
|
|
31
|
+
if (!this.isEnabled) {
|
|
32
|
+
this.onchange.forEach(handler => {
|
|
33
|
+
handler(this.value);
|
|
34
|
+
});
|
|
35
|
+
this.isEnabled = true;
|
|
36
|
+
}
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
disable() {
|
|
40
|
+
this.isEnabled = false;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
on(handler) {
|
|
44
|
+
this.onchange.add(handler);
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
off(handler) {
|
|
48
|
+
this.onchange.delete(handler);
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
$destroy() {
|
|
52
|
+
super.$destroy();
|
|
53
|
+
this.onchange.clear();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseView } from "./base-view";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a view of an array model
|
|
4
|
+
* @class ArrayView
|
|
5
|
+
* @extends BaseView
|
|
6
|
+
*/
|
|
7
|
+
export class ArrayView extends BaseView {
|
|
8
|
+
constructor(model) {
|
|
9
|
+
super();
|
|
10
|
+
this.model = model;
|
|
11
|
+
}
|
|
12
|
+
createChild(id, item, before) {
|
|
13
|
+
super.createChild(item, item, before || this.$.nodes.get(id));
|
|
14
|
+
}
|
|
15
|
+
$ready() {
|
|
16
|
+
this.model.forEach(item => {
|
|
17
|
+
this.createChild(item, item);
|
|
18
|
+
});
|
|
19
|
+
super.$ready();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { RepeatNode, RepeatNodePrivate } from "./repeat-node";
|
|
2
|
+
/**
|
|
3
|
+
* Private part of BaseView
|
|
4
|
+
* @class BaseViewPrivate
|
|
5
|
+
* @extends RepeatNodePrivate
|
|
6
|
+
*/
|
|
7
|
+
export class BaseViewPrivate extends RepeatNodePrivate {
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.$seal();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Base class of default views
|
|
15
|
+
* @class BaseView
|
|
16
|
+
* @extends RepeatNode
|
|
17
|
+
* @implements IModel
|
|
18
|
+
*/
|
|
19
|
+
export class BaseView extends RepeatNode {
|
|
20
|
+
constructor($1) {
|
|
21
|
+
super($1 || new BaseViewPrivate);
|
|
22
|
+
const $ = this.$;
|
|
23
|
+
$.addHandler = (id, item) => {
|
|
24
|
+
this.createChild(id, item);
|
|
25
|
+
};
|
|
26
|
+
$.removeHandler = (id, item) => {
|
|
27
|
+
this.destroyChild(id, item);
|
|
28
|
+
};
|
|
29
|
+
this.$seal();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Handle ready event
|
|
33
|
+
*/
|
|
34
|
+
$ready() {
|
|
35
|
+
const $ = this.$;
|
|
36
|
+
this.model.listener.onAdd($.addHandler);
|
|
37
|
+
this.model.listener.onRemove($.removeHandler);
|
|
38
|
+
super.$ready();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Handles destroy event
|
|
42
|
+
*/
|
|
43
|
+
$destroy() {
|
|
44
|
+
const $ = this.$;
|
|
45
|
+
this.model.listener.offAdd($.addHandler);
|
|
46
|
+
this.model.listener.offRemove($.removeHandler);
|
|
47
|
+
super.$destroy();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseView } from "./base-view";
|
|
2
|
+
/**
|
|
3
|
+
* Create a children pack for each map value
|
|
4
|
+
* @class MapView
|
|
5
|
+
* @extends BaseView
|
|
6
|
+
*/
|
|
7
|
+
export class MapView extends BaseView {
|
|
8
|
+
constructor(model) {
|
|
9
|
+
super();
|
|
10
|
+
this.model = model;
|
|
11
|
+
}
|
|
12
|
+
$ready() {
|
|
13
|
+
const map = this.model;
|
|
14
|
+
map.forEach((value, key) => {
|
|
15
|
+
this.createChild(key, value);
|
|
16
|
+
});
|
|
17
|
+
super.$ready();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseView } from "./base-view";
|
|
2
|
+
/**
|
|
3
|
+
* Create a children pack for each object field
|
|
4
|
+
* @class ObjectView
|
|
5
|
+
* @extends BaseView
|
|
6
|
+
*/
|
|
7
|
+
export class ObjectView extends BaseView {
|
|
8
|
+
constructor(model) {
|
|
9
|
+
super();
|
|
10
|
+
this.model = model;
|
|
11
|
+
}
|
|
12
|
+
$ready() {
|
|
13
|
+
const obj = this.model;
|
|
14
|
+
for (const key in obj) {
|
|
15
|
+
this.createChild(key, obj[key]);
|
|
16
|
+
}
|
|
17
|
+
super.$ready();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Fragment, INodePrivate } from "../node/node";
|
|
2
|
+
import { Slot } from "../core/slot";
|
|
3
|
+
import { timeoutExecutor } from "../core/executor";
|
|
4
|
+
/**
|
|
5
|
+
* Private part of repeat node
|
|
6
|
+
* @class RepeatNodePrivate
|
|
7
|
+
* @extends INodePrivate
|
|
8
|
+
*/
|
|
9
|
+
export class RepeatNodePrivate extends INodePrivate {
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
/**
|
|
13
|
+
* Children node hash
|
|
14
|
+
* @type {Map}
|
|
15
|
+
*/
|
|
16
|
+
this.nodes = new Map();
|
|
17
|
+
this.$seal();
|
|
18
|
+
}
|
|
19
|
+
$destroy() {
|
|
20
|
+
this.nodes.clear();
|
|
21
|
+
super.$destroy();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Repeat node repeats its children
|
|
26
|
+
* @class RepeatNode
|
|
27
|
+
* @extends Fragment
|
|
28
|
+
*/
|
|
29
|
+
export class RepeatNode extends Fragment {
|
|
30
|
+
constructor($) {
|
|
31
|
+
super($ || new RepeatNodePrivate);
|
|
32
|
+
/**
|
|
33
|
+
* If false will use timeout executor, otherwise the app executor
|
|
34
|
+
*/
|
|
35
|
+
this.freezeUi = true;
|
|
36
|
+
this.slot = new Slot;
|
|
37
|
+
}
|
|
38
|
+
createChild(id, item, before) {
|
|
39
|
+
// TODO: Refactor: remove @ts-ignore
|
|
40
|
+
const node = new Fragment();
|
|
41
|
+
// eslint-disable-next-line
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
const $ = node.$;
|
|
44
|
+
this.destroyChild(id, item);
|
|
45
|
+
if (before) {
|
|
46
|
+
$.next = before;
|
|
47
|
+
// eslint-disable-next-line
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
$.prev = before.$.prev;
|
|
50
|
+
// eslint-disable-next-line
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
before.$.prev = node;
|
|
53
|
+
if ($.prev) {
|
|
54
|
+
// eslint-disable-next-line
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
$.prev.$.next = node;
|
|
57
|
+
}
|
|
58
|
+
this.$children.splice(this.$children.indexOf(before), 0, node);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const lastChild = this.$children[this.$children.length - 1];
|
|
62
|
+
if (lastChild) {
|
|
63
|
+
// eslint-disable-next-line
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
lastChild.$.next = node;
|
|
66
|
+
}
|
|
67
|
+
$.prev = lastChild;
|
|
68
|
+
this.$children.push(node);
|
|
69
|
+
}
|
|
70
|
+
node.$preinit(this.$.app, this);
|
|
71
|
+
node.$init();
|
|
72
|
+
const callback = () => {
|
|
73
|
+
this.slot.release(node, item, id);
|
|
74
|
+
node.$ready();
|
|
75
|
+
};
|
|
76
|
+
if (this.freezeUi) {
|
|
77
|
+
this.$.app.$run.callCallback(callback);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
timeoutExecutor.callCallback(callback);
|
|
81
|
+
}
|
|
82
|
+
this.$.nodes.set(id, node);
|
|
83
|
+
}
|
|
84
|
+
destroyChild(id, item) {
|
|
85
|
+
const $ = this.$;
|
|
86
|
+
const child = $.nodes.get(id);
|
|
87
|
+
if (child) {
|
|
88
|
+
// eslint-disable-next-line
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
const $ = child.$;
|
|
91
|
+
if ($.prev) {
|
|
92
|
+
// eslint-disable-next-line
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
$.prev.$.next = $.next;
|
|
95
|
+
}
|
|
96
|
+
if ($.next) {
|
|
97
|
+
// eslint-disable-next-line
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
$.next.$.prev = $.prev;
|
|
100
|
+
}
|
|
101
|
+
child.$destroy();
|
|
102
|
+
this.$.nodes.delete(id);
|
|
103
|
+
this.$children.splice(this.$children.indexOf(child), 1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { RepeatNode, RepeatNodePrivate } from "./repeat-node";
|
|
2
|
+
import { Reference } from "../value/reference";
|
|
3
|
+
/**
|
|
4
|
+
* Private part of repeater
|
|
5
|
+
* @class RepeaterPrivate
|
|
6
|
+
* @extends RepeatNodePrivate
|
|
7
|
+
*/
|
|
8
|
+
export class RepeaterPrivate extends RepeatNodePrivate {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
/**
|
|
12
|
+
* Current count of child nodes
|
|
13
|
+
*/
|
|
14
|
+
this.currentCount = 0;
|
|
15
|
+
this.$seal();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The simplest repeat node interpretation, repeat children pack a several times
|
|
20
|
+
* @class Repeater
|
|
21
|
+
* @extends RepeatNode
|
|
22
|
+
*/
|
|
23
|
+
export class Repeater extends RepeatNode {
|
|
24
|
+
constructor($) {
|
|
25
|
+
super($ || new RepeaterPrivate);
|
|
26
|
+
/**
|
|
27
|
+
* The count of children
|
|
28
|
+
*/
|
|
29
|
+
this.count = new Reference(0);
|
|
30
|
+
this.$seal();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Changes the children count
|
|
34
|
+
*/
|
|
35
|
+
changeCount(number) {
|
|
36
|
+
const $ = this.$;
|
|
37
|
+
if (number > $.currentCount) {
|
|
38
|
+
for (let i = $.currentCount; i < number; i++) {
|
|
39
|
+
this.createChild(i, i);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
for (let i = $.currentCount - 1; i >= number; i--) {
|
|
44
|
+
this.destroyChild(i, i);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
$.currentCount = number;
|
|
48
|
+
}
|
|
49
|
+
$created() {
|
|
50
|
+
const $ = this.$;
|
|
51
|
+
super.$created();
|
|
52
|
+
$.updateHandler = this.changeCount.bind(this);
|
|
53
|
+
this.count.on($.updateHandler);
|
|
54
|
+
}
|
|
55
|
+
$ready() {
|
|
56
|
+
this.changeCount(this.count.$);
|
|
57
|
+
}
|
|
58
|
+
$destroy() {
|
|
59
|
+
const $ = this.$;
|
|
60
|
+
super.$destroy();
|
|
61
|
+
this.count.off($.updateHandler);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseView } from "./base-view";
|
|
2
|
+
/**
|
|
3
|
+
* Create a children pack for each set value
|
|
4
|
+
* @class SetView
|
|
5
|
+
* @extends BaseView
|
|
6
|
+
*/
|
|
7
|
+
export class SetView extends BaseView {
|
|
8
|
+
constructor(model) {
|
|
9
|
+
super();
|
|
10
|
+
this.model = model;
|
|
11
|
+
}
|
|
12
|
+
$ready() {
|
|
13
|
+
const $ = this.$;
|
|
14
|
+
const set = this.model;
|
|
15
|
+
set.forEach(item => {
|
|
16
|
+
$.app.$run.callCallback(() => {
|
|
17
|
+
this.createChild(item, item);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
super.$ready();
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vasille",
|
|
3
|
-
"description": "
|
|
3
|
+
"description": "Vasille - Safe. Fast. Powerful.",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "types/index.d.ts",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "2.0.3",
|
|
7
7
|
"exports": {
|
|
8
8
|
"import": "./lib/index.js",
|
|
9
9
|
"browser": "./lib/index.js"
|
|
10
10
|
},
|
|
11
|
+
"unpkg": "./cdn/es2015.js",
|
|
11
12
|
"scripts": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"doc": "jsdoc -a all lib/** DOCHOME.md",
|
|
20
|
-
"tsc": "tsc --build tsconfig.json"
|
|
13
|
+
"build": "tsc --build tsconfig-build.json",
|
|
14
|
+
"build-es5": "tsc --build tsconfig-build-es5.json",
|
|
15
|
+
"test": "jest",
|
|
16
|
+
"test-coverage": "jest --coverage",
|
|
17
|
+
"update-types": "tsc --build tsconfig-types.json",
|
|
18
|
+
"cdn-create": "node cdn/create.js",
|
|
19
|
+
"es5-check": "es-check es5 cdn/*es5.js"
|
|
21
20
|
},
|
|
22
21
|
"repository": {
|
|
23
22
|
"type": "git",
|
|
24
|
-
"url": "https://gitlab.com/vasille
|
|
23
|
+
"url": "https://gitlab.com/vasille-js/vasille-js.git"
|
|
25
24
|
},
|
|
26
25
|
"keywords": [
|
|
27
|
-
"
|
|
28
|
-
"
|
|
26
|
+
"safe",
|
|
27
|
+
"fast",
|
|
28
|
+
"poweful",
|
|
29
29
|
"frontend",
|
|
30
|
-
"
|
|
30
|
+
"javascript",
|
|
31
|
+
"typescript",
|
|
32
|
+
"flow-js"
|
|
31
33
|
],
|
|
32
34
|
"author": "Vasile Lixcode <lixcode@vivaldi.net> (https://t.me/lixcode)",
|
|
33
35
|
"license": "MIT",
|
|
@@ -37,10 +39,16 @@
|
|
|
37
39
|
"@types/eslint-scope": "latest",
|
|
38
40
|
"@types/estree": "latest",
|
|
39
41
|
"@types/events": "latest",
|
|
42
|
+
"@types/jest": "latest",
|
|
43
|
+
"@types/jsdom": "latest",
|
|
40
44
|
"@types/node": "latest",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "latest",
|
|
46
|
+
"@typescript-eslint/parser": "latest",
|
|
47
|
+
"es-check": "latest",
|
|
48
|
+
"eslint": "latest",
|
|
49
|
+
"jest": "latest",
|
|
50
|
+
"jsdom": "latest",
|
|
51
|
+
"ts-jest": "latest",
|
|
44
52
|
"typescript": "latest"
|
|
45
53
|
}
|
|
46
54
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Binding } from "./binding";
|
|
2
|
+
import type { INode } from "../node/node";
|
|
3
|
+
import type { IValue } from "../core/ivalue";
|
|
4
|
+
/**
|
|
5
|
+
* Represents an Attribute binding description
|
|
6
|
+
* @class AttributeBinding
|
|
7
|
+
* @extends Binding
|
|
8
|
+
*/
|
|
9
|
+
export declare class AttributeBinding extends Binding<string> {
|
|
10
|
+
/**
|
|
11
|
+
* Constructs an attribute binding description
|
|
12
|
+
* @param node {INode} the vasille node
|
|
13
|
+
* @param name {String} the name of attribute
|
|
14
|
+
* @param value {IValue} value to bind
|
|
15
|
+
*/
|
|
16
|
+
constructor(node: INode, name: string, value: IValue<string>);
|
|
17
|
+
/**
|
|
18
|
+
* Generates a function which updates the attribute value
|
|
19
|
+
* @param name {String} The name of attribute
|
|
20
|
+
* @returns {Function} a function which will update attribute value
|
|
21
|
+
*/
|
|
22
|
+
protected bound(name: string): (node: INode, value: string) => void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Destroyable } from "../core/destroyable";
|
|
2
|
+
import type { IValue } from "../core/ivalue";
|
|
3
|
+
import type { INode } from "../node/node";
|
|
4
|
+
/**
|
|
5
|
+
* Describe a common binding logic
|
|
6
|
+
* @class Binding
|
|
7
|
+
* @extends Destroyable
|
|
8
|
+
*/
|
|
9
|
+
export declare class Binding<T> extends Destroyable {
|
|
10
|
+
private binding;
|
|
11
|
+
private readonly updateFunc;
|
|
12
|
+
/**
|
|
13
|
+
* Constructs a common binding logic
|
|
14
|
+
* @param node {INode} the vasille node
|
|
15
|
+
* @param name {String} the name of property/attribute/class
|
|
16
|
+
* @param value {IValue} the value to bind
|
|
17
|
+
*/
|
|
18
|
+
constructor(node: INode, name: string, value: IValue<T>);
|
|
19
|
+
/**
|
|
20
|
+
* Is a virtual function to get the specific bind function
|
|
21
|
+
* @param name {String} the name of attribute/property
|
|
22
|
+
* @returns {Function} a function to update attribute/property value
|
|
23
|
+
* @throws Always throws and must be overloaded in child class
|
|
24
|
+
*/
|
|
25
|
+
protected bound(name: string): (node: INode, value: T) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Just clear bindings
|
|
28
|
+
*/
|
|
29
|
+
$destroy(): void;
|
|
30
|
+
}
|