vasille 2.0.5 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/cdn/es2015.js +827 -827
- package/cdn/es5.js +909 -829
- package/flow-typed/vasille.js +2647 -835
- package/lib/binding/attribute.js +8 -3
- package/lib/binding/binding.js +5 -5
- package/lib/binding/class.js +4 -4
- package/lib/binding/style.js +2 -2
- package/lib/core/core.js +73 -17
- package/lib/core/destroyable.js +2 -2
- package/lib/core/ivalue.js +4 -4
- package/lib/functional/components.js +17 -0
- package/lib/functional/merge.js +41 -0
- package/lib/functional/models.js +26 -0
- package/lib/functional/options.js +1 -0
- package/lib/functional/reactivity.js +33 -0
- package/lib/functional/stack.js +127 -0
- package/lib/index.js +2 -7
- package/lib/models/array-model.js +9 -0
- package/lib/models/object-model.js +28 -14
- package/lib/node/app.js +21 -12
- package/lib/node/node.js +229 -573
- package/lib/node/watch.js +6 -14
- package/lib/spec/html.js +1 -0
- package/lib/spec/react.js +1 -0
- package/lib/spec/svg.js +1 -0
- package/lib/v/index.js +23 -0
- package/lib/value/expression.js +21 -18
- package/lib/value/mirror.js +15 -15
- package/lib/value/pointer.js +5 -5
- package/lib/value/reference.js +18 -18
- package/lib/views/array-view.js +6 -10
- package/lib/views/base-view.js +12 -23
- package/lib/views/map-view.js +4 -9
- package/lib/views/object-view.js +4 -7
- package/lib/views/repeat-node.js +10 -22
- package/lib/views/set-view.js +4 -11
- package/package.json +3 -1
- package/types/binding/attribute.d.ts +2 -2
- package/types/binding/binding.d.ts +1 -1
- package/types/core/core.d.ts +31 -43
- package/types/core/destroyable.d.ts +2 -2
- package/types/core/ivalue.d.ts +4 -4
- package/types/functional/components.d.ts +4 -0
- package/types/functional/merge.d.ts +1 -0
- package/types/functional/models.d.ts +10 -0
- package/types/functional/options.d.ts +23 -0
- package/types/functional/reactivity.d.ts +11 -0
- package/types/functional/stack.d.ts +24 -0
- package/types/index.d.ts +3 -7
- package/types/models/array-model.d.ts +1 -0
- package/types/models/object-model.d.ts +2 -0
- package/types/node/app.d.ts +19 -17
- package/types/node/node.d.ts +67 -388
- package/types/node/watch.d.ts +9 -15
- package/types/spec/html.d.ts +975 -0
- package/types/spec/react.d.ts +4 -0
- package/types/spec/svg.d.ts +314 -0
- package/types/v/index.d.ts +36 -0
- package/types/value/expression.d.ts +11 -24
- package/types/value/mirror.d.ts +6 -6
- package/types/value/pointer.d.ts +1 -1
- package/types/value/reference.d.ts +7 -7
- package/types/views/array-view.d.ts +3 -4
- package/types/views/base-view.d.ts +8 -16
- package/types/views/map-view.d.ts +2 -3
- package/types/views/object-view.d.ts +2 -3
- package/types/views/repeat-node.d.ts +8 -9
- package/types/views/set-view.d.ts +2 -3
- package/types/core/executor.d.ts +0 -87
- package/types/core/signal.d.ts +0 -35
- package/types/core/slot.d.ts +0 -45
- package/types/node/interceptor.d.ts +0 -50
- package/types/views/repeater.d.ts +0 -38
package/cdn/es2015.js
CHANGED
|
@@ -149,13 +149,14 @@ class ObjectModel extends Object {
|
|
|
149
149
|
*/
|
|
150
150
|
constructor(obj = {}) {
|
|
151
151
|
super();
|
|
152
|
+
this.container = Object.create(null);
|
|
152
153
|
Object.defineProperty(this, 'listener', {
|
|
153
154
|
value: new Listener,
|
|
154
155
|
writable: false,
|
|
155
156
|
configurable: false
|
|
156
157
|
});
|
|
157
158
|
for (const i in obj) {
|
|
158
|
-
Object.defineProperty(this, i, {
|
|
159
|
+
Object.defineProperty(this.container, i, {
|
|
159
160
|
value: obj[i],
|
|
160
161
|
configurable: true,
|
|
161
162
|
writable: true,
|
|
@@ -170,8 +171,7 @@ class ObjectModel extends Object {
|
|
|
170
171
|
* @return {*}
|
|
171
172
|
*/
|
|
172
173
|
get(key) {
|
|
173
|
-
|
|
174
|
-
return ts[key];
|
|
174
|
+
return this.container[key];
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
177
|
* Sets an object property value
|
|
@@ -180,21 +180,19 @@ class ObjectModel extends Object {
|
|
|
180
180
|
* @return {ObjectModel} a pointer to this
|
|
181
181
|
*/
|
|
182
182
|
set(key, v) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
this.listener.emitRemoved(key, ts[key]);
|
|
187
|
-
ts[key] = v;
|
|
183
|
+
if (Reflect.has(this.container, key)) {
|
|
184
|
+
this.listener.emitRemoved(key, this.container[key]);
|
|
185
|
+
this.container[key] = v;
|
|
188
186
|
}
|
|
189
187
|
else {
|
|
190
|
-
Object.defineProperty(
|
|
188
|
+
Object.defineProperty(this.container, key, {
|
|
191
189
|
value: v,
|
|
192
190
|
configurable: true,
|
|
193
191
|
writable: true,
|
|
194
192
|
enumerable: true
|
|
195
193
|
});
|
|
196
194
|
}
|
|
197
|
-
this.listener.emitAdded(key,
|
|
195
|
+
this.listener.emitAdded(key, this.container[key]);
|
|
198
196
|
return this;
|
|
199
197
|
}
|
|
200
198
|
/**
|
|
@@ -202,12 +200,28 @@ class ObjectModel extends Object {
|
|
|
202
200
|
* @param key {string} property name
|
|
203
201
|
*/
|
|
204
202
|
delete(key) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
this.
|
|
208
|
-
delete ts[key];
|
|
203
|
+
if (this.container[key]) {
|
|
204
|
+
this.listener.emitRemoved(key, this.container[key]);
|
|
205
|
+
delete this.container[key];
|
|
209
206
|
}
|
|
210
207
|
}
|
|
208
|
+
proxy() {
|
|
209
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
210
|
+
const ts = this;
|
|
211
|
+
return new Proxy(this.container, {
|
|
212
|
+
get(target, p) {
|
|
213
|
+
return ts.get(p);
|
|
214
|
+
},
|
|
215
|
+
set(target, p, value) {
|
|
216
|
+
ts.set(p, value);
|
|
217
|
+
return true;
|
|
218
|
+
},
|
|
219
|
+
deleteProperty(target, p) {
|
|
220
|
+
ts.delete(p);
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
211
225
|
enableReactivity() {
|
|
212
226
|
this.listener.enableReactivity();
|
|
213
227
|
}
|
|
@@ -373,6 +387,15 @@ class ArrayModel extends Array {
|
|
|
373
387
|
super.push(data[i]);
|
|
374
388
|
}
|
|
375
389
|
}
|
|
390
|
+
// proxy
|
|
391
|
+
proxy() {
|
|
392
|
+
return new Proxy(this, {
|
|
393
|
+
set(target, p, value) {
|
|
394
|
+
target.splice(parseInt(p), 1, value);
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
}
|
|
376
399
|
/* Array members */
|
|
377
400
|
/**
|
|
378
401
|
* Gets the last item of array
|
|
@@ -862,7 +885,7 @@ class Destroyable {
|
|
|
862
885
|
* Make object fields non configurable
|
|
863
886
|
* @protected
|
|
864
887
|
*/
|
|
865
|
-
seal() {
|
|
888
|
+
$seal() {
|
|
866
889
|
const $ = this;
|
|
867
890
|
Object.keys($).forEach(i => {
|
|
868
891
|
// eslint-disable-next-line no-prototype-builtins
|
|
@@ -894,7 +917,7 @@ class Destroyable {
|
|
|
894
917
|
/**
|
|
895
918
|
* Garbage collector method
|
|
896
919
|
*/
|
|
897
|
-
destroy() {
|
|
920
|
+
$destroy() {
|
|
898
921
|
// nothing here
|
|
899
922
|
}
|
|
900
923
|
}
|
|
@@ -906,13 +929,13 @@ class Switchable extends Destroyable {
|
|
|
906
929
|
/**
|
|
907
930
|
* Enable update handlers triggering
|
|
908
931
|
*/
|
|
909
|
-
enable() {
|
|
932
|
+
$enable() {
|
|
910
933
|
throw notOverwritten();
|
|
911
934
|
}
|
|
912
935
|
/**
|
|
913
936
|
* disable update handlers triggering
|
|
914
937
|
*/
|
|
915
|
-
disable() {
|
|
938
|
+
$disable() {
|
|
916
939
|
throw notOverwritten();
|
|
917
940
|
}
|
|
918
941
|
}
|
|
@@ -947,14 +970,14 @@ class IValue extends Switchable {
|
|
|
947
970
|
* Add a new handler to value change
|
|
948
971
|
* @param handler {function(value : *)} the handler to add
|
|
949
972
|
*/
|
|
950
|
-
on(handler) {
|
|
973
|
+
$on(handler) {
|
|
951
974
|
throw notOverwritten();
|
|
952
975
|
}
|
|
953
976
|
/**
|
|
954
977
|
* Removes a handler of value change
|
|
955
978
|
* @param handler {function(value : *)} the handler to remove
|
|
956
979
|
*/
|
|
957
|
-
off(handler) {
|
|
980
|
+
$off(handler) {
|
|
958
981
|
throw notOverwritten();
|
|
959
982
|
}
|
|
960
983
|
}
|
|
@@ -966,6 +989,18 @@ window.IValue = IValue;
|
|
|
966
989
|
|
|
967
990
|
|
|
968
991
|
|
|
992
|
+
// ./lib/spec/svg.js
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
// ./lib/spec/react.js
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
// ./lib/spec/html.js
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
969
1004
|
// ./lib/value/expression.js
|
|
970
1005
|
/**
|
|
971
1006
|
* Bind some values to one expression
|
|
@@ -973,13 +1008,18 @@ window.IValue = IValue;
|
|
|
973
1008
|
* @extends IValue
|
|
974
1009
|
*/
|
|
975
1010
|
class Expression extends IValue {
|
|
976
|
-
|
|
1011
|
+
/**
|
|
1012
|
+
* Creates a function bounded to N values
|
|
1013
|
+
* @param func {Function} the function to bound
|
|
1014
|
+
* @param values
|
|
1015
|
+
* @param link {Boolean} links immediately if true
|
|
1016
|
+
*/
|
|
1017
|
+
constructor(func, link, ...values) {
|
|
977
1018
|
super(false);
|
|
978
1019
|
/**
|
|
979
1020
|
* Expression will link different handler for each value of list
|
|
980
1021
|
*/
|
|
981
1022
|
this.linkedFunc = [];
|
|
982
|
-
const values = [v1, v2, v3, v4, v5, v6, v7, v8, v9].filter(v => v instanceof IValue);
|
|
983
1023
|
const handler = (i) => {
|
|
984
1024
|
if (i != null) {
|
|
985
1025
|
this.valuesCache[i] = this.values[i].$;
|
|
@@ -988,23 +1028,21 @@ class Expression extends IValue {
|
|
|
988
1028
|
};
|
|
989
1029
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
990
1030
|
// @ts-ignore
|
|
991
|
-
this.valuesCache = values.map(
|
|
1031
|
+
this.valuesCache = values.map(item => item.$);
|
|
992
1032
|
this.sync = new Reference(func.apply(this, this.valuesCache));
|
|
993
1033
|
let i = 0;
|
|
994
1034
|
values.forEach(() => {
|
|
995
1035
|
this.linkedFunc.push(handler.bind(this, Number(i++)));
|
|
996
1036
|
});
|
|
997
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
998
|
-
// @ts-ignore
|
|
999
1037
|
this.values = values;
|
|
1000
1038
|
this.func = handler;
|
|
1001
1039
|
if (link) {
|
|
1002
|
-
this
|
|
1040
|
+
this.$enable();
|
|
1003
1041
|
}
|
|
1004
1042
|
else {
|
|
1005
1043
|
handler();
|
|
1006
1044
|
}
|
|
1007
|
-
this
|
|
1045
|
+
this.$seal();
|
|
1008
1046
|
}
|
|
1009
1047
|
get $() {
|
|
1010
1048
|
return this.sync.$;
|
|
@@ -1012,18 +1050,18 @@ class Expression extends IValue {
|
|
|
1012
1050
|
set $(value) {
|
|
1013
1051
|
this.sync.$ = value;
|
|
1014
1052
|
}
|
|
1015
|
-
on(handler) {
|
|
1016
|
-
this.sync
|
|
1053
|
+
$on(handler) {
|
|
1054
|
+
this.sync.$on(handler);
|
|
1017
1055
|
return this;
|
|
1018
1056
|
}
|
|
1019
|
-
off(handler) {
|
|
1020
|
-
this.sync
|
|
1057
|
+
$off(handler) {
|
|
1058
|
+
this.sync.$off(handler);
|
|
1021
1059
|
return this;
|
|
1022
1060
|
}
|
|
1023
|
-
enable() {
|
|
1061
|
+
$enable() {
|
|
1024
1062
|
if (!this.isEnabled) {
|
|
1025
1063
|
for (let i = 0; i < this.values.length; i++) {
|
|
1026
|
-
this.values[i]
|
|
1064
|
+
this.values[i].$on(this.linkedFunc[i]);
|
|
1027
1065
|
this.valuesCache[i] = this.values[i].$;
|
|
1028
1066
|
}
|
|
1029
1067
|
this.func();
|
|
@@ -1031,21 +1069,21 @@ class Expression extends IValue {
|
|
|
1031
1069
|
}
|
|
1032
1070
|
return this;
|
|
1033
1071
|
}
|
|
1034
|
-
disable() {
|
|
1072
|
+
$disable() {
|
|
1035
1073
|
if (this.isEnabled) {
|
|
1036
1074
|
for (let i = 0; i < this.values.length; i++) {
|
|
1037
|
-
this.values[i]
|
|
1075
|
+
this.values[i].$off(this.linkedFunc[i]);
|
|
1038
1076
|
}
|
|
1039
1077
|
this.isEnabled = false;
|
|
1040
1078
|
}
|
|
1041
1079
|
return this;
|
|
1042
1080
|
}
|
|
1043
|
-
destroy() {
|
|
1044
|
-
this
|
|
1081
|
+
$destroy() {
|
|
1082
|
+
this.$disable();
|
|
1045
1083
|
this.values.splice(0);
|
|
1046
1084
|
this.valuesCache.splice(0);
|
|
1047
1085
|
this.linkedFunc.splice(0);
|
|
1048
|
-
super
|
|
1086
|
+
super.$destroy();
|
|
1049
1087
|
}
|
|
1050
1088
|
}
|
|
1051
1089
|
|
|
@@ -1063,43 +1101,43 @@ class Reference extends IValue {
|
|
|
1063
1101
|
*/
|
|
1064
1102
|
constructor(value) {
|
|
1065
1103
|
super(true);
|
|
1066
|
-
this
|
|
1067
|
-
this
|
|
1068
|
-
this
|
|
1104
|
+
this.$value = value;
|
|
1105
|
+
this.$onchange = new Set;
|
|
1106
|
+
this.$seal();
|
|
1069
1107
|
}
|
|
1070
1108
|
get $() {
|
|
1071
|
-
return this
|
|
1109
|
+
return this.$value;
|
|
1072
1110
|
}
|
|
1073
1111
|
set $(value) {
|
|
1074
|
-
if (this
|
|
1075
|
-
this
|
|
1112
|
+
if (this.$value !== value) {
|
|
1113
|
+
this.$value = value;
|
|
1076
1114
|
if (this.isEnabled) {
|
|
1077
|
-
this
|
|
1115
|
+
this.$onchange.forEach(handler => {
|
|
1078
1116
|
handler(value);
|
|
1079
1117
|
});
|
|
1080
1118
|
}
|
|
1081
1119
|
}
|
|
1082
1120
|
}
|
|
1083
|
-
enable() {
|
|
1121
|
+
$enable() {
|
|
1084
1122
|
if (!this.isEnabled) {
|
|
1085
|
-
this
|
|
1086
|
-
handler(this
|
|
1123
|
+
this.$onchange.forEach(handler => {
|
|
1124
|
+
handler(this.$value);
|
|
1087
1125
|
});
|
|
1088
1126
|
this.isEnabled = true;
|
|
1089
1127
|
}
|
|
1090
1128
|
}
|
|
1091
|
-
disable() {
|
|
1129
|
+
$disable() {
|
|
1092
1130
|
this.isEnabled = false;
|
|
1093
1131
|
}
|
|
1094
|
-
on(handler) {
|
|
1095
|
-
this
|
|
1132
|
+
$on(handler) {
|
|
1133
|
+
this.$onchange.add(handler);
|
|
1096
1134
|
}
|
|
1097
|
-
off(handler) {
|
|
1098
|
-
this
|
|
1135
|
+
$off(handler) {
|
|
1136
|
+
this.$onchange.delete(handler);
|
|
1099
1137
|
}
|
|
1100
|
-
destroy() {
|
|
1101
|
-
super
|
|
1102
|
-
this
|
|
1138
|
+
$destroy() {
|
|
1139
|
+
super.$destroy();
|
|
1140
|
+
this.$onchange.clear();
|
|
1103
1141
|
}
|
|
1104
1142
|
}
|
|
1105
1143
|
|
|
@@ -1120,13 +1158,13 @@ class Mirror extends Reference {
|
|
|
1120
1158
|
*/
|
|
1121
1159
|
constructor(value, forwardOnly = false) {
|
|
1122
1160
|
super(value.$);
|
|
1123
|
-
this
|
|
1161
|
+
this.$handler = (v) => {
|
|
1124
1162
|
this.$ = v;
|
|
1125
1163
|
};
|
|
1126
|
-
this
|
|
1127
|
-
this
|
|
1128
|
-
value
|
|
1129
|
-
this
|
|
1164
|
+
this.$pointedValue = value;
|
|
1165
|
+
this.$forwardOnly = forwardOnly;
|
|
1166
|
+
value.$on(this.$handler);
|
|
1167
|
+
this.$seal();
|
|
1130
1168
|
}
|
|
1131
1169
|
get $() {
|
|
1132
1170
|
// this is a ts bug
|
|
@@ -1135,30 +1173,30 @@ class Mirror extends Reference {
|
|
|
1135
1173
|
return super.$;
|
|
1136
1174
|
}
|
|
1137
1175
|
set $(v) {
|
|
1138
|
-
if (!this
|
|
1139
|
-
this
|
|
1176
|
+
if (!this.$forwardOnly) {
|
|
1177
|
+
this.$pointedValue.$ = v;
|
|
1140
1178
|
}
|
|
1141
1179
|
// this is a ts bug
|
|
1142
1180
|
// eslint-disable-next-line
|
|
1143
1181
|
// @ts-ignore
|
|
1144
1182
|
super.$ = v;
|
|
1145
1183
|
}
|
|
1146
|
-
enable() {
|
|
1184
|
+
$enable() {
|
|
1147
1185
|
if (!this.isEnabled) {
|
|
1148
1186
|
this.isEnabled = true;
|
|
1149
|
-
this
|
|
1150
|
-
this.$ = this
|
|
1187
|
+
this.$pointedValue.$on(this.$handler);
|
|
1188
|
+
this.$ = this.$pointedValue.$;
|
|
1151
1189
|
}
|
|
1152
1190
|
}
|
|
1153
|
-
disable() {
|
|
1191
|
+
$disable() {
|
|
1154
1192
|
if (this.isEnabled) {
|
|
1155
|
-
this
|
|
1193
|
+
this.$pointedValue.$off(this.$handler);
|
|
1156
1194
|
this.isEnabled = false;
|
|
1157
1195
|
}
|
|
1158
1196
|
}
|
|
1159
|
-
destroy() {
|
|
1160
|
-
this
|
|
1161
|
-
super
|
|
1197
|
+
$destroy() {
|
|
1198
|
+
this.$disable();
|
|
1199
|
+
super.$destroy();
|
|
1162
1200
|
}
|
|
1163
1201
|
}
|
|
1164
1202
|
|
|
@@ -1182,11 +1220,11 @@ class Pointer extends Mirror {
|
|
|
1182
1220
|
* Point a new ivalue
|
|
1183
1221
|
* @param value {IValue} value to point
|
|
1184
1222
|
*/
|
|
1185
|
-
|
|
1186
|
-
if (this
|
|
1187
|
-
this
|
|
1188
|
-
this
|
|
1189
|
-
this
|
|
1223
|
+
set $$(value) {
|
|
1224
|
+
if (this.$pointedValue !== value) {
|
|
1225
|
+
this.$disable();
|
|
1226
|
+
this.$pointedValue = value;
|
|
1227
|
+
this.$enable();
|
|
1190
1228
|
}
|
|
1191
1229
|
}
|
|
1192
1230
|
}
|
|
@@ -1207,25 +1245,34 @@ class Binding extends Destroyable {
|
|
|
1207
1245
|
constructor(value) {
|
|
1208
1246
|
super();
|
|
1209
1247
|
this.binding = value;
|
|
1210
|
-
this
|
|
1248
|
+
this.$seal();
|
|
1211
1249
|
}
|
|
1212
1250
|
init(bounded) {
|
|
1213
1251
|
this.func = bounded;
|
|
1214
|
-
this.binding
|
|
1252
|
+
this.binding.$on(this.func);
|
|
1215
1253
|
this.func(this.binding.$);
|
|
1216
1254
|
}
|
|
1217
1255
|
/**
|
|
1218
1256
|
* Just clear bindings
|
|
1219
1257
|
*/
|
|
1220
|
-
destroy() {
|
|
1221
|
-
this.binding
|
|
1222
|
-
super
|
|
1258
|
+
$destroy() {
|
|
1259
|
+
this.binding.$off(this.func);
|
|
1260
|
+
super.$destroy();
|
|
1223
1261
|
}
|
|
1224
1262
|
}
|
|
1225
1263
|
|
|
1226
1264
|
window.Binding = Binding;
|
|
1227
1265
|
|
|
1228
1266
|
// ./lib/core/core.js
|
|
1267
|
+
|
|
1268
|
+
const currentStack = [];
|
|
1269
|
+
function stack(node) {
|
|
1270
|
+
currentStack.push(current);
|
|
1271
|
+
current = node;
|
|
1272
|
+
}
|
|
1273
|
+
function unstack() {
|
|
1274
|
+
current = currentStack.pop();
|
|
1275
|
+
}
|
|
1229
1276
|
/**
|
|
1230
1277
|
* Private stuff of a reactive object
|
|
1231
1278
|
* @class ReactivePrivate
|
|
@@ -1258,18 +1305,18 @@ class ReactivePrivate extends Destroyable {
|
|
|
1258
1305
|
* @type {boolean}
|
|
1259
1306
|
*/
|
|
1260
1307
|
this.frozen = false;
|
|
1261
|
-
this
|
|
1308
|
+
this.$seal();
|
|
1262
1309
|
}
|
|
1263
|
-
destroy() {
|
|
1264
|
-
|
|
1265
|
-
this.watch.forEach(value => value.destroy());
|
|
1310
|
+
$destroy() {
|
|
1311
|
+
this.watch.forEach(value => value.$destroy());
|
|
1266
1312
|
this.watch.clear();
|
|
1267
|
-
this.bindings.forEach(binding => binding
|
|
1313
|
+
this.bindings.forEach(binding => binding.$destroy());
|
|
1268
1314
|
this.bindings.clear();
|
|
1269
1315
|
this.models.forEach(model => model.disableReactivity());
|
|
1270
1316
|
this.models.clear();
|
|
1271
|
-
|
|
1272
|
-
|
|
1317
|
+
this.freezeExpr && this.freezeExpr.$destroy();
|
|
1318
|
+
this.onDestroy && this.onDestroy();
|
|
1319
|
+
super.$destroy();
|
|
1273
1320
|
}
|
|
1274
1321
|
}
|
|
1275
1322
|
/**
|
|
@@ -1278,9 +1325,17 @@ class ReactivePrivate extends Destroyable {
|
|
|
1278
1325
|
* @extends Destroyable
|
|
1279
1326
|
*/
|
|
1280
1327
|
class Reactive extends Destroyable {
|
|
1281
|
-
constructor($) {
|
|
1328
|
+
constructor(input, $) {
|
|
1282
1329
|
super();
|
|
1330
|
+
this.input = input;
|
|
1283
1331
|
this.$ = $ || new ReactivePrivate;
|
|
1332
|
+
this.$seal();
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Get parent node
|
|
1336
|
+
*/
|
|
1337
|
+
get parent() {
|
|
1338
|
+
return this.$.parent;
|
|
1284
1339
|
}
|
|
1285
1340
|
/**
|
|
1286
1341
|
* Create a reference
|
|
@@ -1329,12 +1384,23 @@ class Reactive extends Destroyable {
|
|
|
1329
1384
|
this.$.models.add(model);
|
|
1330
1385
|
return model;
|
|
1331
1386
|
}
|
|
1332
|
-
|
|
1387
|
+
/**
|
|
1388
|
+
* Creates a watcher
|
|
1389
|
+
* @param func {function} function to run on any argument change
|
|
1390
|
+
* @param values
|
|
1391
|
+
*/
|
|
1392
|
+
watch(func, ...values) {
|
|
1333
1393
|
const $ = this.$;
|
|
1334
|
-
$.watch.add(new Expression(func, !this.$.frozen,
|
|
1394
|
+
$.watch.add(new Expression(func, !this.$.frozen, ...values));
|
|
1335
1395
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1396
|
+
/**
|
|
1397
|
+
* Creates a computed value
|
|
1398
|
+
* @param func {function} function to run on any argument change
|
|
1399
|
+
* @param values
|
|
1400
|
+
* @return {IValue} the created ivalue
|
|
1401
|
+
*/
|
|
1402
|
+
expr(func, ...values) {
|
|
1403
|
+
const res = new Expression(func, !this.$.frozen, ...values);
|
|
1338
1404
|
const $ = this.$;
|
|
1339
1405
|
$.watch.add(res);
|
|
1340
1406
|
return res;
|
|
@@ -1346,7 +1412,7 @@ class Reactive extends Destroyable {
|
|
|
1346
1412
|
const $ = this.$;
|
|
1347
1413
|
if (!$.enabled) {
|
|
1348
1414
|
$.watch.forEach(watcher => {
|
|
1349
|
-
watcher
|
|
1415
|
+
watcher.$enable();
|
|
1350
1416
|
});
|
|
1351
1417
|
$.models.forEach(model => {
|
|
1352
1418
|
model.enableReactivity();
|
|
@@ -1361,7 +1427,7 @@ class Reactive extends Destroyable {
|
|
|
1361
1427
|
const $ = this.$;
|
|
1362
1428
|
if ($.enabled) {
|
|
1363
1429
|
$.watch.forEach(watcher => {
|
|
1364
|
-
watcher
|
|
1430
|
+
watcher.$disable();
|
|
1365
1431
|
});
|
|
1366
1432
|
$.models.forEach(model => {
|
|
1367
1433
|
model.disableReactivity();
|
|
@@ -1396,9 +1462,37 @@ class Reactive extends Destroyable {
|
|
|
1396
1462
|
}, true, cond);
|
|
1397
1463
|
return this;
|
|
1398
1464
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
this
|
|
1465
|
+
init() {
|
|
1466
|
+
this.applyOptions(this.input);
|
|
1467
|
+
this.compose(this.input);
|
|
1468
|
+
}
|
|
1469
|
+
applyOptions(input) {
|
|
1470
|
+
// empty
|
|
1471
|
+
}
|
|
1472
|
+
applyOptionsNow() {
|
|
1473
|
+
this.applyOptions(this.input);
|
|
1474
|
+
}
|
|
1475
|
+
compose(input) {
|
|
1476
|
+
// empty
|
|
1477
|
+
}
|
|
1478
|
+
composeNow() {
|
|
1479
|
+
this.compose(this.input);
|
|
1480
|
+
}
|
|
1481
|
+
runFunctional(f, ...args) {
|
|
1482
|
+
stack(this);
|
|
1483
|
+
// yet another ts bug
|
|
1484
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1485
|
+
// @ts-ignore
|
|
1486
|
+
const result = f(...args);
|
|
1487
|
+
unstack();
|
|
1488
|
+
return result;
|
|
1489
|
+
}
|
|
1490
|
+
runOnDestroy(func) {
|
|
1491
|
+
this.$.onDestroy = func;
|
|
1492
|
+
}
|
|
1493
|
+
$destroy() {
|
|
1494
|
+
super.$destroy();
|
|
1495
|
+
this.$.$destroy();
|
|
1402
1496
|
this.$ = null;
|
|
1403
1497
|
}
|
|
1404
1498
|
}
|
|
@@ -1415,7 +1509,7 @@ window.Reactive = Reactive;
|
|
|
1415
1509
|
class FragmentPrivate extends ReactivePrivate {
|
|
1416
1510
|
constructor() {
|
|
1417
1511
|
super();
|
|
1418
|
-
this
|
|
1512
|
+
this.$seal();
|
|
1419
1513
|
}
|
|
1420
1514
|
/**
|
|
1421
1515
|
* Pre-initializes the base of a fragment
|
|
@@ -1429,10 +1523,10 @@ class FragmentPrivate extends ReactivePrivate {
|
|
|
1429
1523
|
/**
|
|
1430
1524
|
* Unlinks all bindings
|
|
1431
1525
|
*/
|
|
1432
|
-
destroy() {
|
|
1526
|
+
$destroy() {
|
|
1433
1527
|
this.next = null;
|
|
1434
1528
|
this.prev = null;
|
|
1435
|
-
super
|
|
1529
|
+
super.$destroy();
|
|
1436
1530
|
}
|
|
1437
1531
|
}
|
|
1438
1532
|
/**
|
|
@@ -1442,10 +1536,11 @@ class FragmentPrivate extends ReactivePrivate {
|
|
|
1442
1536
|
class Fragment extends Reactive {
|
|
1443
1537
|
/**
|
|
1444
1538
|
* Constructs a Vasille Node
|
|
1539
|
+
* @param input
|
|
1445
1540
|
* @param $ {FragmentPrivate}
|
|
1446
1541
|
*/
|
|
1447
|
-
constructor($) {
|
|
1448
|
-
super($ || new FragmentPrivate);
|
|
1542
|
+
constructor(input, $) {
|
|
1543
|
+
super(input, $ || new FragmentPrivate);
|
|
1449
1544
|
/**
|
|
1450
1545
|
* The children list
|
|
1451
1546
|
* @type Array
|
|
@@ -1469,36 +1564,18 @@ class Fragment extends Reactive {
|
|
|
1469
1564
|
const $ = this.$;
|
|
1470
1565
|
$.preinit(app, parent);
|
|
1471
1566
|
}
|
|
1472
|
-
/**
|
|
1473
|
-
* Initialize node
|
|
1474
|
-
*/
|
|
1475
1567
|
init() {
|
|
1476
|
-
|
|
1477
|
-
this.
|
|
1478
|
-
this.compose();
|
|
1479
|
-
this.mounted();
|
|
1480
|
-
return this;
|
|
1568
|
+
super.init();
|
|
1569
|
+
this.ready();
|
|
1481
1570
|
}
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
}
|
|
1486
|
-
/** To be overloaded: mounted event handler */
|
|
1487
|
-
mounted() {
|
|
1488
|
-
// empty
|
|
1571
|
+
compose(input) {
|
|
1572
|
+
super.compose(input);
|
|
1573
|
+
input.slot && input.slot(this);
|
|
1489
1574
|
}
|
|
1490
1575
|
/** To be overloaded: ready event handler */
|
|
1491
1576
|
ready() {
|
|
1492
1577
|
// empty
|
|
1493
1578
|
}
|
|
1494
|
-
/** To be overloaded: watchers creation milestone */
|
|
1495
|
-
createWatchers() {
|
|
1496
|
-
// empty
|
|
1497
|
-
}
|
|
1498
|
-
/** To be overloaded: DOM creation milestone */
|
|
1499
|
-
compose() {
|
|
1500
|
-
// empty
|
|
1501
|
-
}
|
|
1502
1579
|
/**
|
|
1503
1580
|
* Pushes a node to children immediately
|
|
1504
1581
|
* @param node {Fragment} A node to push
|
|
@@ -1545,7 +1622,7 @@ class Fragment extends Reactive {
|
|
|
1545
1622
|
const child = this.findFirstChild();
|
|
1546
1623
|
const $ = this.$;
|
|
1547
1624
|
if (child) {
|
|
1548
|
-
|
|
1625
|
+
child.parentElement.insertBefore(node, child);
|
|
1549
1626
|
}
|
|
1550
1627
|
else if ($.next) {
|
|
1551
1628
|
$.next.insertAdjacent(node);
|
|
@@ -1562,14 +1639,9 @@ class Fragment extends Reactive {
|
|
|
1562
1639
|
text(text, cb) {
|
|
1563
1640
|
const $ = this.$;
|
|
1564
1641
|
const node = new TextNode();
|
|
1565
|
-
|
|
1566
|
-
node.preinit($.app, this, textValue);
|
|
1642
|
+
node.preinit($.app, this, text);
|
|
1567
1643
|
this.pushNode(node);
|
|
1568
|
-
|
|
1569
|
-
$.app.run.callCallback(() => {
|
|
1570
|
-
cb(node);
|
|
1571
|
-
});
|
|
1572
|
-
}
|
|
1644
|
+
cb && cb(node);
|
|
1573
1645
|
}
|
|
1574
1646
|
debug(text) {
|
|
1575
1647
|
if (this.$.app.debugUi) {
|
|
@@ -1577,39 +1649,35 @@ class Fragment extends Reactive {
|
|
|
1577
1649
|
node.preinit(this.$.app, this, text);
|
|
1578
1650
|
this.pushNode(node);
|
|
1579
1651
|
}
|
|
1580
|
-
return this;
|
|
1581
1652
|
}
|
|
1582
|
-
|
|
1653
|
+
/**
|
|
1654
|
+
* Defines a tag element
|
|
1655
|
+
* @param tagName {String} the tag name
|
|
1656
|
+
* @param input
|
|
1657
|
+
* @param cb {function(Tag, *)} callback
|
|
1658
|
+
*/
|
|
1659
|
+
tag(tagName, input, cb) {
|
|
1583
1660
|
const $ = this.$;
|
|
1584
|
-
const node = new Tag();
|
|
1661
|
+
const node = new Tag(input);
|
|
1662
|
+
input.slot = cb || input.slot;
|
|
1585
1663
|
node.preinit($.app, this, tagName);
|
|
1586
1664
|
node.init();
|
|
1587
1665
|
this.pushNode(node);
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
cb(node, node.node);
|
|
1591
|
-
}
|
|
1592
|
-
node.ready();
|
|
1593
|
-
});
|
|
1666
|
+
node.ready();
|
|
1667
|
+
return node.node;
|
|
1594
1668
|
}
|
|
1595
1669
|
/**
|
|
1596
1670
|
* Defines a custom element
|
|
1597
1671
|
* @param node {Fragment} vasille element to insert
|
|
1598
1672
|
* @param callback {function($ : *)}
|
|
1599
|
-
* @param callback1 {function($ : *)}
|
|
1600
1673
|
*/
|
|
1601
|
-
create(node, callback
|
|
1674
|
+
create(node, callback) {
|
|
1602
1675
|
const $ = this.$;
|
|
1603
1676
|
node.$.parent = this;
|
|
1604
1677
|
node.preinit($.app, this);
|
|
1605
|
-
|
|
1606
|
-
callback(node);
|
|
1607
|
-
}
|
|
1608
|
-
if (callback1) {
|
|
1609
|
-
callback1(node);
|
|
1610
|
-
}
|
|
1678
|
+
node.input.slot = callback || node.input.slot;
|
|
1611
1679
|
this.pushNode(node);
|
|
1612
|
-
node.init()
|
|
1680
|
+
node.init();
|
|
1613
1681
|
}
|
|
1614
1682
|
/**
|
|
1615
1683
|
* Defines an if node
|
|
@@ -1618,31 +1686,28 @@ class Fragment extends Reactive {
|
|
|
1618
1686
|
* @return {this}
|
|
1619
1687
|
*/
|
|
1620
1688
|
if(cond, cb) {
|
|
1621
|
-
return this.switch({ cond, cb });
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Defines a if-else node
|
|
1625
|
-
* @param ifCond {IValue} `if` condition
|
|
1626
|
-
* @param ifCb {function(Fragment)} Call-back to create `if` child nodes
|
|
1627
|
-
* @param elseCb {function(Fragment)} Call-back to create `else` child nodes
|
|
1628
|
-
*/
|
|
1629
|
-
if_else(ifCond, ifCb, elseCb) {
|
|
1630
|
-
return this.switch({ cond: ifCond, cb: ifCb }, { cond: trueIValue, cb: elseCb });
|
|
1631
|
-
}
|
|
1632
|
-
/**
|
|
1633
|
-
* Defines a switch nodes: Will break after first true condition
|
|
1634
|
-
* @param cases {...{ cond : IValue, cb : function(Fragment) }} cases
|
|
1635
|
-
* @return {INode}
|
|
1636
|
-
*/
|
|
1637
|
-
switch(...cases) {
|
|
1638
|
-
const $ = this.$;
|
|
1639
1689
|
const node = new SwitchedNode();
|
|
1640
|
-
node.preinit(
|
|
1690
|
+
node.preinit(this.$.app, this);
|
|
1641
1691
|
node.init();
|
|
1642
1692
|
this.pushNode(node);
|
|
1643
|
-
node.
|
|
1693
|
+
node.addCase(this.case(cond, cb));
|
|
1644
1694
|
node.ready();
|
|
1645
|
-
|
|
1695
|
+
}
|
|
1696
|
+
else(cb) {
|
|
1697
|
+
if (this.lastChild instanceof SwitchedNode) {
|
|
1698
|
+
this.lastChild.addCase(this.default(cb));
|
|
1699
|
+
}
|
|
1700
|
+
else {
|
|
1701
|
+
throw userError('wrong `else` function use', 'logic-error');
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
elif(cond, cb) {
|
|
1705
|
+
if (this.lastChild instanceof SwitchedNode) {
|
|
1706
|
+
this.lastChild.addCase(this.case(cond, cb));
|
|
1707
|
+
}
|
|
1708
|
+
else {
|
|
1709
|
+
throw userError('wrong `elif` function use', 'logic-error');
|
|
1710
|
+
}
|
|
1646
1711
|
}
|
|
1647
1712
|
/**
|
|
1648
1713
|
* Create a case for switch
|
|
@@ -1684,14 +1749,14 @@ class Fragment extends Reactive {
|
|
|
1684
1749
|
$.prev.$.next = $.next;
|
|
1685
1750
|
}
|
|
1686
1751
|
}
|
|
1687
|
-
destroy() {
|
|
1688
|
-
this.children.forEach(child => child
|
|
1752
|
+
$destroy() {
|
|
1753
|
+
this.children.forEach(child => child.$destroy());
|
|
1689
1754
|
this.children.clear();
|
|
1690
1755
|
this.lastChild = null;
|
|
1691
1756
|
if (this.$.parent.lastChild === this) {
|
|
1692
1757
|
this.$.parent.lastChild = this.$.prev;
|
|
1693
1758
|
}
|
|
1694
|
-
super
|
|
1759
|
+
super.$destroy();
|
|
1695
1760
|
}
|
|
1696
1761
|
}
|
|
1697
1762
|
const trueIValue = new Reference(true);
|
|
@@ -1703,25 +1768,28 @@ const trueIValue = new Reference(true);
|
|
|
1703
1768
|
class TextNodePrivate extends FragmentPrivate {
|
|
1704
1769
|
constructor() {
|
|
1705
1770
|
super();
|
|
1706
|
-
this
|
|
1771
|
+
this.$seal();
|
|
1707
1772
|
}
|
|
1708
1773
|
/**
|
|
1709
1774
|
* Pre-initializes a text node
|
|
1710
1775
|
* @param app {AppNode} the app node
|
|
1776
|
+
* @param parent
|
|
1711
1777
|
* @param text {IValue}
|
|
1712
1778
|
*/
|
|
1713
1779
|
preinitText(app, parent, text) {
|
|
1714
1780
|
super.preinit(app, parent);
|
|
1715
|
-
this.node = document.createTextNode(text.$);
|
|
1716
|
-
|
|
1717
|
-
this.
|
|
1718
|
-
|
|
1781
|
+
this.node = document.createTextNode(text instanceof IValue ? text.$ : text);
|
|
1782
|
+
if (text instanceof IValue) {
|
|
1783
|
+
this.bindings.add(new Expression((v) => {
|
|
1784
|
+
this.node.replaceData(0, -1, v);
|
|
1785
|
+
}, true, text));
|
|
1786
|
+
}
|
|
1719
1787
|
}
|
|
1720
1788
|
/**
|
|
1721
1789
|
* Clear node data
|
|
1722
1790
|
*/
|
|
1723
|
-
destroy() {
|
|
1724
|
-
super
|
|
1791
|
+
$destroy() {
|
|
1792
|
+
super.$destroy();
|
|
1725
1793
|
}
|
|
1726
1794
|
}
|
|
1727
1795
|
/**
|
|
@@ -1731,8 +1799,8 @@ class TextNodePrivate extends FragmentPrivate {
|
|
|
1731
1799
|
*/
|
|
1732
1800
|
class TextNode extends Fragment {
|
|
1733
1801
|
constructor($ = new TextNodePrivate()) {
|
|
1734
|
-
super($);
|
|
1735
|
-
this
|
|
1802
|
+
super({}, $);
|
|
1803
|
+
this.$seal();
|
|
1736
1804
|
}
|
|
1737
1805
|
preinit(app, parent, text) {
|
|
1738
1806
|
const $ = this.$;
|
|
@@ -1745,10 +1813,10 @@ class TextNode extends Fragment {
|
|
|
1745
1813
|
findFirstChild() {
|
|
1746
1814
|
return this.$.node;
|
|
1747
1815
|
}
|
|
1748
|
-
destroy() {
|
|
1816
|
+
$destroy() {
|
|
1749
1817
|
this.$.node.remove();
|
|
1750
|
-
this
|
|
1751
|
-
super
|
|
1818
|
+
this.$.$destroy();
|
|
1819
|
+
super.$destroy();
|
|
1752
1820
|
}
|
|
1753
1821
|
}
|
|
1754
1822
|
/**
|
|
@@ -1764,10 +1832,10 @@ class INodePrivate extends FragmentPrivate {
|
|
|
1764
1832
|
* @type {boolean}
|
|
1765
1833
|
*/
|
|
1766
1834
|
this.unmounted = false;
|
|
1767
|
-
this
|
|
1835
|
+
this.$seal();
|
|
1768
1836
|
}
|
|
1769
|
-
destroy() {
|
|
1770
|
-
super
|
|
1837
|
+
$destroy() {
|
|
1838
|
+
super.$destroy();
|
|
1771
1839
|
}
|
|
1772
1840
|
}
|
|
1773
1841
|
/**
|
|
@@ -1778,11 +1846,12 @@ class INodePrivate extends FragmentPrivate {
|
|
|
1778
1846
|
class INode extends Fragment {
|
|
1779
1847
|
/**
|
|
1780
1848
|
* Constructs a base node
|
|
1849
|
+
* @param input
|
|
1781
1850
|
* @param $ {?INodePrivate}
|
|
1782
1851
|
*/
|
|
1783
|
-
constructor($) {
|
|
1784
|
-
super($ || new INodePrivate);
|
|
1785
|
-
this
|
|
1852
|
+
constructor(input, $) {
|
|
1853
|
+
super(input, $ || new INodePrivate);
|
|
1854
|
+
this.$seal();
|
|
1786
1855
|
}
|
|
1787
1856
|
/**
|
|
1788
1857
|
* Get the bound node
|
|
@@ -1790,26 +1859,6 @@ class INode extends Fragment {
|
|
|
1790
1859
|
get node() {
|
|
1791
1860
|
return this.$.node;
|
|
1792
1861
|
}
|
|
1793
|
-
/**
|
|
1794
|
-
* Initialize node
|
|
1795
|
-
*/
|
|
1796
|
-
init() {
|
|
1797
|
-
this.createWatchers();
|
|
1798
|
-
this.createAttrs();
|
|
1799
|
-
this.createStyle();
|
|
1800
|
-
this.created();
|
|
1801
|
-
this.compose();
|
|
1802
|
-
this.mounted();
|
|
1803
|
-
return this;
|
|
1804
|
-
}
|
|
1805
|
-
/** To be overloaded: attributes creation milestone */
|
|
1806
|
-
createAttrs() {
|
|
1807
|
-
// empty
|
|
1808
|
-
}
|
|
1809
|
-
/** To be overloaded: $style attributes creation milestone */
|
|
1810
|
-
createStyle() {
|
|
1811
|
-
// empty
|
|
1812
|
-
}
|
|
1813
1862
|
/**
|
|
1814
1863
|
* Bind attribute value
|
|
1815
1864
|
* @param name {String} name of attribute
|
|
@@ -1820,18 +1869,20 @@ class INode extends Fragment {
|
|
|
1820
1869
|
const attr = new AttributeBinding(this, name, value);
|
|
1821
1870
|
$.bindings.add(attr);
|
|
1822
1871
|
}
|
|
1823
|
-
bindAttr(name, calculator, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
|
|
1824
|
-
const $ = this.$;
|
|
1825
|
-
const expr = this.bind(calculator, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
|
1826
|
-
$.bindings.add(new AttributeBinding(this, name, expr));
|
|
1827
|
-
}
|
|
1828
1872
|
/**
|
|
1829
1873
|
* Set attribute value
|
|
1830
1874
|
* @param name {string} name of attribute
|
|
1831
1875
|
* @param value {string} value
|
|
1832
1876
|
*/
|
|
1833
1877
|
setAttr(name, value) {
|
|
1834
|
-
|
|
1878
|
+
if (typeof value === 'boolean') {
|
|
1879
|
+
if (value) {
|
|
1880
|
+
this.$.node.setAttribute(name, "");
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
else {
|
|
1884
|
+
this.$.node.setAttribute(name, `${value}`);
|
|
1885
|
+
}
|
|
1835
1886
|
return this;
|
|
1836
1887
|
}
|
|
1837
1888
|
/**
|
|
@@ -1839,17 +1890,15 @@ class INode extends Fragment {
|
|
|
1839
1890
|
* @param cl {string} Class name
|
|
1840
1891
|
*/
|
|
1841
1892
|
addClass(cl) {
|
|
1842
|
-
this.$.
|
|
1893
|
+
this.$.node.classList.add(cl);
|
|
1843
1894
|
return this;
|
|
1844
1895
|
}
|
|
1845
1896
|
/**
|
|
1846
1897
|
* Adds some CSS classes
|
|
1847
1898
|
* @param cls {...string} classes names
|
|
1848
1899
|
*/
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
this.$.app.run.addClass(this.$.node, cl);
|
|
1852
|
-
});
|
|
1900
|
+
removeClasse(cl) {
|
|
1901
|
+
this.$.node.classList.remove(cl);
|
|
1853
1902
|
return this;
|
|
1854
1903
|
}
|
|
1855
1904
|
/**
|
|
@@ -1885,17 +1934,6 @@ class INode extends Fragment {
|
|
|
1885
1934
|
}
|
|
1886
1935
|
return this;
|
|
1887
1936
|
}
|
|
1888
|
-
bindStyle(name, calculator, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
|
|
1889
|
-
const $ = this.$;
|
|
1890
|
-
const expr = this.bind(calculator, v1, v2, v3, v4, v5, v6, v7, v8, v9);
|
|
1891
|
-
if ($.node instanceof HTMLElement) {
|
|
1892
|
-
$.bindings.add(new StyleBinding(this, name, expr));
|
|
1893
|
-
}
|
|
1894
|
-
else {
|
|
1895
|
-
throw userError('style can be applied to HTML elements only', 'non-html-element');
|
|
1896
|
-
}
|
|
1897
|
-
return this;
|
|
1898
|
-
}
|
|
1899
1937
|
/**
|
|
1900
1938
|
* Sets a style property value
|
|
1901
1939
|
* @param prop {string} Property name
|
|
@@ -1903,10 +1941,10 @@ class INode extends Fragment {
|
|
|
1903
1941
|
*/
|
|
1904
1942
|
setStyle(prop, value) {
|
|
1905
1943
|
if (this.$.node instanceof HTMLElement) {
|
|
1906
|
-
this.$.
|
|
1944
|
+
this.$.node.style.setProperty(prop, value);
|
|
1907
1945
|
}
|
|
1908
1946
|
else {
|
|
1909
|
-
throw userError("Style can be
|
|
1947
|
+
throw userError("Style can be set for HTML elements only", "non-html-element");
|
|
1910
1948
|
}
|
|
1911
1949
|
return this;
|
|
1912
1950
|
}
|
|
@@ -1920,446 +1958,156 @@ class INode extends Fragment {
|
|
|
1920
1958
|
this.$.node.addEventListener(name, handler, options);
|
|
1921
1959
|
return this;
|
|
1922
1960
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
* @param options {Object | boolean}
|
|
1926
|
-
*/
|
|
1927
|
-
oncontextmenu(handler, options) {
|
|
1928
|
-
return this.listen("contextmenu", handler, options);
|
|
1961
|
+
insertAdjacent(node) {
|
|
1962
|
+
this.$.node.parentNode.insertBefore(node, this.$.node);
|
|
1929
1963
|
}
|
|
1930
1964
|
/**
|
|
1931
|
-
*
|
|
1932
|
-
* @param
|
|
1965
|
+
* A v-show & ngShow alternative
|
|
1966
|
+
* @param cond {IValue} show condition
|
|
1933
1967
|
*/
|
|
1934
|
-
|
|
1935
|
-
|
|
1968
|
+
bindShow(cond) {
|
|
1969
|
+
const $ = this.$;
|
|
1970
|
+
const node = $.node;
|
|
1971
|
+
if (node instanceof HTMLElement) {
|
|
1972
|
+
let lastDisplay = node.style.display;
|
|
1973
|
+
const htmlNode = node;
|
|
1974
|
+
return this.bindAlive(cond, () => {
|
|
1975
|
+
lastDisplay = htmlNode.style.display;
|
|
1976
|
+
htmlNode.style.display = 'none';
|
|
1977
|
+
}, () => {
|
|
1978
|
+
htmlNode.style.display = lastDisplay;
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
else {
|
|
1982
|
+
throw userError('the element must be a html element', 'bind-show');
|
|
1983
|
+
}
|
|
1936
1984
|
}
|
|
1937
1985
|
/**
|
|
1938
|
-
*
|
|
1939
|
-
* @param
|
|
1986
|
+
* bind HTML
|
|
1987
|
+
* @param value {IValue}
|
|
1940
1988
|
*/
|
|
1941
|
-
|
|
1942
|
-
|
|
1989
|
+
bindDomApi(name, value) {
|
|
1990
|
+
const $ = this.$;
|
|
1991
|
+
const node = $.node;
|
|
1992
|
+
if (node instanceof HTMLElement) {
|
|
1993
|
+
node[name] = value.$;
|
|
1994
|
+
this.watch((v) => {
|
|
1995
|
+
node[name] = v;
|
|
1996
|
+
}, value);
|
|
1997
|
+
}
|
|
1998
|
+
else {
|
|
1999
|
+
throw userError("HTML can be bound for HTML nodes only", "dom-error");
|
|
2000
|
+
}
|
|
1943
2001
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
2002
|
+
applyOptions(options) {
|
|
2003
|
+
options["v:attr"] && Object.keys(options["v:attr"]).forEach(name => {
|
|
2004
|
+
const value = options["v:attr"][name];
|
|
2005
|
+
if (value instanceof IValue) {
|
|
2006
|
+
this.attr(name, value);
|
|
2007
|
+
}
|
|
2008
|
+
else {
|
|
2009
|
+
this.setAttr(name, value);
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
if (options.class) {
|
|
2013
|
+
const handleClass = (name, value) => {
|
|
2014
|
+
if (value instanceof IValue) {
|
|
2015
|
+
this.floatingClass(value, name);
|
|
2016
|
+
}
|
|
2017
|
+
else if (value && name !== '$') {
|
|
2018
|
+
this.addClass(name);
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
this.removeClasse(name);
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2024
|
+
if (Array.isArray(options.class)) {
|
|
2025
|
+
options.class.forEach(item => {
|
|
2026
|
+
if (item instanceof IValue) {
|
|
2027
|
+
this.bindClass(item);
|
|
2028
|
+
}
|
|
2029
|
+
else if (typeof item == "string") {
|
|
2030
|
+
this.addClass(item);
|
|
2031
|
+
}
|
|
2032
|
+
else {
|
|
2033
|
+
Reflect.ownKeys(item).forEach((name) => {
|
|
2034
|
+
handleClass(name, item[name]);
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
else {
|
|
2040
|
+
options.class.$.forEach(item => {
|
|
2041
|
+
this.bindClass(item);
|
|
2042
|
+
});
|
|
2043
|
+
Reflect.ownKeys(options.class).forEach((name) => {
|
|
2044
|
+
handleClass(name, options.class[name]);
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
options.style && Object.keys(options.style).forEach(name => {
|
|
2049
|
+
const value = options.style[name];
|
|
2050
|
+
if (value instanceof IValue) {
|
|
2051
|
+
this.style(name, value);
|
|
2052
|
+
}
|
|
2053
|
+
else if (typeof value === "string") {
|
|
2054
|
+
this.setStyle(name, value);
|
|
2055
|
+
}
|
|
2056
|
+
else {
|
|
2057
|
+
if (value[0] instanceof IValue) {
|
|
2058
|
+
this.style(name, this.expr((v) => v + value[1], value[0]));
|
|
2059
|
+
}
|
|
2060
|
+
else {
|
|
2061
|
+
this.setStyle(name, value[0] + value[1]);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
});
|
|
2065
|
+
options["v:events"] && Object.keys(options["v:events"]).forEach(name => {
|
|
2066
|
+
this.listen(name, options["v:events"][name]);
|
|
2067
|
+
});
|
|
2068
|
+
if (options["v:bind"]) {
|
|
2069
|
+
const inode = this.node;
|
|
2070
|
+
Reflect.ownKeys(options["v:bind"]).forEach((k) => {
|
|
2071
|
+
const value = options["v:bind"][k];
|
|
2072
|
+
if (k === 'value' && (inode instanceof HTMLInputElement || inode instanceof HTMLTextAreaElement)) {
|
|
2073
|
+
inode.oninput = () => value.$ = inode.value;
|
|
2074
|
+
}
|
|
2075
|
+
else if (k === 'checked' && inode instanceof HTMLInputElement) {
|
|
2076
|
+
inode.oninput = () => value.$ = inode.checked;
|
|
2077
|
+
}
|
|
2078
|
+
else if (k === 'volume' && inode instanceof HTMLMediaElement) {
|
|
2079
|
+
inode.onvolumechange = () => value.$ = inode.volume;
|
|
2080
|
+
}
|
|
2081
|
+
this.bindDomApi(k, value);
|
|
2082
|
+
});
|
|
2083
|
+
}
|
|
2084
|
+
options["v:set"] && Object.keys(options["v:set"]).forEach(key => {
|
|
2085
|
+
this.node[key] = options["v:set"][key];
|
|
2086
|
+
});
|
|
1950
2087
|
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2088
|
+
}
|
|
2089
|
+
/**
|
|
2090
|
+
* Represents an Vasille.js HTML element node
|
|
2091
|
+
* @class Tag
|
|
2092
|
+
* @extends INode
|
|
2093
|
+
*/
|
|
2094
|
+
class Tag extends INode {
|
|
2095
|
+
constructor(input) {
|
|
2096
|
+
super(input);
|
|
2097
|
+
this.$seal();
|
|
1957
2098
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2099
|
+
preinit(app, parent, tagName) {
|
|
2100
|
+
if (!tagName || typeof tagName !== "string") {
|
|
2101
|
+
throw internalError('wrong Tag::$preinit call');
|
|
2102
|
+
}
|
|
2103
|
+
const node = document.createElement(tagName);
|
|
2104
|
+
const $ = this.$;
|
|
2105
|
+
$.preinit(app, parent);
|
|
2106
|
+
$.node = node;
|
|
2107
|
+
$.parent.appendNode(node);
|
|
1964
2108
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
* @param options {Object | boolean}
|
|
1968
|
-
*/
|
|
1969
|
-
onmouseover(handler, options) {
|
|
1970
|
-
return this.listen("mouseover", handler, options);
|
|
1971
|
-
}
|
|
1972
|
-
/**
|
|
1973
|
-
* @param handler {function (MouseEvent)}
|
|
1974
|
-
* @param options {Object | boolean}
|
|
1975
|
-
*/
|
|
1976
|
-
onmouseup(handler, options) {
|
|
1977
|
-
return this.listen("mouseup", handler, options);
|
|
1978
|
-
}
|
|
1979
|
-
/**
|
|
1980
|
-
* @param handler {function (MouseEvent)}
|
|
1981
|
-
* @param options {Object | boolean}
|
|
1982
|
-
*/
|
|
1983
|
-
onclick(handler, options) {
|
|
1984
|
-
return this.listen("click", handler, options);
|
|
1985
|
-
}
|
|
1986
|
-
/**
|
|
1987
|
-
* @param handler {function (MouseEvent)}
|
|
1988
|
-
* @param options {Object | boolean}
|
|
1989
|
-
*/
|
|
1990
|
-
ondblclick(handler, options) {
|
|
1991
|
-
return this.listen("dblclick", handler, options);
|
|
1992
|
-
}
|
|
1993
|
-
/**
|
|
1994
|
-
* @param handler {function (FocusEvent)}
|
|
1995
|
-
* @param options {Object | boolean}
|
|
1996
|
-
*/
|
|
1997
|
-
onblur(handler, options) {
|
|
1998
|
-
return this.listen("blur", handler, options);
|
|
1999
|
-
}
|
|
2000
|
-
/**
|
|
2001
|
-
* @param handler {function (FocusEvent)}
|
|
2002
|
-
* @param options {Object | boolean}
|
|
2003
|
-
*/
|
|
2004
|
-
onfocus(handler, options) {
|
|
2005
|
-
return this.listen("focus", handler, options);
|
|
2006
|
-
}
|
|
2007
|
-
/**
|
|
2008
|
-
* @param handler {function (FocusEvent)}
|
|
2009
|
-
* @param options {Object | boolean}
|
|
2010
|
-
*/
|
|
2011
|
-
onfocusin(handler, options) {
|
|
2012
|
-
return this.listen("focusin", handler, options);
|
|
2013
|
-
}
|
|
2014
|
-
/**
|
|
2015
|
-
* @param handler {function (FocusEvent)}
|
|
2016
|
-
* @param options {Object | boolean}
|
|
2017
|
-
*/
|
|
2018
|
-
onfocusout(handler, options) {
|
|
2019
|
-
return this.listen("focusout", handler, options);
|
|
2020
|
-
}
|
|
2021
|
-
/**
|
|
2022
|
-
* @param handler {function (KeyboardEvent)}
|
|
2023
|
-
* @param options {Object | boolean}
|
|
2024
|
-
*/
|
|
2025
|
-
onkeydown(handler, options) {
|
|
2026
|
-
return this.listen("keydown", handler, options);
|
|
2027
|
-
}
|
|
2028
|
-
/**
|
|
2029
|
-
* @param handler {function (KeyboardEvent)}
|
|
2030
|
-
* @param options {Object | boolean}
|
|
2031
|
-
*/
|
|
2032
|
-
onkeyup(handler, options) {
|
|
2033
|
-
return this.listen("keyup", handler, options);
|
|
2034
|
-
}
|
|
2035
|
-
/**
|
|
2036
|
-
* @param handler {function (KeyboardEvent)}
|
|
2037
|
-
* @param options {Object | boolean}
|
|
2038
|
-
*/
|
|
2039
|
-
onkeypress(handler, options) {
|
|
2040
|
-
return this.listen("keypress", handler, options);
|
|
2041
|
-
}
|
|
2042
|
-
/**
|
|
2043
|
-
* @param handler {function (TouchEvent)}
|
|
2044
|
-
* @param options {Object | boolean}
|
|
2045
|
-
*/
|
|
2046
|
-
ontouchstart(handler, options) {
|
|
2047
|
-
return this.listen("touchstart", handler, options);
|
|
2048
|
-
}
|
|
2049
|
-
/**
|
|
2050
|
-
* @param handler {function (TouchEvent)}
|
|
2051
|
-
* @param options {Object | boolean}
|
|
2052
|
-
*/
|
|
2053
|
-
ontouchmove(handler, options) {
|
|
2054
|
-
return this.listen("touchmove", handler, options);
|
|
2055
|
-
}
|
|
2056
|
-
/**
|
|
2057
|
-
* @param handler {function (TouchEvent)}
|
|
2058
|
-
* @param options {Object | boolean}
|
|
2059
|
-
*/
|
|
2060
|
-
ontouchend(handler, options) {
|
|
2061
|
-
return this.listen("touchend", handler, options);
|
|
2062
|
-
}
|
|
2063
|
-
/**
|
|
2064
|
-
* @param handler {function (TouchEvent)}
|
|
2065
|
-
* @param options {Object | boolean}
|
|
2066
|
-
*/
|
|
2067
|
-
ontouchcancel(handler, options) {
|
|
2068
|
-
return this.listen("touchcancel", handler, options);
|
|
2069
|
-
}
|
|
2070
|
-
/**
|
|
2071
|
-
* @param handler {function (WheelEvent)}
|
|
2072
|
-
* @param options {Object | boolean}
|
|
2073
|
-
*/
|
|
2074
|
-
onwheel(handler, options) {
|
|
2075
|
-
return this.listen("wheel", handler, options);
|
|
2076
|
-
}
|
|
2077
|
-
/**
|
|
2078
|
-
* @param handler {function (ProgressEvent)}
|
|
2079
|
-
* @param options {Object | boolean}
|
|
2080
|
-
*/
|
|
2081
|
-
onabort(handler, options) {
|
|
2082
|
-
return this.listen("abort", handler, options);
|
|
2083
|
-
}
|
|
2084
|
-
/**
|
|
2085
|
-
* @param handler {function (ProgressEvent)}
|
|
2086
|
-
* @param options {Object | boolean}
|
|
2087
|
-
*/
|
|
2088
|
-
onerror(handler, options) {
|
|
2089
|
-
return this.listen("error", handler, options);
|
|
2090
|
-
}
|
|
2091
|
-
/**
|
|
2092
|
-
* @param handler {function (ProgressEvent)}
|
|
2093
|
-
* @param options {Object | boolean}
|
|
2094
|
-
*/
|
|
2095
|
-
onload(handler, options) {
|
|
2096
|
-
return this.listen("load", handler, options);
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* @param handler {function (ProgressEvent)}
|
|
2100
|
-
* @param options {Object | boolean}
|
|
2101
|
-
*/
|
|
2102
|
-
onloadend(handler, options) {
|
|
2103
|
-
return this.listen("loadend", handler, options);
|
|
2104
|
-
}
|
|
2105
|
-
/**
|
|
2106
|
-
* @param handler {function (ProgressEvent)}
|
|
2107
|
-
* @param options {Object | boolean}
|
|
2108
|
-
*/
|
|
2109
|
-
onloadstart(handler, options) {
|
|
2110
|
-
return this.listen("loadstart", handler, options);
|
|
2111
|
-
}
|
|
2112
|
-
/**
|
|
2113
|
-
* @param handler {function (ProgressEvent)}
|
|
2114
|
-
* @param options {Object | boolean}
|
|
2115
|
-
*/
|
|
2116
|
-
onprogress(handler, options) {
|
|
2117
|
-
return this.listen("progress", handler, options);
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* @param handler {function (ProgressEvent)}
|
|
2121
|
-
* @param options {Object | boolean}
|
|
2122
|
-
*/
|
|
2123
|
-
ontimeout(handler, options) {
|
|
2124
|
-
return this.listen("timeout", handler, options);
|
|
2125
|
-
}
|
|
2126
|
-
/**
|
|
2127
|
-
* @param handler {function (DragEvent)}
|
|
2128
|
-
* @param options {Object | boolean}
|
|
2129
|
-
*/
|
|
2130
|
-
ondrag(handler, options) {
|
|
2131
|
-
return this.listen("drag", handler, options);
|
|
2132
|
-
}
|
|
2133
|
-
/**
|
|
2134
|
-
* @param handler {function (DragEvent)}
|
|
2135
|
-
* @param options {Object | boolean}
|
|
2136
|
-
*/
|
|
2137
|
-
ondragend(handler, options) {
|
|
2138
|
-
return this.listen("dragend", handler, options);
|
|
2139
|
-
}
|
|
2140
|
-
/**
|
|
2141
|
-
* @param handler {function (DragEvent)}
|
|
2142
|
-
* @param options {Object | boolean}
|
|
2143
|
-
*/
|
|
2144
|
-
ondragenter(handler, options) {
|
|
2145
|
-
return this.listen("dragenter", handler, options);
|
|
2146
|
-
}
|
|
2147
|
-
/**
|
|
2148
|
-
* @param handler {function (DragEvent)}
|
|
2149
|
-
* @param options {Object | boolean}
|
|
2150
|
-
*/
|
|
2151
|
-
ondragexit(handler, options) {
|
|
2152
|
-
return this.listen("dragexit", handler, options);
|
|
2153
|
-
}
|
|
2154
|
-
/**
|
|
2155
|
-
* @param handler {function (DragEvent)}
|
|
2156
|
-
* @param options {Object | boolean}
|
|
2157
|
-
*/
|
|
2158
|
-
ondragleave(handler, options) {
|
|
2159
|
-
return this.listen("dragleave", handler, options);
|
|
2160
|
-
}
|
|
2161
|
-
/**
|
|
2162
|
-
* @param handler {function (DragEvent)}
|
|
2163
|
-
* @param options {Object | boolean}
|
|
2164
|
-
*/
|
|
2165
|
-
ondragover(handler, options) {
|
|
2166
|
-
return this.listen("dragover", handler, options);
|
|
2167
|
-
}
|
|
2168
|
-
/**
|
|
2169
|
-
* @param handler {function (DragEvent)}
|
|
2170
|
-
* @param options {Object | boolean}
|
|
2171
|
-
*/
|
|
2172
|
-
ondragstart(handler, options) {
|
|
2173
|
-
return this.listen("dragstart", handler, options);
|
|
2174
|
-
}
|
|
2175
|
-
/**
|
|
2176
|
-
* @param handler {function (DragEvent)}
|
|
2177
|
-
* @param options {Object | boolean}
|
|
2178
|
-
*/
|
|
2179
|
-
ondrop(handler, options) {
|
|
2180
|
-
return this.listen("drop", handler, options);
|
|
2181
|
-
}
|
|
2182
|
-
/**
|
|
2183
|
-
* @param handler {function (PointerEvent)}
|
|
2184
|
-
* @param options {Object | boolean}
|
|
2185
|
-
*/
|
|
2186
|
-
onpointerover(handler, options) {
|
|
2187
|
-
return this.listen("pointerover", handler, options);
|
|
2188
|
-
}
|
|
2189
|
-
/**
|
|
2190
|
-
* @param handler {function (PointerEvent)}
|
|
2191
|
-
* @param options {Object | boolean}
|
|
2192
|
-
*/
|
|
2193
|
-
onpointerenter(handler, options) {
|
|
2194
|
-
return this.listen("pointerenter", handler, options);
|
|
2195
|
-
}
|
|
2196
|
-
/**
|
|
2197
|
-
* @param handler {function (PointerEvent)}
|
|
2198
|
-
* @param options {Object | boolean}
|
|
2199
|
-
*/
|
|
2200
|
-
onpointerdown(handler, options) {
|
|
2201
|
-
return this.listen("pointerdown", handler, options);
|
|
2202
|
-
}
|
|
2203
|
-
/**
|
|
2204
|
-
* @param handler {function (PointerEvent)}
|
|
2205
|
-
* @param options {Object | boolean}
|
|
2206
|
-
*/
|
|
2207
|
-
onpointermove(handler, options) {
|
|
2208
|
-
return this.listen("pointermove", handler, options);
|
|
2209
|
-
}
|
|
2210
|
-
/**
|
|
2211
|
-
* @param handler {function (PointerEvent)}
|
|
2212
|
-
* @param options {Object | boolean}
|
|
2213
|
-
*/
|
|
2214
|
-
onpointerup(handler, options) {
|
|
2215
|
-
return this.listen("pointerup", handler, options);
|
|
2216
|
-
}
|
|
2217
|
-
/**
|
|
2218
|
-
* @param handler {function (PointerEvent)}
|
|
2219
|
-
* @param options {Object | boolean}
|
|
2220
|
-
*/
|
|
2221
|
-
onpointercancel(handler, options) {
|
|
2222
|
-
return this.listen("pointercancel", handler, options);
|
|
2223
|
-
}
|
|
2224
|
-
/**
|
|
2225
|
-
* @param handler {function (PointerEvent)}
|
|
2226
|
-
* @param options {Object | boolean}
|
|
2227
|
-
*/
|
|
2228
|
-
onpointerout(handler, options) {
|
|
2229
|
-
return this.listen("pointerout", handler, options);
|
|
2230
|
-
}
|
|
2231
|
-
/**
|
|
2232
|
-
* @param handler {function (PointerEvent)}
|
|
2233
|
-
* @param options {Object | boolean}
|
|
2234
|
-
*/
|
|
2235
|
-
onpointerleave(handler, options) {
|
|
2236
|
-
return this.listen("pointerleave", handler, options);
|
|
2237
|
-
}
|
|
2238
|
-
/**
|
|
2239
|
-
* @param handler {function (PointerEvent)}
|
|
2240
|
-
* @param options {Object | boolean}
|
|
2241
|
-
*/
|
|
2242
|
-
ongotpointercapture(handler, options) {
|
|
2243
|
-
return this.listen("gotpointercapture", handler, options);
|
|
2244
|
-
}
|
|
2245
|
-
/**
|
|
2246
|
-
* @param handler {function (PointerEvent)}
|
|
2247
|
-
* @param options {Object | boolean}
|
|
2248
|
-
*/
|
|
2249
|
-
onlostpointercapture(handler, options) {
|
|
2250
|
-
return this.listen("lostpointercapture", handler, options);
|
|
2251
|
-
}
|
|
2252
|
-
/**
|
|
2253
|
-
* @param handler {function (AnimationEvent)}
|
|
2254
|
-
* @param options {Object | boolean}
|
|
2255
|
-
*/
|
|
2256
|
-
onanimationstart(handler, options) {
|
|
2257
|
-
return this.listen("animationstart", handler, options);
|
|
2258
|
-
}
|
|
2259
|
-
/**
|
|
2260
|
-
* @param handler {function (AnimationEvent)}
|
|
2261
|
-
* @param options {Object | boolean}
|
|
2262
|
-
*/
|
|
2263
|
-
onanimationend(handler, options) {
|
|
2264
|
-
return this.listen("animationend", handler, options);
|
|
2265
|
-
}
|
|
2266
|
-
/**
|
|
2267
|
-
* @param handler {function (AnimationEvent)}
|
|
2268
|
-
* @param options {Object | boolean}
|
|
2269
|
-
*/
|
|
2270
|
-
onanimationiteraton(handler, options) {
|
|
2271
|
-
return this.listen("animationiteration", handler, options);
|
|
2272
|
-
}
|
|
2273
|
-
/**
|
|
2274
|
-
* @param handler {function (ClipboardEvent)}
|
|
2275
|
-
* @param options {Object | boolean}
|
|
2276
|
-
*/
|
|
2277
|
-
onclipboardchange(handler, options) {
|
|
2278
|
-
return this.listen("clipboardchange", handler, options);
|
|
2279
|
-
}
|
|
2280
|
-
/**
|
|
2281
|
-
* @param handler {function (ClipboardEvent)}
|
|
2282
|
-
* @param options {Object | boolean}
|
|
2283
|
-
*/
|
|
2284
|
-
oncut(handler, options) {
|
|
2285
|
-
return this.listen("cut", handler, options);
|
|
2286
|
-
}
|
|
2287
|
-
/**
|
|
2288
|
-
* @param handler {function (ClipboardEvent)}
|
|
2289
|
-
* @param options {Object | boolean}
|
|
2290
|
-
*/
|
|
2291
|
-
oncopy(handler, options) {
|
|
2292
|
-
return this.listen("copy", handler, options);
|
|
2293
|
-
}
|
|
2294
|
-
/**
|
|
2295
|
-
* @param handler {function (ClipboardEvent)}
|
|
2296
|
-
* @param options {Object | boolean}
|
|
2297
|
-
*/
|
|
2298
|
-
onpaste(handler, options) {
|
|
2299
|
-
return this.listen("paste", handler, options);
|
|
2300
|
-
}
|
|
2301
|
-
insertAdjacent(node) {
|
|
2302
|
-
const $ = this.$;
|
|
2303
|
-
$.app.run.insertBefore($.node, node);
|
|
2304
|
-
}
|
|
2305
|
-
/**
|
|
2306
|
-
* A v-show & ngShow alternative
|
|
2307
|
-
* @param cond {IValue} show condition
|
|
2308
|
-
*/
|
|
2309
|
-
bindShow(cond) {
|
|
2310
|
-
const $ = this.$;
|
|
2311
|
-
const node = $.node;
|
|
2312
|
-
if (node instanceof HTMLElement) {
|
|
2313
|
-
let lastDisplay = node.style.display;
|
|
2314
|
-
const htmlNode = node;
|
|
2315
|
-
return this.bindAlive(cond, () => {
|
|
2316
|
-
lastDisplay = htmlNode.style.display;
|
|
2317
|
-
htmlNode.style.display = 'none';
|
|
2318
|
-
}, () => {
|
|
2319
|
-
htmlNode.style.display = lastDisplay;
|
|
2320
|
-
});
|
|
2321
|
-
}
|
|
2322
|
-
else {
|
|
2323
|
-
throw userError('the element must be a html element', 'bind-show');
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
/**
|
|
2327
|
-
* bind HTML
|
|
2328
|
-
* @param value {IValue}
|
|
2329
|
-
*/
|
|
2330
|
-
html(value) {
|
|
2331
|
-
const $ = this.$;
|
|
2332
|
-
const node = $.node;
|
|
2333
|
-
if (node instanceof HTMLElement) {
|
|
2334
|
-
node.innerHTML = value.$;
|
|
2335
|
-
this.watch((v) => {
|
|
2336
|
-
node.innerHTML = v;
|
|
2337
|
-
}, value);
|
|
2338
|
-
}
|
|
2339
|
-
else {
|
|
2340
|
-
throw userError("HTML can be bound for HTML nodes only", "dom-error");
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
/**
|
|
2345
|
-
* Represents an Vasille.js HTML element node
|
|
2346
|
-
* @class Tag
|
|
2347
|
-
* @extends INode
|
|
2348
|
-
*/
|
|
2349
|
-
class Tag extends INode {
|
|
2350
|
-
constructor() {
|
|
2351
|
-
super();
|
|
2352
|
-
this.seal();
|
|
2353
|
-
}
|
|
2354
|
-
preinit(app, parent, tagName) {
|
|
2355
|
-
if (!tagName || typeof tagName !== "string") {
|
|
2356
|
-
throw internalError('wrong Tag::$preinit call');
|
|
2357
|
-
}
|
|
2358
|
-
const node = document.createElement(tagName);
|
|
2359
|
-
const $ = this.$;
|
|
2360
|
-
$.preinit(app, parent);
|
|
2361
|
-
$.node = node;
|
|
2362
|
-
$.parent.appendNode(node);
|
|
2109
|
+
compose(input) {
|
|
2110
|
+
input.slot && input.slot(this);
|
|
2363
2111
|
}
|
|
2364
2112
|
findFirstChild() {
|
|
2365
2113
|
return this.$.unmounted ? null : this.$.node;
|
|
@@ -2378,8 +2126,7 @@ class Tag extends INode {
|
|
|
2378
2126
|
}
|
|
2379
2127
|
}
|
|
2380
2128
|
appendNode(node) {
|
|
2381
|
-
|
|
2382
|
-
$.app.run.appendChild($.node, node);
|
|
2129
|
+
this.$.node.appendChild(node);
|
|
2383
2130
|
}
|
|
2384
2131
|
/**
|
|
2385
2132
|
* Mount/Unmount a node
|
|
@@ -2400,9 +2147,9 @@ class Tag extends INode {
|
|
|
2400
2147
|
/**
|
|
2401
2148
|
* Runs GC
|
|
2402
2149
|
*/
|
|
2403
|
-
destroy() {
|
|
2150
|
+
$destroy() {
|
|
2404
2151
|
this.node.remove();
|
|
2405
|
-
super
|
|
2152
|
+
super.$destroy();
|
|
2406
2153
|
}
|
|
2407
2154
|
}
|
|
2408
2155
|
/**
|
|
@@ -2412,21 +2159,21 @@ class Tag extends INode {
|
|
|
2412
2159
|
*/
|
|
2413
2160
|
class Extension extends INode {
|
|
2414
2161
|
preinit(app, parent) {
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2162
|
+
const $ = this.$;
|
|
2163
|
+
let it = parent;
|
|
2164
|
+
while (it && !(it instanceof INode)) {
|
|
2165
|
+
it = it.parent;
|
|
2419
2166
|
}
|
|
2420
|
-
|
|
2167
|
+
if (it && it instanceof INode) {
|
|
2168
|
+
$.node = it.node;
|
|
2169
|
+
}
|
|
2170
|
+
$.preinit(app, parent);
|
|
2171
|
+
if (!it) {
|
|
2421
2172
|
throw userError("A extension node can be encapsulated only in a tag/extension/component", "virtual-dom");
|
|
2422
2173
|
}
|
|
2423
2174
|
}
|
|
2424
|
-
|
|
2425
|
-
super(
|
|
2426
|
-
this.seal();
|
|
2427
|
-
}
|
|
2428
|
-
destroy() {
|
|
2429
|
-
super.destroy();
|
|
2175
|
+
$destroy() {
|
|
2176
|
+
super.$destroy();
|
|
2430
2177
|
}
|
|
2431
2178
|
}
|
|
2432
2179
|
/**
|
|
@@ -2435,12 +2182,13 @@ class Extension extends INode {
|
|
|
2435
2182
|
* @extends Extension
|
|
2436
2183
|
*/
|
|
2437
2184
|
class Component extends Extension {
|
|
2438
|
-
|
|
2439
|
-
super();
|
|
2440
|
-
this.
|
|
2185
|
+
init() {
|
|
2186
|
+
super.composeNow();
|
|
2187
|
+
this.ready();
|
|
2188
|
+
super.applyOptionsNow();
|
|
2441
2189
|
}
|
|
2442
|
-
|
|
2443
|
-
super.
|
|
2190
|
+
ready() {
|
|
2191
|
+
super.ready();
|
|
2444
2192
|
if (this.children.size !== 1) {
|
|
2445
2193
|
throw userError("Component must have a child only", "dom-error");
|
|
2446
2194
|
}
|
|
@@ -2465,18 +2213,23 @@ class Component extends Extension {
|
|
|
2465
2213
|
class SwitchedNodePrivate extends FragmentPrivate {
|
|
2466
2214
|
constructor() {
|
|
2467
2215
|
super();
|
|
2468
|
-
|
|
2216
|
+
/**
|
|
2217
|
+
* Array of possible cases
|
|
2218
|
+
* @type {Array<{cond : IValue<boolean>, cb : function(Fragment)}>}
|
|
2219
|
+
*/
|
|
2220
|
+
this.cases = [];
|
|
2221
|
+
this.$seal();
|
|
2469
2222
|
}
|
|
2470
2223
|
/**
|
|
2471
2224
|
* Runs GC
|
|
2472
2225
|
*/
|
|
2473
|
-
destroy() {
|
|
2226
|
+
$destroy() {
|
|
2474
2227
|
this.cases.forEach(c => {
|
|
2475
2228
|
delete c.cond;
|
|
2476
2229
|
delete c.cb;
|
|
2477
2230
|
});
|
|
2478
2231
|
this.cases.splice(0);
|
|
2479
|
-
super
|
|
2232
|
+
super.$destroy();
|
|
2480
2233
|
}
|
|
2481
2234
|
}
|
|
2482
2235
|
/**
|
|
@@ -2487,7 +2240,7 @@ class SwitchedNode extends Fragment {
|
|
|
2487
2240
|
* Constructs a switch node and define a sync function
|
|
2488
2241
|
*/
|
|
2489
2242
|
constructor() {
|
|
2490
|
-
super(new SwitchedNodePrivate);
|
|
2243
|
+
super({}, new SwitchedNodePrivate);
|
|
2491
2244
|
this.$.sync = () => {
|
|
2492
2245
|
const $ = this.$;
|
|
2493
2246
|
let i = 0;
|
|
@@ -2500,7 +2253,7 @@ class SwitchedNode extends Fragment {
|
|
|
2500
2253
|
return;
|
|
2501
2254
|
}
|
|
2502
2255
|
if (this.lastChild) {
|
|
2503
|
-
this.lastChild
|
|
2256
|
+
this.lastChild.$destroy();
|
|
2504
2257
|
this.children.clear();
|
|
2505
2258
|
this.lastChild = null;
|
|
2506
2259
|
}
|
|
@@ -2512,22 +2265,19 @@ class SwitchedNode extends Fragment {
|
|
|
2512
2265
|
$.index = -1;
|
|
2513
2266
|
}
|
|
2514
2267
|
};
|
|
2515
|
-
this
|
|
2268
|
+
this.$seal();
|
|
2516
2269
|
}
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
setCases(cases) {
|
|
2522
|
-
const $ = this.$;
|
|
2523
|
-
$.cases = [...cases];
|
|
2270
|
+
addCase(case_) {
|
|
2271
|
+
this.$.cases.push(case_);
|
|
2272
|
+
case_.cond.$on(this.$.sync);
|
|
2273
|
+
this.$.sync();
|
|
2524
2274
|
}
|
|
2525
2275
|
/**
|
|
2526
2276
|
* Creates a child node
|
|
2527
2277
|
* @param cb {function(Fragment)} Call-back
|
|
2528
2278
|
*/
|
|
2529
2279
|
createChild(cb) {
|
|
2530
|
-
const node = new Fragment();
|
|
2280
|
+
const node = new Fragment({});
|
|
2531
2281
|
node.preinit(this.$.app, this);
|
|
2532
2282
|
node.init();
|
|
2533
2283
|
this.lastChild = node;
|
|
@@ -2537,16 +2287,16 @@ class SwitchedNode extends Fragment {
|
|
|
2537
2287
|
ready() {
|
|
2538
2288
|
const $ = this.$;
|
|
2539
2289
|
$.cases.forEach(c => {
|
|
2540
|
-
c.cond
|
|
2290
|
+
c.cond.$on($.sync);
|
|
2541
2291
|
});
|
|
2542
2292
|
$.sync();
|
|
2543
2293
|
}
|
|
2544
|
-
destroy() {
|
|
2294
|
+
$destroy() {
|
|
2545
2295
|
const $ = this.$;
|
|
2546
2296
|
$.cases.forEach(c => {
|
|
2547
|
-
c.cond
|
|
2297
|
+
c.cond.$off($.sync);
|
|
2548
2298
|
});
|
|
2549
|
-
super
|
|
2299
|
+
super.$destroy();
|
|
2550
2300
|
}
|
|
2551
2301
|
}
|
|
2552
2302
|
/**
|
|
@@ -2555,7 +2305,7 @@ class SwitchedNode extends Fragment {
|
|
|
2555
2305
|
class DebugPrivate extends FragmentPrivate {
|
|
2556
2306
|
constructor() {
|
|
2557
2307
|
super();
|
|
2558
|
-
this
|
|
2308
|
+
this.$seal();
|
|
2559
2309
|
}
|
|
2560
2310
|
/**
|
|
2561
2311
|
* Pre-initializes a text node
|
|
@@ -2574,9 +2324,9 @@ class DebugPrivate extends FragmentPrivate {
|
|
|
2574
2324
|
/**
|
|
2575
2325
|
* Clear node data
|
|
2576
2326
|
*/
|
|
2577
|
-
destroy() {
|
|
2327
|
+
$destroy() {
|
|
2578
2328
|
this.node.remove();
|
|
2579
|
-
super
|
|
2329
|
+
super.$destroy();
|
|
2580
2330
|
}
|
|
2581
2331
|
}
|
|
2582
2332
|
/**
|
|
@@ -2586,13 +2336,13 @@ class DebugPrivate extends FragmentPrivate {
|
|
|
2586
2336
|
*/
|
|
2587
2337
|
class DebugNode extends Fragment {
|
|
2588
2338
|
constructor() {
|
|
2589
|
-
super();
|
|
2339
|
+
super({});
|
|
2590
2340
|
/**
|
|
2591
2341
|
* private data
|
|
2592
2342
|
* @type {DebugNode}
|
|
2593
2343
|
*/
|
|
2594
2344
|
this.$ = new DebugPrivate();
|
|
2595
|
-
this
|
|
2345
|
+
this.$seal();
|
|
2596
2346
|
}
|
|
2597
2347
|
preinit(app, parent, text) {
|
|
2598
2348
|
const $ = this.$;
|
|
@@ -2604,9 +2354,9 @@ class DebugNode extends Fragment {
|
|
|
2604
2354
|
/**
|
|
2605
2355
|
* Runs garbage collector
|
|
2606
2356
|
*/
|
|
2607
|
-
destroy() {
|
|
2608
|
-
this
|
|
2609
|
-
super
|
|
2357
|
+
$destroy() {
|
|
2358
|
+
this.$.$destroy();
|
|
2359
|
+
super.$destroy();
|
|
2610
2360
|
}
|
|
2611
2361
|
}
|
|
2612
2362
|
|
|
@@ -2620,6 +2370,7 @@ window.Tag = Tag;
|
|
|
2620
2370
|
window.Extension = Extension;
|
|
2621
2371
|
window.Component = Component;
|
|
2622
2372
|
window.SwitchedNodePrivate = SwitchedNodePrivate;
|
|
2373
|
+
window.SwitchedNode = SwitchedNode;
|
|
2623
2374
|
window.DebugPrivate = DebugPrivate;
|
|
2624
2375
|
window.DebugNode = DebugNode;
|
|
2625
2376
|
|
|
@@ -2631,12 +2382,12 @@ window.DebugNode = DebugNode;
|
|
|
2631
2382
|
*/
|
|
2632
2383
|
class AppNode extends INode {
|
|
2633
2384
|
/**
|
|
2634
|
-
* @param
|
|
2385
|
+
* @param input
|
|
2635
2386
|
*/
|
|
2636
|
-
constructor(
|
|
2637
|
-
super();
|
|
2638
|
-
this.
|
|
2639
|
-
this
|
|
2387
|
+
constructor(input) {
|
|
2388
|
+
super(input);
|
|
2389
|
+
this.debugUi = input.debugUi || false;
|
|
2390
|
+
this.$seal();
|
|
2640
2391
|
}
|
|
2641
2392
|
}
|
|
2642
2393
|
/**
|
|
@@ -2648,22 +2399,33 @@ class App extends AppNode {
|
|
|
2648
2399
|
/**
|
|
2649
2400
|
* Constructs an app node
|
|
2650
2401
|
* @param node {Element} The root of application
|
|
2651
|
-
* @param
|
|
2402
|
+
* @param input
|
|
2652
2403
|
*/
|
|
2653
|
-
constructor(node,
|
|
2654
|
-
super(
|
|
2404
|
+
constructor(node, input) {
|
|
2405
|
+
super(input);
|
|
2655
2406
|
this.$.node = node;
|
|
2656
2407
|
this.preinit(this, this);
|
|
2657
|
-
this.
|
|
2408
|
+
this.init();
|
|
2409
|
+
this.$seal();
|
|
2658
2410
|
}
|
|
2659
2411
|
appendNode(node) {
|
|
2660
|
-
|
|
2661
|
-
|
|
2412
|
+
this.$.node.appendChild(node);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
class Portal extends AppNode {
|
|
2416
|
+
constructor(input) {
|
|
2417
|
+
super(input);
|
|
2418
|
+
this.$.node = input.node;
|
|
2419
|
+
this.$seal();
|
|
2420
|
+
}
|
|
2421
|
+
appendNode(node) {
|
|
2422
|
+
this.$.node.appendChild(node);
|
|
2662
2423
|
}
|
|
2663
2424
|
}
|
|
2664
2425
|
|
|
2665
2426
|
window.AppNode = AppNode;
|
|
2666
2427
|
window.App = App;
|
|
2428
|
+
window.Portal = Portal;
|
|
2667
2429
|
|
|
2668
2430
|
// ./lib/node/interceptor.js
|
|
2669
2431
|
/**
|
|
@@ -2766,13 +2528,18 @@ class AttributeBinding extends Binding {
|
|
|
2766
2528
|
super(value);
|
|
2767
2529
|
this.init((value) => {
|
|
2768
2530
|
if (value) {
|
|
2769
|
-
|
|
2531
|
+
if (typeof value === 'boolean') {
|
|
2532
|
+
node.node.setAttribute(name, "");
|
|
2533
|
+
}
|
|
2534
|
+
else {
|
|
2535
|
+
node.node.setAttribute(name, `${value}`);
|
|
2536
|
+
}
|
|
2770
2537
|
}
|
|
2771
2538
|
else {
|
|
2772
|
-
node.
|
|
2539
|
+
node.node.removeAttribute(name);
|
|
2773
2540
|
}
|
|
2774
2541
|
});
|
|
2775
|
-
this
|
|
2542
|
+
this.$seal();
|
|
2776
2543
|
}
|
|
2777
2544
|
}
|
|
2778
2545
|
|
|
@@ -2795,10 +2562,10 @@ class StyleBinding extends Binding {
|
|
|
2795
2562
|
super(value);
|
|
2796
2563
|
this.init((value) => {
|
|
2797
2564
|
if (node.node instanceof HTMLElement) {
|
|
2798
|
-
node.
|
|
2565
|
+
node.node.style.setProperty(name, value);
|
|
2799
2566
|
}
|
|
2800
2567
|
});
|
|
2801
|
-
this
|
|
2568
|
+
this.$seal();
|
|
2802
2569
|
}
|
|
2803
2570
|
}
|
|
2804
2571
|
|
|
@@ -2806,10 +2573,10 @@ window.StyleBinding = StyleBinding;
|
|
|
2806
2573
|
|
|
2807
2574
|
// ./lib/binding/class.js
|
|
2808
2575
|
function addClass(node, cl) {
|
|
2809
|
-
node.
|
|
2576
|
+
node.node.classList.add(cl);
|
|
2810
2577
|
}
|
|
2811
2578
|
function removeClass(node, cl) {
|
|
2812
|
-
node.
|
|
2579
|
+
node.node.classList.remove(cl);
|
|
2813
2580
|
}
|
|
2814
2581
|
class StaticClassBinding extends Binding {
|
|
2815
2582
|
constructor(node, name, value) {
|
|
@@ -2826,7 +2593,7 @@ class StaticClassBinding extends Binding {
|
|
|
2826
2593
|
this.current = value;
|
|
2827
2594
|
}
|
|
2828
2595
|
});
|
|
2829
|
-
this
|
|
2596
|
+
this.$seal();
|
|
2830
2597
|
}
|
|
2831
2598
|
}
|
|
2832
2599
|
class DynamicalClassBinding extends Binding {
|
|
@@ -2844,7 +2611,7 @@ class DynamicalClassBinding extends Binding {
|
|
|
2844
2611
|
this.current = value;
|
|
2845
2612
|
}
|
|
2846
2613
|
});
|
|
2847
|
-
this
|
|
2614
|
+
this.$seal();
|
|
2848
2615
|
}
|
|
2849
2616
|
}
|
|
2850
2617
|
|
|
@@ -2865,11 +2632,11 @@ class RepeatNodePrivate extends INodePrivate {
|
|
|
2865
2632
|
* @type {Map}
|
|
2866
2633
|
*/
|
|
2867
2634
|
this.nodes = new Map();
|
|
2868
|
-
this
|
|
2635
|
+
this.$seal();
|
|
2869
2636
|
}
|
|
2870
|
-
destroy() {
|
|
2637
|
+
$destroy() {
|
|
2871
2638
|
this.nodes.clear();
|
|
2872
|
-
super
|
|
2639
|
+
super.$destroy();
|
|
2873
2640
|
}
|
|
2874
2641
|
}
|
|
2875
2642
|
/**
|
|
@@ -2878,17 +2645,15 @@ class RepeatNodePrivate extends INodePrivate {
|
|
|
2878
2645
|
* @extends Fragment
|
|
2879
2646
|
*/
|
|
2880
2647
|
class RepeatNode extends Fragment {
|
|
2881
|
-
constructor($) {
|
|
2882
|
-
super($
|
|
2648
|
+
constructor(input, $) {
|
|
2649
|
+
super(input, $);
|
|
2883
2650
|
/**
|
|
2884
2651
|
* If false will use timeout executor, otherwise the app executor
|
|
2885
2652
|
*/
|
|
2886
2653
|
this.freezeUi = true;
|
|
2887
|
-
this.slot = new Slot;
|
|
2888
2654
|
}
|
|
2889
|
-
createChild(id, item, before) {
|
|
2890
|
-
|
|
2891
|
-
const node = new Fragment();
|
|
2655
|
+
createChild(opts, id, item, before) {
|
|
2656
|
+
const node = new Fragment({});
|
|
2892
2657
|
this.destroyChild(id, item);
|
|
2893
2658
|
if (before) {
|
|
2894
2659
|
this.children.add(node);
|
|
@@ -2904,16 +2669,8 @@ class RepeatNode extends Fragment {
|
|
|
2904
2669
|
this.lastChild = node;
|
|
2905
2670
|
node.preinit(this.$.app, this);
|
|
2906
2671
|
node.init();
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
node.ready();
|
|
2910
|
-
};
|
|
2911
|
-
if (this.freezeUi) {
|
|
2912
|
-
this.$.app.run.callCallback(callback);
|
|
2913
|
-
}
|
|
2914
|
-
else {
|
|
2915
|
-
timeoutExecutor.callCallback(callback);
|
|
2916
|
-
}
|
|
2672
|
+
opts.slot && opts.slot(node, item, id);
|
|
2673
|
+
node.ready();
|
|
2917
2674
|
this.$.nodes.set(id, node);
|
|
2918
2675
|
}
|
|
2919
2676
|
destroyChild(id, item) {
|
|
@@ -2921,7 +2678,7 @@ class RepeatNode extends Fragment {
|
|
|
2921
2678
|
const child = $.nodes.get(id);
|
|
2922
2679
|
if (child) {
|
|
2923
2680
|
child.remove();
|
|
2924
|
-
child
|
|
2681
|
+
child.$destroy();
|
|
2925
2682
|
this.$.nodes.delete(id);
|
|
2926
2683
|
this.children.delete(child);
|
|
2927
2684
|
}
|
|
@@ -3006,7 +2763,7 @@ window.Repeater = Repeater;
|
|
|
3006
2763
|
class BaseViewPrivate extends RepeatNodePrivate {
|
|
3007
2764
|
constructor() {
|
|
3008
2765
|
super();
|
|
3009
|
-
this
|
|
2766
|
+
this.$seal();
|
|
3010
2767
|
}
|
|
3011
2768
|
}
|
|
3012
2769
|
/**
|
|
@@ -3016,34 +2773,23 @@ class BaseViewPrivate extends RepeatNodePrivate {
|
|
|
3016
2773
|
* @implements IModel
|
|
3017
2774
|
*/
|
|
3018
2775
|
class BaseView extends RepeatNode {
|
|
3019
|
-
constructor($
|
|
3020
|
-
super($
|
|
2776
|
+
constructor(input, $) {
|
|
2777
|
+
super(input, $ || new BaseViewPrivate);
|
|
2778
|
+
}
|
|
2779
|
+
compose(input) {
|
|
3021
2780
|
const $ = this.$;
|
|
3022
2781
|
$.addHandler = (id, item) => {
|
|
3023
|
-
this.createChild(id, item);
|
|
2782
|
+
this.createChild(input, id, item);
|
|
3024
2783
|
};
|
|
3025
2784
|
$.removeHandler = (id, item) => {
|
|
3026
2785
|
this.destroyChild(id, item);
|
|
3027
2786
|
};
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
const $ = this.$;
|
|
3035
|
-
this.model.listener.onAdd($.addHandler);
|
|
3036
|
-
this.model.listener.onRemove($.removeHandler);
|
|
3037
|
-
super.ready();
|
|
3038
|
-
}
|
|
3039
|
-
/**
|
|
3040
|
-
* Handles destroy event
|
|
3041
|
-
*/
|
|
3042
|
-
destroy() {
|
|
3043
|
-
const $ = this.$;
|
|
3044
|
-
this.model.listener.offAdd($.addHandler);
|
|
3045
|
-
this.model.listener.offRemove($.removeHandler);
|
|
3046
|
-
super.destroy();
|
|
2787
|
+
input.model.listener.onAdd($.addHandler);
|
|
2788
|
+
input.model.listener.onRemove($.removeHandler);
|
|
2789
|
+
this.runOnDestroy(() => {
|
|
2790
|
+
input.model.listener.offAdd($.addHandler);
|
|
2791
|
+
input.model.listener.offRemove($.removeHandler);
|
|
2792
|
+
});
|
|
3047
2793
|
}
|
|
3048
2794
|
}
|
|
3049
2795
|
|
|
@@ -3057,18 +2803,14 @@ window.BaseView = BaseView;
|
|
|
3057
2803
|
* @extends BaseView
|
|
3058
2804
|
*/
|
|
3059
2805
|
class ArrayView extends BaseView {
|
|
3060
|
-
|
|
3061
|
-
super();
|
|
3062
|
-
this.model = model;
|
|
2806
|
+
createChild(input, id, item, before) {
|
|
2807
|
+
super.createChild(input, item, item, before || this.$.nodes.get(id));
|
|
3063
2808
|
}
|
|
3064
|
-
|
|
3065
|
-
super.
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
this.model.forEach(item => {
|
|
3069
|
-
this.createChild(item, item);
|
|
2809
|
+
compose(input) {
|
|
2810
|
+
super.compose(input);
|
|
2811
|
+
input.model.forEach(item => {
|
|
2812
|
+
this.createChild(input, item, item);
|
|
3070
2813
|
});
|
|
3071
|
-
super.ready();
|
|
3072
2814
|
}
|
|
3073
2815
|
}
|
|
3074
2816
|
|
|
@@ -3081,23 +2823,16 @@ window.ArrayView = ArrayView;
|
|
|
3081
2823
|
* @extends Fragment
|
|
3082
2824
|
*/
|
|
3083
2825
|
class Watch extends Fragment {
|
|
3084
|
-
|
|
3085
|
-
super();
|
|
3086
|
-
this.slot = new Slot;
|
|
3087
|
-
this.model = this.ref(null);
|
|
3088
|
-
this.seal();
|
|
3089
|
-
}
|
|
3090
|
-
createWatchers() {
|
|
2826
|
+
compose(input) {
|
|
3091
2827
|
this.watch((value) => {
|
|
3092
2828
|
this.children.forEach(child => {
|
|
3093
|
-
child
|
|
2829
|
+
child.$destroy();
|
|
3094
2830
|
});
|
|
3095
2831
|
this.children.clear();
|
|
3096
|
-
this.
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
this.slot.release(this, this.model.$);
|
|
2832
|
+
this.lastChild = null;
|
|
2833
|
+
input.slot && input.slot(this, value);
|
|
2834
|
+
}, input.model);
|
|
2835
|
+
input.slot(this, input.model.$);
|
|
3101
2836
|
}
|
|
3102
2837
|
}
|
|
3103
2838
|
|
|
@@ -3110,14 +2845,11 @@ window.Watch = Watch;
|
|
|
3110
2845
|
* @extends BaseView
|
|
3111
2846
|
*/
|
|
3112
2847
|
class ObjectView extends BaseView {
|
|
3113
|
-
|
|
3114
|
-
super();
|
|
3115
|
-
|
|
3116
|
-
}
|
|
3117
|
-
ready() {
|
|
3118
|
-
const obj = this.model;
|
|
2848
|
+
compose(input) {
|
|
2849
|
+
super.compose(input);
|
|
2850
|
+
const obj = input.model.proxy();
|
|
3119
2851
|
for (const key in obj) {
|
|
3120
|
-
this.createChild(key, obj[key]);
|
|
2852
|
+
this.createChild(input, key, obj[key]);
|
|
3121
2853
|
}
|
|
3122
2854
|
super.ready();
|
|
3123
2855
|
}
|
|
@@ -3132,16 +2864,11 @@ window.ObjectView = ObjectView;
|
|
|
3132
2864
|
* @extends BaseView
|
|
3133
2865
|
*/
|
|
3134
2866
|
class MapView extends BaseView {
|
|
3135
|
-
|
|
3136
|
-
super();
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
ready() {
|
|
3140
|
-
const map = this.model;
|
|
3141
|
-
map.forEach((value, key) => {
|
|
3142
|
-
this.createChild(key, value);
|
|
2867
|
+
compose(input) {
|
|
2868
|
+
super.compose(input);
|
|
2869
|
+
input.model.forEach((value, key) => {
|
|
2870
|
+
this.createChild(input, key, value);
|
|
3143
2871
|
});
|
|
3144
|
-
super.ready();
|
|
3145
2872
|
}
|
|
3146
2873
|
}
|
|
3147
2874
|
|
|
@@ -3154,22 +2881,295 @@ window.MapView = MapView;
|
|
|
3154
2881
|
* @extends BaseView
|
|
3155
2882
|
*/
|
|
3156
2883
|
class SetView extends BaseView {
|
|
3157
|
-
|
|
3158
|
-
super();
|
|
3159
|
-
|
|
3160
|
-
}
|
|
3161
|
-
ready() {
|
|
3162
|
-
const $ = this.$;
|
|
3163
|
-
const set = this.model;
|
|
2884
|
+
compose(input) {
|
|
2885
|
+
super.compose(input);
|
|
2886
|
+
const set = input.model;
|
|
3164
2887
|
set.forEach(item => {
|
|
3165
|
-
|
|
3166
|
-
this.createChild(item, item);
|
|
3167
|
-
});
|
|
2888
|
+
this.createChild(input, item, item);
|
|
3168
2889
|
});
|
|
3169
|
-
super.ready();
|
|
3170
2890
|
}
|
|
3171
2891
|
}
|
|
3172
2892
|
|
|
3173
2893
|
window.SetView = SetView;
|
|
3174
2894
|
|
|
2895
|
+
// ./lib/functional/merge.js
|
|
2896
|
+
function merge(main, ...targets) {
|
|
2897
|
+
function refactorClass(obj) {
|
|
2898
|
+
if (Array.isArray(obj.class)) {
|
|
2899
|
+
const out = {
|
|
2900
|
+
$: []
|
|
2901
|
+
};
|
|
2902
|
+
obj.class.forEach(item => {
|
|
2903
|
+
if (item instanceof IValue) {
|
|
2904
|
+
out.$.push(item);
|
|
2905
|
+
}
|
|
2906
|
+
else if (typeof item === 'string') {
|
|
2907
|
+
out[item] = true;
|
|
2908
|
+
}
|
|
2909
|
+
else if (typeof item === 'object') {
|
|
2910
|
+
Object.assign(out, item);
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
obj.class = out;
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
refactorClass(main);
|
|
2917
|
+
targets.forEach(target => {
|
|
2918
|
+
Reflect.ownKeys(target).forEach((prop) => {
|
|
2919
|
+
if (!Reflect.has(main, prop)) {
|
|
2920
|
+
main[prop] = target[prop];
|
|
2921
|
+
}
|
|
2922
|
+
else if (typeof main[prop] === 'object' && typeof target[prop] === 'object') {
|
|
2923
|
+
if (prop === 'class') {
|
|
2924
|
+
refactorClass(target);
|
|
2925
|
+
}
|
|
2926
|
+
if (prop === '$' && Array.isArray(main[prop]) && Array.isArray(target[prop])) {
|
|
2927
|
+
main.$.push(...target.$);
|
|
2928
|
+
}
|
|
2929
|
+
else {
|
|
2930
|
+
merge(main[prop], target[prop]);
|
|
2931
|
+
}
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
window.merge = merge;
|
|
2938
|
+
|
|
2939
|
+
// ./lib/functional/stack.js
|
|
2940
|
+
function app(renderer) {
|
|
2941
|
+
return (node, opts) => {
|
|
2942
|
+
return new App(node, opts).runFunctional(renderer, opts);
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
function component(renderer) {
|
|
2946
|
+
return (opts, callback) => {
|
|
2947
|
+
const component = new Component(opts);
|
|
2948
|
+
if (!(current instanceof Fragment))
|
|
2949
|
+
throw userError('missing parent node', 'out-of-context');
|
|
2950
|
+
let ret;
|
|
2951
|
+
if (callback)
|
|
2952
|
+
opts.slot = callback;
|
|
2953
|
+
current.create(component, node => {
|
|
2954
|
+
ret = node.runFunctional(renderer, opts);
|
|
2955
|
+
});
|
|
2956
|
+
return ret;
|
|
2957
|
+
};
|
|
2958
|
+
}
|
|
2959
|
+
function fragment(renderer) {
|
|
2960
|
+
return (opts, callback) => {
|
|
2961
|
+
const frag = new Fragment(opts);
|
|
2962
|
+
if (!(current instanceof Fragment))
|
|
2963
|
+
throw userError('missing parent node', 'out-of-context');
|
|
2964
|
+
if (callback)
|
|
2965
|
+
opts.slot = callback;
|
|
2966
|
+
current.create(frag);
|
|
2967
|
+
return frag.runFunctional(renderer, opts);
|
|
2968
|
+
};
|
|
2969
|
+
}
|
|
2970
|
+
function extension(renderer) {
|
|
2971
|
+
return (opts, callback) => {
|
|
2972
|
+
const ext = new Extension(opts);
|
|
2973
|
+
if (!(current instanceof Fragment))
|
|
2974
|
+
throw userError('missing parent node', 'out-of-context');
|
|
2975
|
+
if (callback)
|
|
2976
|
+
opts.slot = callback;
|
|
2977
|
+
current.create(ext);
|
|
2978
|
+
return ext.runFunctional(renderer, opts);
|
|
2979
|
+
};
|
|
2980
|
+
}
|
|
2981
|
+
function tag(name, opts, callback) {
|
|
2982
|
+
if (!(current instanceof Fragment))
|
|
2983
|
+
throw userError('missing parent node', 'out-of-context');
|
|
2984
|
+
return {
|
|
2985
|
+
node: current.tag(name, opts, (node) => {
|
|
2986
|
+
callback && node.runFunctional(callback);
|
|
2987
|
+
})
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
function create(node, callback) {
|
|
2991
|
+
if (!(current instanceof Fragment))
|
|
2992
|
+
throw userError('missing current node', 'out-of-context');
|
|
2993
|
+
current.create(node, (node, ...args) => {
|
|
2994
|
+
callback && node.runFunctional(callback, ...args);
|
|
2995
|
+
});
|
|
2996
|
+
return node;
|
|
2997
|
+
}
|
|
2998
|
+
const vx = {
|
|
2999
|
+
if(condition, callback) {
|
|
3000
|
+
if (current instanceof Fragment) {
|
|
3001
|
+
current.if(condition, node => node.runFunctional(callback));
|
|
3002
|
+
}
|
|
3003
|
+
else {
|
|
3004
|
+
throw userError("wrong use of `v.if` function", "logic-error");
|
|
3005
|
+
}
|
|
3006
|
+
},
|
|
3007
|
+
else(callback) {
|
|
3008
|
+
if (current instanceof Fragment) {
|
|
3009
|
+
current.else(node => node.runFunctional(callback));
|
|
3010
|
+
}
|
|
3011
|
+
else {
|
|
3012
|
+
throw userError("wrong use of `v.else` function", "logic-error");
|
|
3013
|
+
}
|
|
3014
|
+
},
|
|
3015
|
+
elif(condition, callback) {
|
|
3016
|
+
if (current instanceof Fragment) {
|
|
3017
|
+
current.elif(condition, node => node.runFunctional(callback));
|
|
3018
|
+
}
|
|
3019
|
+
else {
|
|
3020
|
+
throw userError("wrong use of `v.elif` function", "logic-error");
|
|
3021
|
+
}
|
|
3022
|
+
},
|
|
3023
|
+
for(model, callback) {
|
|
3024
|
+
if (model instanceof ArrayModel) {
|
|
3025
|
+
// for arrays T & K are the same type
|
|
3026
|
+
create(new ArrayView({ model }), callback);
|
|
3027
|
+
}
|
|
3028
|
+
else if (model instanceof MapModel) {
|
|
3029
|
+
create(new MapView({ model }), callback);
|
|
3030
|
+
}
|
|
3031
|
+
else if (model instanceof SetModel) {
|
|
3032
|
+
// for sets T & K are the same type
|
|
3033
|
+
create(new SetView({ model }), callback);
|
|
3034
|
+
}
|
|
3035
|
+
else if (model instanceof ObjectModel) {
|
|
3036
|
+
// for objects K is always string
|
|
3037
|
+
create(new ObjectView({ model }), callback);
|
|
3038
|
+
}
|
|
3039
|
+
else {
|
|
3040
|
+
throw userError("wrong use of `v.for` function", 'wrong-model');
|
|
3041
|
+
}
|
|
3042
|
+
},
|
|
3043
|
+
watch(model, callback) {
|
|
3044
|
+
const opts = { model };
|
|
3045
|
+
create(new Watch(opts), callback);
|
|
3046
|
+
},
|
|
3047
|
+
nextTick(callback) {
|
|
3048
|
+
const node = current;
|
|
3049
|
+
window.setTimeout(() => {
|
|
3050
|
+
node.runFunctional(callback);
|
|
3051
|
+
}, 0);
|
|
3052
|
+
}
|
|
3053
|
+
};
|
|
3054
|
+
|
|
3055
|
+
window.app = app;
|
|
3056
|
+
window.component = component;
|
|
3057
|
+
window.fragment = fragment;
|
|
3058
|
+
window.extension = extension;
|
|
3059
|
+
window.tag = tag;
|
|
3060
|
+
window.create = create;
|
|
3061
|
+
window.vx = vx;
|
|
3062
|
+
|
|
3063
|
+
// ./lib/functional/models.js
|
|
3064
|
+
function arrayModel(arr = []) {
|
|
3065
|
+
if (!current)
|
|
3066
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3067
|
+
return current.register(new ArrayModel(arr)).proxy();
|
|
3068
|
+
}
|
|
3069
|
+
function mapModel(map = []) {
|
|
3070
|
+
if (!current)
|
|
3071
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3072
|
+
return current.register(new MapModel(map));
|
|
3073
|
+
}
|
|
3074
|
+
function setModel(arr = []) {
|
|
3075
|
+
if (!current)
|
|
3076
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3077
|
+
return current.register(new SetModel(arr));
|
|
3078
|
+
}
|
|
3079
|
+
function objectModel(obj = {}) {
|
|
3080
|
+
if (!current)
|
|
3081
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3082
|
+
return current.register(new ObjectModel(obj));
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
window.arrayModel = arrayModel;
|
|
3086
|
+
window.mapModel = mapModel;
|
|
3087
|
+
window.setModel = setModel;
|
|
3088
|
+
window.objectModel = objectModel;
|
|
3089
|
+
|
|
3090
|
+
// ./lib/functional/options.js
|
|
3091
|
+
|
|
3092
|
+
|
|
3093
|
+
|
|
3094
|
+
// ./lib/functional/reactivity.js
|
|
3095
|
+
function ref(value) {
|
|
3096
|
+
const ref = current.ref(value);
|
|
3097
|
+
return [ref, (value) => ref.$ = value];
|
|
3098
|
+
}
|
|
3099
|
+
function mirror(value) {
|
|
3100
|
+
return current.mirror(value);
|
|
3101
|
+
}
|
|
3102
|
+
function forward(value) {
|
|
3103
|
+
return current.forward(value);
|
|
3104
|
+
}
|
|
3105
|
+
function point(value) {
|
|
3106
|
+
return current.point(value);
|
|
3107
|
+
}
|
|
3108
|
+
function expr(func, ...values) {
|
|
3109
|
+
return current.expr(func, ...values);
|
|
3110
|
+
}
|
|
3111
|
+
function watch(func, ...values) {
|
|
3112
|
+
current.watch(func, ...values);
|
|
3113
|
+
}
|
|
3114
|
+
function valueOf(value) {
|
|
3115
|
+
return value.$;
|
|
3116
|
+
}
|
|
3117
|
+
function setValue(ref, value) {
|
|
3118
|
+
if (ref instanceof Pointer && value instanceof IValue) {
|
|
3119
|
+
ref.$$ = value;
|
|
3120
|
+
}
|
|
3121
|
+
else {
|
|
3122
|
+
ref.$ = value instanceof IValue ? value.$ : value;
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
window.ref = ref;
|
|
3127
|
+
window.mirror = mirror;
|
|
3128
|
+
window.forward = forward;
|
|
3129
|
+
window.point = point;
|
|
3130
|
+
window.expr = expr;
|
|
3131
|
+
window.watch = watch;
|
|
3132
|
+
window.valueOf = valueOf;
|
|
3133
|
+
window.setValue = setValue;
|
|
3134
|
+
|
|
3135
|
+
// ./lib/functional/components.js
|
|
3136
|
+
function text(text) {
|
|
3137
|
+
if (!(current instanceof Fragment))
|
|
3138
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3139
|
+
;
|
|
3140
|
+
current.text(text);
|
|
3141
|
+
}
|
|
3142
|
+
function debug(text) {
|
|
3143
|
+
if (!(current instanceof Fragment))
|
|
3144
|
+
throw userError('missing parent node', 'out-of-context');
|
|
3145
|
+
current.debug(text);
|
|
3146
|
+
}
|
|
3147
|
+
function predefine(slot, predefined) {
|
|
3148
|
+
return slot || predefined;
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
window.text = text;
|
|
3152
|
+
window.debug = debug;
|
|
3153
|
+
window.predefine = predefine;
|
|
3154
|
+
|
|
3155
|
+
// ./lib/v/index.js
|
|
3156
|
+
|
|
3157
|
+
const v = Object.assign(Object.assign({ ref(value) {
|
|
3158
|
+
return current.ref(value);
|
|
3159
|
+
}, expr: expr, of: valueOf, sv: setValue, alwaysFalse: new Reference(false), app,
|
|
3160
|
+
component,
|
|
3161
|
+
fragment,
|
|
3162
|
+
extension,
|
|
3163
|
+
text,
|
|
3164
|
+
tag,
|
|
3165
|
+
create }, vx), { merge,
|
|
3166
|
+
destructor() {
|
|
3167
|
+
return current.$destroy.bind(current);
|
|
3168
|
+
},
|
|
3169
|
+
runOnDestroy(callback) {
|
|
3170
|
+
current.runOnDestroy(callback);
|
|
3171
|
+
} });
|
|
3172
|
+
|
|
3173
|
+
window.v = v;
|
|
3174
|
+
|
|
3175
3175
|
})();
|