vasille 2.3.2 → 2.3.4
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/cdn/es2015.js +1077 -1072
- package/cdn/es5.js +1726 -1719
- package/flow-typed/vasille.js +2170 -2168
- package/lib/core/core.js +2 -2
- package/lib/index.js +2 -2
- package/lib/node/node.js +4 -1
- package/lib-node/core/core.js +3 -1
- package/lib-node/index.js +3 -1
- package/lib-node/node/node.js +4 -1
- package/package.json +4 -1
- package/types/core/core.d.ts +2 -0
- package/types/index.d.ts +2 -2
package/cdn/es2015.js
CHANGED
|
@@ -1,356 +1,743 @@
|
|
|
1
1
|
(function(){
|
|
2
|
-
// ./lib/
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// ./lib/models/listener.js
|
|
2
|
+
// ./lib/core/destroyable.js
|
|
7
3
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @class
|
|
4
|
+
* Mark an object which can be destroyed
|
|
5
|
+
* @class Destroyable
|
|
10
6
|
*/
|
|
11
|
-
class
|
|
12
|
-
constructor() {
|
|
13
|
-
Object.defineProperties(this, {
|
|
14
|
-
onAdded: {
|
|
15
|
-
value: new Set,
|
|
16
|
-
writable: false,
|
|
17
|
-
configurable: false
|
|
18
|
-
},
|
|
19
|
-
onRemoved: {
|
|
20
|
-
value: new Set,
|
|
21
|
-
writable: false,
|
|
22
|
-
configurable: false
|
|
23
|
-
},
|
|
24
|
-
frozen: {
|
|
25
|
-
value: false,
|
|
26
|
-
writable: true,
|
|
27
|
-
configurable: false
|
|
28
|
-
},
|
|
29
|
-
queue: {
|
|
30
|
-
value: [],
|
|
31
|
-
writable: false,
|
|
32
|
-
configurable: false
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
7
|
+
class Destroyable {
|
|
36
8
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @
|
|
9
|
+
* Make object fields non configurable
|
|
10
|
+
* @protected
|
|
39
11
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
12
|
+
$seal() {
|
|
13
|
+
const $ = this;
|
|
14
|
+
Object.keys($).forEach(i => {
|
|
15
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
16
|
+
if (this.hasOwnProperty(i)) {
|
|
17
|
+
const config = Object.getOwnPropertyDescriptor($, i);
|
|
18
|
+
if (config.configurable) {
|
|
19
|
+
let descriptor;
|
|
20
|
+
if (config.set || config.get) {
|
|
21
|
+
descriptor = {
|
|
22
|
+
configurable: false,
|
|
23
|
+
get: config.get,
|
|
24
|
+
set: config.set,
|
|
25
|
+
enumerable: config.enumerable
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
descriptor = {
|
|
30
|
+
value: $[i],
|
|
31
|
+
configurable: false,
|
|
32
|
+
writable: config.writable,
|
|
33
|
+
enumerable: config.enumerable
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
Object.defineProperty($, i, descriptor);
|
|
37
|
+
}
|
|
45
38
|
}
|
|
46
39
|
});
|
|
47
|
-
return false;
|
|
48
40
|
}
|
|
49
41
|
/**
|
|
50
|
-
*
|
|
51
|
-
* @param index {*} index of value
|
|
52
|
-
* @param value {*} value of added item
|
|
42
|
+
* Garbage collector method
|
|
53
43
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!this.excludeRepeat(index)) {
|
|
57
|
-
this.queue.push({ sign: true, index, value });
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
this.onAdded.forEach(handler => {
|
|
62
|
-
handler(index, value);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
44
|
+
$destroy() {
|
|
45
|
+
// nothing here
|
|
65
46
|
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
window.Destroyable = Destroyable;
|
|
50
|
+
|
|
51
|
+
// ./lib/core/errors.js
|
|
52
|
+
const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
|
|
53
|
+
function notOverwritten() {
|
|
54
|
+
console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
|
|
55
|
+
return "not-overwritten";
|
|
56
|
+
}
|
|
57
|
+
function internalError(msg) {
|
|
58
|
+
console.error("Vasille-SFP: Internal error", msg, reportIt);
|
|
59
|
+
return "internal-error";
|
|
60
|
+
}
|
|
61
|
+
function userError(msg, err) {
|
|
62
|
+
console.error("Vasille-SFP: User error", msg);
|
|
63
|
+
return err;
|
|
64
|
+
}
|
|
65
|
+
function wrongBinding(msg) {
|
|
66
|
+
return userError(msg, "wrong-binding");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
window.notOverwritten = notOverwritten;
|
|
70
|
+
window.internalError = internalError;
|
|
71
|
+
window.userError = userError;
|
|
72
|
+
window.wrongBinding = wrongBinding;
|
|
73
|
+
|
|
74
|
+
// ./lib/core/ivalue.js
|
|
75
|
+
class Switchable extends Destroyable {
|
|
66
76
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @param index {*} index of removed value
|
|
69
|
-
* @param value {*} value of removed item
|
|
77
|
+
* Enable update handlers triggering
|
|
70
78
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (!this.excludeRepeat(index)) {
|
|
74
|
-
this.queue.push({ sign: false, index, value });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
this.onRemoved.forEach(handler => {
|
|
79
|
-
handler(index, value);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
79
|
+
$enable() {
|
|
80
|
+
throw notOverwritten();
|
|
82
81
|
}
|
|
83
82
|
/**
|
|
84
|
-
*
|
|
85
|
-
* @param handler {function} function to run on event emitting
|
|
83
|
+
* disable update handlers triggering
|
|
86
84
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
$disable() {
|
|
86
|
+
throw notOverwritten();
|
|
89
87
|
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Interface which describes a value
|
|
91
|
+
* @class IValue
|
|
92
|
+
* @extends Destroyable
|
|
93
|
+
*/
|
|
94
|
+
class IValue extends Switchable {
|
|
90
95
|
/**
|
|
91
|
-
*
|
|
92
|
-
* @param handler {function} function to run on event emitting
|
|
96
|
+
* @param isEnabled {boolean} initial is enabled state
|
|
93
97
|
*/
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
constructor(isEnabled) {
|
|
99
|
+
super();
|
|
100
|
+
this.isEnabled = isEnabled;
|
|
96
101
|
}
|
|
97
102
|
/**
|
|
98
|
-
*
|
|
99
|
-
* @
|
|
103
|
+
* Get the encapsulated value
|
|
104
|
+
* @return {*} the encapsulated value
|
|
100
105
|
*/
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
get $() {
|
|
107
|
+
throw notOverwritten();
|
|
103
108
|
}
|
|
104
109
|
/**
|
|
105
|
-
*
|
|
106
|
-
* @param
|
|
110
|
+
* Sets the encapsulated value
|
|
111
|
+
* @param value {*} value to encapsulate
|
|
107
112
|
*/
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
set $(value) {
|
|
114
|
+
throw notOverwritten();
|
|
110
115
|
}
|
|
111
116
|
/**
|
|
112
|
-
*
|
|
117
|
+
* Add a new handler to value change
|
|
118
|
+
* @param handler {function(value : *)} the handler to add
|
|
113
119
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (item.sign) {
|
|
117
|
-
this.onAdded.forEach(handler => {
|
|
118
|
-
handler(item.index, item.value);
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
this.onRemoved.forEach(handler => {
|
|
123
|
-
handler(item.index, item.value);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
this.queue.splice(0);
|
|
128
|
-
this.frozen = false;
|
|
120
|
+
$on(handler) {
|
|
121
|
+
throw notOverwritten();
|
|
129
122
|
}
|
|
130
123
|
/**
|
|
131
|
-
*
|
|
124
|
+
* Removes a handler of value change
|
|
125
|
+
* @param handler {function(value : *)} the handler to remove
|
|
132
126
|
*/
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
$off(handler) {
|
|
128
|
+
throw notOverwritten();
|
|
135
129
|
}
|
|
136
130
|
}
|
|
137
131
|
|
|
138
|
-
window.
|
|
132
|
+
window.Switchable = Switchable;
|
|
133
|
+
window.IValue = IValue;
|
|
139
134
|
|
|
140
|
-
// ./lib/
|
|
135
|
+
// ./lib/core/core.js
|
|
136
|
+
|
|
137
|
+
const currentStack = [];
|
|
138
|
+
function stack(node) {
|
|
139
|
+
currentStack.push(current);
|
|
140
|
+
current = node;
|
|
141
|
+
}
|
|
142
|
+
function unstack() {
|
|
143
|
+
current = currentStack.pop();
|
|
144
|
+
}
|
|
141
145
|
/**
|
|
142
|
-
*
|
|
143
|
-
* @
|
|
146
|
+
* Private stuff of a reactive object
|
|
147
|
+
* @class ReactivePrivate
|
|
148
|
+
* @extends Destroyable
|
|
144
149
|
*/
|
|
145
|
-
class
|
|
146
|
-
|
|
147
|
-
* Constructs a object model
|
|
148
|
-
* @param obj {Object} input data
|
|
149
|
-
*/
|
|
150
|
-
constructor(obj = {}) {
|
|
150
|
+
class ReactivePrivate extends Destroyable {
|
|
151
|
+
constructor() {
|
|
151
152
|
super();
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
153
|
+
/**
|
|
154
|
+
* A list of user-defined values
|
|
155
|
+
* @type {Set}
|
|
156
|
+
*/
|
|
157
|
+
this.watch = new Set;
|
|
158
|
+
/**
|
|
159
|
+
* A list of user-defined bindings
|
|
160
|
+
* @type {Set}
|
|
161
|
+
*/
|
|
162
|
+
this.bindings = new Set;
|
|
163
|
+
/**
|
|
164
|
+
* A list of user defined models
|
|
165
|
+
*/
|
|
166
|
+
this.models = new Set;
|
|
167
|
+
/**
|
|
168
|
+
* Reactivity switch state
|
|
169
|
+
* @type {boolean}
|
|
170
|
+
*/
|
|
171
|
+
this.enabled = true;
|
|
172
|
+
/**
|
|
173
|
+
* The frozen state of object
|
|
174
|
+
* @type {boolean}
|
|
175
|
+
*/
|
|
176
|
+
this.frozen = false;
|
|
177
|
+
this.$seal();
|
|
178
|
+
}
|
|
179
|
+
$destroy() {
|
|
180
|
+
this.watch.forEach(value => value.$destroy());
|
|
181
|
+
this.watch.clear();
|
|
182
|
+
this.bindings.forEach(binding => binding.$destroy());
|
|
183
|
+
this.bindings.clear();
|
|
184
|
+
this.models.forEach(model => model.disableReactivity());
|
|
185
|
+
this.models.clear();
|
|
186
|
+
this.freezeExpr && this.freezeExpr.$destroy();
|
|
187
|
+
this.onDestroy && this.onDestroy();
|
|
188
|
+
super.$destroy();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A reactive object
|
|
193
|
+
* @class Reactive
|
|
194
|
+
* @extends Destroyable
|
|
195
|
+
*/
|
|
196
|
+
class Reactive extends Destroyable {
|
|
197
|
+
constructor(input, $) {
|
|
198
|
+
super();
|
|
199
|
+
this.input = input;
|
|
200
|
+
this.$ = $ || new ReactivePrivate;
|
|
201
|
+
this.$seal();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get parent node
|
|
181
205
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
206
|
+
get parent() {
|
|
207
|
+
return this.$.parent;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Create a reference
|
|
211
|
+
* @param value {*} value to reference
|
|
212
|
+
*/
|
|
213
|
+
ref(value) {
|
|
214
|
+
const $ = this.$;
|
|
215
|
+
const ref = new Reference(value);
|
|
216
|
+
$.watch.add(ref);
|
|
217
|
+
return ref;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create a mirror
|
|
221
|
+
* @param value {IValue} value to mirror
|
|
222
|
+
*/
|
|
223
|
+
mirror(value) {
|
|
224
|
+
const mirror = new Mirror(value, false);
|
|
225
|
+
this.$.watch.add(mirror);
|
|
226
|
+
return mirror;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Create a forward-only mirror
|
|
230
|
+
* @param value {IValue} value to mirror
|
|
231
|
+
*/
|
|
232
|
+
forward(value) {
|
|
233
|
+
const mirror = new Mirror(value, true);
|
|
234
|
+
this.$.watch.add(mirror);
|
|
235
|
+
return mirror;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Creates a pointer
|
|
239
|
+
* @param value {*} default value to point
|
|
240
|
+
* @param forwardOnly {boolean} forward only sync
|
|
241
|
+
*/
|
|
242
|
+
point(value, forwardOnly = false) {
|
|
243
|
+
const $ = this.$;
|
|
244
|
+
const pointer = new Pointer(value, forwardOnly);
|
|
245
|
+
$.watch.add(pointer);
|
|
246
|
+
return pointer;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Register a model
|
|
250
|
+
* @param model
|
|
251
|
+
*/
|
|
252
|
+
register(model) {
|
|
253
|
+
this.$.models.add(model);
|
|
254
|
+
return model;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Creates a watcher
|
|
258
|
+
* @param func {function} function to run on any argument change
|
|
259
|
+
* @param values
|
|
260
|
+
*/
|
|
261
|
+
watch(func, ...values) {
|
|
262
|
+
const $ = this.$;
|
|
263
|
+
$.watch.add(new Expression(func, !this.$.frozen, ...values));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Creates a computed value
|
|
267
|
+
* @param func {function} function to run on any argument change
|
|
268
|
+
* @param values
|
|
269
|
+
* @return {IValue} the created ivalue
|
|
270
|
+
*/
|
|
271
|
+
expr(func, ...values) {
|
|
272
|
+
const res = new Expression(func, !this.$.frozen, ...values);
|
|
273
|
+
const $ = this.$;
|
|
274
|
+
$.watch.add(res);
|
|
275
|
+
return res;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Enable reactivity of fields
|
|
279
|
+
*/
|
|
280
|
+
enable() {
|
|
281
|
+
const $ = this.$;
|
|
282
|
+
if (!$.enabled) {
|
|
283
|
+
$.watch.forEach(watcher => {
|
|
284
|
+
watcher.$enable();
|
|
285
|
+
});
|
|
286
|
+
$.models.forEach(model => {
|
|
287
|
+
model.enableReactivity();
|
|
288
|
+
});
|
|
289
|
+
$.enabled = true;
|
|
186
290
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Disable reactivity of fields
|
|
294
|
+
*/
|
|
295
|
+
disable() {
|
|
296
|
+
const $ = this.$;
|
|
297
|
+
if ($.enabled) {
|
|
298
|
+
$.watch.forEach(watcher => {
|
|
299
|
+
watcher.$disable();
|
|
300
|
+
});
|
|
301
|
+
$.models.forEach(model => {
|
|
302
|
+
model.disableReactivity();
|
|
193
303
|
});
|
|
304
|
+
$.enabled = false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Disable/Enable reactivity of object fields with feedback
|
|
309
|
+
* @param cond {IValue} show condition
|
|
310
|
+
* @param onOff {function} on show feedback
|
|
311
|
+
* @param onOn {function} on hide feedback
|
|
312
|
+
*/
|
|
313
|
+
bindAlive(cond, onOff, onOn) {
|
|
314
|
+
const $ = this.$;
|
|
315
|
+
if ($.freezeExpr) {
|
|
316
|
+
throw wrongBinding("this component already have a freeze state");
|
|
317
|
+
}
|
|
318
|
+
if ($.watch.has(cond)) {
|
|
319
|
+
throw wrongBinding("freeze state must be bound to an external component");
|
|
320
|
+
}
|
|
321
|
+
$.freezeExpr = new Expression((cond) => {
|
|
322
|
+
$.frozen = !cond;
|
|
323
|
+
if (cond) {
|
|
324
|
+
onOn === null || onOn === void 0 ? void 0 : onOn();
|
|
325
|
+
this.enable();
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
onOff === null || onOff === void 0 ? void 0 : onOff();
|
|
329
|
+
this.disable();
|
|
330
|
+
}
|
|
331
|
+
}, true, cond);
|
|
332
|
+
return this;
|
|
333
|
+
}
|
|
334
|
+
init() {
|
|
335
|
+
this.applyOptions(this.input);
|
|
336
|
+
return this.compose(this.input);
|
|
337
|
+
}
|
|
338
|
+
applyOptions(input) {
|
|
339
|
+
// empty
|
|
340
|
+
}
|
|
341
|
+
applyOptionsNow() {
|
|
342
|
+
this.applyOptions(this.input);
|
|
343
|
+
}
|
|
344
|
+
compose(input) {
|
|
345
|
+
throw notOverwritten();
|
|
346
|
+
}
|
|
347
|
+
composeNow() {
|
|
348
|
+
this.compose(this.input);
|
|
349
|
+
}
|
|
350
|
+
runFunctional(f, ...args) {
|
|
351
|
+
stack(this);
|
|
352
|
+
// yet another ts bug
|
|
353
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
354
|
+
// @ts-ignore
|
|
355
|
+
const result = f(...args);
|
|
356
|
+
unstack();
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
runOnDestroy(func) {
|
|
360
|
+
this.$.onDestroy = func;
|
|
361
|
+
}
|
|
362
|
+
$destroy() {
|
|
363
|
+
super.$destroy();
|
|
364
|
+
this.$.$destroy();
|
|
365
|
+
this.$ = null;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
window.stack = stack;
|
|
370
|
+
window.unstack = unstack;
|
|
371
|
+
window.ReactivePrivate = ReactivePrivate;
|
|
372
|
+
window.Reactive = Reactive;
|
|
373
|
+
|
|
374
|
+
// ./lib/value/reference.js
|
|
375
|
+
/**
|
|
376
|
+
* Declares a notifiable value
|
|
377
|
+
* @class Reference
|
|
378
|
+
* @extends IValue
|
|
379
|
+
*/
|
|
380
|
+
class Reference extends IValue {
|
|
381
|
+
/**
|
|
382
|
+
* @param value {any} the initial value
|
|
383
|
+
*/
|
|
384
|
+
constructor(value) {
|
|
385
|
+
super(true);
|
|
386
|
+
this.$value = value;
|
|
387
|
+
this.$onchange = new Set;
|
|
388
|
+
this.$seal();
|
|
389
|
+
}
|
|
390
|
+
get $() {
|
|
391
|
+
return this.$value;
|
|
392
|
+
}
|
|
393
|
+
set $(value) {
|
|
394
|
+
if (this.$value !== value) {
|
|
395
|
+
this.$value = value;
|
|
396
|
+
if (this.isEnabled) {
|
|
397
|
+
this.$onchange.forEach(handler => {
|
|
398
|
+
handler(value);
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
$enable() {
|
|
404
|
+
if (!this.isEnabled) {
|
|
405
|
+
this.$onchange.forEach(handler => {
|
|
406
|
+
handler(this.$value);
|
|
407
|
+
});
|
|
408
|
+
this.isEnabled = true;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
$disable() {
|
|
412
|
+
this.isEnabled = false;
|
|
413
|
+
}
|
|
414
|
+
$on(handler) {
|
|
415
|
+
this.$onchange.add(handler);
|
|
416
|
+
}
|
|
417
|
+
$off(handler) {
|
|
418
|
+
this.$onchange.delete(handler);
|
|
419
|
+
}
|
|
420
|
+
$destroy() {
|
|
421
|
+
super.$destroy();
|
|
422
|
+
this.$onchange.clear();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
window.Reference = Reference;
|
|
427
|
+
|
|
428
|
+
// ./lib/value/expression.js
|
|
429
|
+
/**
|
|
430
|
+
* Bind some values to one expression
|
|
431
|
+
* @class Expression
|
|
432
|
+
* @extends IValue
|
|
433
|
+
*/
|
|
434
|
+
class Expression extends IValue {
|
|
435
|
+
/**
|
|
436
|
+
* Creates a function bounded to N values
|
|
437
|
+
* @param func {Function} the function to bound
|
|
438
|
+
* @param values
|
|
439
|
+
* @param link {Boolean} links immediately if true
|
|
440
|
+
*/
|
|
441
|
+
constructor(func, link, ...values) {
|
|
442
|
+
super(false);
|
|
443
|
+
/**
|
|
444
|
+
* Expression will link different handler for each value of list
|
|
445
|
+
*/
|
|
446
|
+
this.linkedFunc = [];
|
|
447
|
+
const handler = (i) => {
|
|
448
|
+
if (i != null) {
|
|
449
|
+
this.valuesCache[i] = this.values[i].$;
|
|
450
|
+
}
|
|
451
|
+
this.sync.$ = func.apply(this, this.valuesCache);
|
|
452
|
+
};
|
|
453
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
454
|
+
// @ts-ignore
|
|
455
|
+
this.valuesCache = values.map(item => item.$);
|
|
456
|
+
this.sync = new Reference(func.apply(this, this.valuesCache));
|
|
457
|
+
let i = 0;
|
|
458
|
+
values.forEach(() => {
|
|
459
|
+
this.linkedFunc.push(handler.bind(this, Number(i++)));
|
|
460
|
+
});
|
|
461
|
+
this.values = values;
|
|
462
|
+
this.func = handler;
|
|
463
|
+
if (link) {
|
|
464
|
+
this.$enable();
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
handler();
|
|
468
|
+
}
|
|
469
|
+
this.$seal();
|
|
470
|
+
}
|
|
471
|
+
get $() {
|
|
472
|
+
return this.sync.$;
|
|
473
|
+
}
|
|
474
|
+
set $(value) {
|
|
475
|
+
this.sync.$ = value;
|
|
476
|
+
}
|
|
477
|
+
$on(handler) {
|
|
478
|
+
this.sync.$on(handler);
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
$off(handler) {
|
|
482
|
+
this.sync.$off(handler);
|
|
483
|
+
return this;
|
|
484
|
+
}
|
|
485
|
+
$enable() {
|
|
486
|
+
if (!this.isEnabled) {
|
|
487
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
488
|
+
this.values[i].$on(this.linkedFunc[i]);
|
|
489
|
+
this.valuesCache[i] = this.values[i].$;
|
|
490
|
+
}
|
|
491
|
+
this.func();
|
|
492
|
+
this.isEnabled = true;
|
|
493
|
+
}
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
496
|
+
$disable() {
|
|
497
|
+
if (this.isEnabled) {
|
|
498
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
499
|
+
this.values[i].$off(this.linkedFunc[i]);
|
|
500
|
+
}
|
|
501
|
+
this.isEnabled = false;
|
|
194
502
|
}
|
|
195
|
-
this.listener.emitAdded(key, this.container[key]);
|
|
196
503
|
return this;
|
|
197
504
|
}
|
|
198
|
-
|
|
199
|
-
|
|
505
|
+
$destroy() {
|
|
506
|
+
this.$disable();
|
|
507
|
+
this.values.splice(0);
|
|
508
|
+
this.valuesCache.splice(0);
|
|
509
|
+
this.linkedFunc.splice(0);
|
|
510
|
+
super.$destroy();
|
|
200
511
|
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
window.Expression = Expression;
|
|
515
|
+
|
|
516
|
+
// ./lib/value/mirror.js
|
|
517
|
+
/**
|
|
518
|
+
* Declares a notifiable bind to a value
|
|
519
|
+
* @class Mirror
|
|
520
|
+
* @extends IValue
|
|
521
|
+
* @version 2
|
|
522
|
+
*/
|
|
523
|
+
class Mirror extends Reference {
|
|
201
524
|
/**
|
|
202
|
-
*
|
|
203
|
-
* @param
|
|
525
|
+
* Constructs a notifiable bind to a value
|
|
526
|
+
* @param value {IValue} is initial value
|
|
527
|
+
* @param forwardOnly {boolean} ensure forward only synchronization
|
|
204
528
|
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
529
|
+
constructor(value, forwardOnly = false) {
|
|
530
|
+
super(value.$);
|
|
531
|
+
this.$handler = (v) => {
|
|
532
|
+
this.$ = v;
|
|
533
|
+
};
|
|
534
|
+
this.$pointedValue = value;
|
|
535
|
+
this.$forwardOnly = forwardOnly;
|
|
536
|
+
value.$on(this.$handler);
|
|
537
|
+
this.$seal();
|
|
538
|
+
}
|
|
539
|
+
get $() {
|
|
540
|
+
// this is a ts bug
|
|
541
|
+
// eslint-disable-next-line
|
|
542
|
+
// @ts-ignore
|
|
543
|
+
return super.$;
|
|
544
|
+
}
|
|
545
|
+
set $(v) {
|
|
546
|
+
if (!this.$forwardOnly) {
|
|
547
|
+
this.$pointedValue.$ = v;
|
|
209
548
|
}
|
|
549
|
+
// this is a ts bug
|
|
550
|
+
// eslint-disable-next-line
|
|
551
|
+
// @ts-ignore
|
|
552
|
+
super.$ = v;
|
|
210
553
|
}
|
|
211
|
-
|
|
212
|
-
this.
|
|
554
|
+
$enable() {
|
|
555
|
+
if (!this.isEnabled) {
|
|
556
|
+
this.isEnabled = true;
|
|
557
|
+
this.$pointedValue.$on(this.$handler);
|
|
558
|
+
this.$ = this.$pointedValue.$;
|
|
559
|
+
}
|
|
213
560
|
}
|
|
214
|
-
|
|
215
|
-
this.
|
|
561
|
+
$disable() {
|
|
562
|
+
if (this.isEnabled) {
|
|
563
|
+
this.$pointedValue.$off(this.$handler);
|
|
564
|
+
this.isEnabled = false;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
$destroy() {
|
|
568
|
+
this.$disable();
|
|
569
|
+
super.$destroy();
|
|
216
570
|
}
|
|
217
571
|
}
|
|
218
572
|
|
|
219
|
-
window.
|
|
573
|
+
window.Mirror = Mirror;
|
|
220
574
|
|
|
221
|
-
// ./lib/
|
|
575
|
+
// ./lib/value/pointer.js
|
|
222
576
|
/**
|
|
223
|
-
*
|
|
224
|
-
* @class
|
|
225
|
-
* @extends
|
|
226
|
-
* @implements IModel
|
|
577
|
+
* r/w pointer to a value
|
|
578
|
+
* @class Pointer
|
|
579
|
+
* @extends Mirror
|
|
227
580
|
*/
|
|
228
|
-
class
|
|
581
|
+
class Pointer extends Mirror {
|
|
229
582
|
/**
|
|
230
|
-
*
|
|
231
|
-
* @param
|
|
583
|
+
* @param value {IValue} value to point
|
|
584
|
+
* @param forwardOnly {boolean} forward only data flow
|
|
232
585
|
*/
|
|
233
|
-
constructor(
|
|
234
|
-
super();
|
|
235
|
-
Object.defineProperty(this, 'listener', {
|
|
236
|
-
value: new Listener,
|
|
237
|
-
writable: false,
|
|
238
|
-
configurable: false
|
|
239
|
-
});
|
|
240
|
-
set.forEach(item => {
|
|
241
|
-
super.add(item);
|
|
242
|
-
});
|
|
586
|
+
constructor(value, forwardOnly = false) {
|
|
587
|
+
super(value, forwardOnly);
|
|
243
588
|
}
|
|
244
589
|
/**
|
|
245
|
-
*
|
|
246
|
-
* @param value {
|
|
247
|
-
* @return {this} a pointer to this
|
|
590
|
+
* Point a new ivalue
|
|
591
|
+
* @param value {IValue} value to point
|
|
248
592
|
*/
|
|
249
|
-
|
|
250
|
-
if (
|
|
251
|
-
this
|
|
252
|
-
|
|
593
|
+
set $$(value) {
|
|
594
|
+
if (this.$pointedValue !== value) {
|
|
595
|
+
this.$disable();
|
|
596
|
+
this.$pointedValue = value;
|
|
597
|
+
this.$enable();
|
|
253
598
|
}
|
|
254
|
-
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
window.Pointer = Pointer;
|
|
603
|
+
|
|
604
|
+
// ./lib/models/listener.js
|
|
605
|
+
/**
|
|
606
|
+
* Represent a listener for a model
|
|
607
|
+
* @class Listener
|
|
608
|
+
*/
|
|
609
|
+
class Listener {
|
|
610
|
+
constructor() {
|
|
611
|
+
Object.defineProperties(this, {
|
|
612
|
+
onAdded: {
|
|
613
|
+
value: new Set,
|
|
614
|
+
writable: false,
|
|
615
|
+
configurable: false
|
|
616
|
+
},
|
|
617
|
+
onRemoved: {
|
|
618
|
+
value: new Set,
|
|
619
|
+
writable: false,
|
|
620
|
+
configurable: false
|
|
621
|
+
},
|
|
622
|
+
frozen: {
|
|
623
|
+
value: false,
|
|
624
|
+
writable: true,
|
|
625
|
+
configurable: false
|
|
626
|
+
},
|
|
627
|
+
queue: {
|
|
628
|
+
value: [],
|
|
629
|
+
writable: false,
|
|
630
|
+
configurable: false
|
|
631
|
+
}
|
|
632
|
+
});
|
|
255
633
|
}
|
|
256
634
|
/**
|
|
257
|
-
*
|
|
635
|
+
* Exclude the repeated operation in queue
|
|
636
|
+
* @private
|
|
258
637
|
*/
|
|
259
|
-
|
|
260
|
-
this.forEach(item => {
|
|
261
|
-
|
|
638
|
+
excludeRepeat(index) {
|
|
639
|
+
this.queue.forEach((item, i) => {
|
|
640
|
+
if (item.index === index) {
|
|
641
|
+
this.queue.splice(i, 1);
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
262
644
|
});
|
|
263
|
-
|
|
645
|
+
return false;
|
|
264
646
|
}
|
|
265
647
|
/**
|
|
266
|
-
*
|
|
267
|
-
* @param
|
|
268
|
-
* @
|
|
648
|
+
* Emits added event to listeners
|
|
649
|
+
* @param index {*} index of value
|
|
650
|
+
* @param value {*} value of added item
|
|
269
651
|
*/
|
|
270
|
-
|
|
271
|
-
if (
|
|
272
|
-
this.
|
|
652
|
+
emitAdded(index, value) {
|
|
653
|
+
if (this.frozen) {
|
|
654
|
+
if (!this.excludeRepeat(index)) {
|
|
655
|
+
this.queue.push({ sign: true, index, value });
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
this.onAdded.forEach(handler => {
|
|
660
|
+
handler(index, value);
|
|
661
|
+
});
|
|
273
662
|
}
|
|
274
|
-
return super.delete(value);
|
|
275
|
-
}
|
|
276
|
-
enableReactivity() {
|
|
277
|
-
this.listener.enableReactivity();
|
|
278
|
-
}
|
|
279
|
-
disableReactivity() {
|
|
280
|
-
this.listener.disableReactivity();
|
|
281
663
|
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
window.SetModel = SetModel;
|
|
285
|
-
|
|
286
|
-
// ./lib/models/map-model.js
|
|
287
|
-
/**
|
|
288
|
-
* A Map based memory
|
|
289
|
-
* @class MapModel
|
|
290
|
-
* @extends Map
|
|
291
|
-
* @implements IModel
|
|
292
|
-
*/
|
|
293
|
-
class MapModel extends Map {
|
|
294
664
|
/**
|
|
295
|
-
*
|
|
296
|
-
* @param
|
|
665
|
+
* Emits removed event to listeners
|
|
666
|
+
* @param index {*} index of removed value
|
|
667
|
+
* @param value {*} value of removed item
|
|
297
668
|
*/
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
669
|
+
emitRemoved(index, value) {
|
|
670
|
+
if (this.frozen) {
|
|
671
|
+
if (!this.excludeRepeat(index)) {
|
|
672
|
+
this.queue.push({ sign: false, index, value });
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
this.onRemoved.forEach(handler => {
|
|
677
|
+
handler(index, value);
|
|
678
|
+
});
|
|
679
|
+
}
|
|
308
680
|
}
|
|
309
681
|
/**
|
|
310
|
-
*
|
|
682
|
+
* Adds a handler to added event
|
|
683
|
+
* @param handler {function} function to run on event emitting
|
|
311
684
|
*/
|
|
312
|
-
|
|
313
|
-
this.
|
|
314
|
-
this.listener.emitRemoved(key, value);
|
|
315
|
-
});
|
|
316
|
-
super.clear();
|
|
685
|
+
onAdd(handler) {
|
|
686
|
+
this.onAdded.add(handler);
|
|
317
687
|
}
|
|
318
688
|
/**
|
|
319
|
-
*
|
|
320
|
-
* @param
|
|
321
|
-
* @return {boolean} true if removed something, otherwise false
|
|
689
|
+
* Adds a handler to removed event
|
|
690
|
+
* @param handler {function} function to run on event emitting
|
|
322
691
|
*/
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
692
|
+
onRemove(handler) {
|
|
693
|
+
this.onRemoved.add(handler);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Removes an handler from added event
|
|
697
|
+
* @param handler {function} handler to remove
|
|
698
|
+
*/
|
|
699
|
+
offAdd(handler) {
|
|
700
|
+
this.onAdded.delete(handler);
|
|
329
701
|
}
|
|
330
702
|
/**
|
|
331
|
-
*
|
|
332
|
-
* @param
|
|
333
|
-
* @param value {*} value
|
|
334
|
-
* @return {MapModel} a pointer to this
|
|
703
|
+
* Removes an handler form removed event
|
|
704
|
+
* @param handler {function} handler to remove
|
|
335
705
|
*/
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (tmp) {
|
|
339
|
-
this.listener.emitRemoved(key, tmp);
|
|
340
|
-
}
|
|
341
|
-
super.set(key, value);
|
|
342
|
-
this.listener.emitAdded(key, value);
|
|
343
|
-
return this;
|
|
706
|
+
offRemove(handler) {
|
|
707
|
+
this.onRemoved.delete(handler);
|
|
344
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* Run all queued operation and enable reactivity
|
|
711
|
+
*/
|
|
345
712
|
enableReactivity() {
|
|
346
|
-
this.
|
|
713
|
+
this.queue.forEach(item => {
|
|
714
|
+
if (item.sign) {
|
|
715
|
+
this.onAdded.forEach(handler => {
|
|
716
|
+
handler(item.index, item.value);
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
this.onRemoved.forEach(handler => {
|
|
721
|
+
handler(item.index, item.value);
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
this.queue.splice(0);
|
|
726
|
+
this.frozen = false;
|
|
347
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* Disable the reactivity and enable the queue
|
|
730
|
+
*/
|
|
348
731
|
disableReactivity() {
|
|
349
|
-
this.
|
|
732
|
+
this.frozen = true;
|
|
350
733
|
}
|
|
351
734
|
}
|
|
352
735
|
|
|
353
|
-
window.
|
|
736
|
+
window.Listener = Listener;
|
|
737
|
+
|
|
738
|
+
// ./lib/models/model.js
|
|
739
|
+
|
|
740
|
+
|
|
354
741
|
|
|
355
742
|
// ./lib/models/array-model.js
|
|
356
743
|
/**
|
|
@@ -554,399 +941,247 @@ class ArrayModel extends Array {
|
|
|
554
941
|
return this;
|
|
555
942
|
}
|
|
556
943
|
replace(at, with_) {
|
|
557
|
-
this.listener.emitAdded(this[at], with_);
|
|
558
|
-
this.listener.emitRemoved(this[at], this[at]);
|
|
559
|
-
this[at] = with_;
|
|
560
|
-
return this;
|
|
561
|
-
}
|
|
562
|
-
enableReactivity() {
|
|
563
|
-
this.listener.enableReactivity();
|
|
564
|
-
}
|
|
565
|
-
disableReactivity() {
|
|
566
|
-
this.listener.disableReactivity();
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
window.ArrayModel = ArrayModel;
|
|
571
|
-
|
|
572
|
-
// ./lib/core/errors.js
|
|
573
|
-
const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
|
|
574
|
-
function notOverwritten() {
|
|
575
|
-
console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
|
|
576
|
-
return "not-overwritten";
|
|
577
|
-
}
|
|
578
|
-
function internalError(msg) {
|
|
579
|
-
console.error("Vasille-SFP: Internal error", msg, reportIt);
|
|
580
|
-
return "internal-error";
|
|
581
|
-
}
|
|
582
|
-
function userError(msg, err) {
|
|
583
|
-
console.error("Vasille-SFP: User error", msg);
|
|
584
|
-
return err;
|
|
585
|
-
}
|
|
586
|
-
function wrongBinding(msg) {
|
|
587
|
-
return userError(msg, "wrong-binding");
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
window.notOverwritten = notOverwritten;
|
|
591
|
-
window.internalError = internalError;
|
|
592
|
-
window.userError = userError;
|
|
593
|
-
window.wrongBinding = wrongBinding;
|
|
594
|
-
|
|
595
|
-
// ./lib/core/destroyable.js
|
|
596
|
-
/**
|
|
597
|
-
* Mark an object which can be destroyed
|
|
598
|
-
* @class Destroyable
|
|
599
|
-
*/
|
|
600
|
-
class Destroyable {
|
|
601
|
-
/**
|
|
602
|
-
* Make object fields non configurable
|
|
603
|
-
* @protected
|
|
604
|
-
*/
|
|
605
|
-
$seal() {
|
|
606
|
-
const $ = this;
|
|
607
|
-
Object.keys($).forEach(i => {
|
|
608
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
609
|
-
if (this.hasOwnProperty(i)) {
|
|
610
|
-
const config = Object.getOwnPropertyDescriptor($, i);
|
|
611
|
-
if (config.configurable) {
|
|
612
|
-
let descriptor;
|
|
613
|
-
if (config.set || config.get) {
|
|
614
|
-
descriptor = {
|
|
615
|
-
configurable: false,
|
|
616
|
-
get: config.get,
|
|
617
|
-
set: config.set,
|
|
618
|
-
enumerable: config.enumerable
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
else {
|
|
622
|
-
descriptor = {
|
|
623
|
-
value: $[i],
|
|
624
|
-
configurable: false,
|
|
625
|
-
writable: config.writable,
|
|
626
|
-
enumerable: config.enumerable
|
|
627
|
-
};
|
|
628
|
-
}
|
|
629
|
-
Object.defineProperty($, i, descriptor);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Garbage collector method
|
|
636
|
-
*/
|
|
637
|
-
$destroy() {
|
|
638
|
-
// nothing here
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
window.Destroyable = Destroyable;
|
|
643
|
-
|
|
644
|
-
// ./lib/core/ivalue.js
|
|
645
|
-
class Switchable extends Destroyable {
|
|
646
|
-
/**
|
|
647
|
-
* Enable update handlers triggering
|
|
648
|
-
*/
|
|
649
|
-
$enable() {
|
|
650
|
-
throw notOverwritten();
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* disable update handlers triggering
|
|
654
|
-
*/
|
|
655
|
-
$disable() {
|
|
656
|
-
throw notOverwritten();
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Interface which describes a value
|
|
661
|
-
* @class IValue
|
|
662
|
-
* @extends Destroyable
|
|
663
|
-
*/
|
|
664
|
-
class IValue extends Switchable {
|
|
665
|
-
/**
|
|
666
|
-
* @param isEnabled {boolean} initial is enabled state
|
|
667
|
-
*/
|
|
668
|
-
constructor(isEnabled) {
|
|
669
|
-
super();
|
|
670
|
-
this.isEnabled = isEnabled;
|
|
671
|
-
}
|
|
672
|
-
/**
|
|
673
|
-
* Get the encapsulated value
|
|
674
|
-
* @return {*} the encapsulated value
|
|
675
|
-
*/
|
|
676
|
-
get $() {
|
|
677
|
-
throw notOverwritten();
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Sets the encapsulated value
|
|
681
|
-
* @param value {*} value to encapsulate
|
|
682
|
-
*/
|
|
683
|
-
set $(value) {
|
|
684
|
-
throw notOverwritten();
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Add a new handler to value change
|
|
688
|
-
* @param handler {function(value : *)} the handler to add
|
|
689
|
-
*/
|
|
690
|
-
$on(handler) {
|
|
691
|
-
throw notOverwritten();
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Removes a handler of value change
|
|
695
|
-
* @param handler {function(value : *)} the handler to remove
|
|
696
|
-
*/
|
|
697
|
-
$off(handler) {
|
|
698
|
-
throw notOverwritten();
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
window.Switchable = Switchable;
|
|
703
|
-
window.IValue = IValue;
|
|
704
|
-
|
|
705
|
-
// ./lib/index.js
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
// ./lib/spec/svg.js
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
// ./lib/spec/react.js
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
// ./lib/spec/html.js
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
// ./lib/value/expression.js
|
|
722
|
-
/**
|
|
723
|
-
* Bind some values to one expression
|
|
724
|
-
* @class Expression
|
|
725
|
-
* @extends IValue
|
|
726
|
-
*/
|
|
727
|
-
class Expression extends IValue {
|
|
728
|
-
/**
|
|
729
|
-
* Creates a function bounded to N values
|
|
730
|
-
* @param func {Function} the function to bound
|
|
731
|
-
* @param values
|
|
732
|
-
* @param link {Boolean} links immediately if true
|
|
733
|
-
*/
|
|
734
|
-
constructor(func, link, ...values) {
|
|
735
|
-
super(false);
|
|
736
|
-
/**
|
|
737
|
-
* Expression will link different handler for each value of list
|
|
738
|
-
*/
|
|
739
|
-
this.linkedFunc = [];
|
|
740
|
-
const handler = (i) => {
|
|
741
|
-
if (i != null) {
|
|
742
|
-
this.valuesCache[i] = this.values[i].$;
|
|
743
|
-
}
|
|
744
|
-
this.sync.$ = func.apply(this, this.valuesCache);
|
|
745
|
-
};
|
|
746
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
747
|
-
// @ts-ignore
|
|
748
|
-
this.valuesCache = values.map(item => item.$);
|
|
749
|
-
this.sync = new Reference(func.apply(this, this.valuesCache));
|
|
750
|
-
let i = 0;
|
|
751
|
-
values.forEach(() => {
|
|
752
|
-
this.linkedFunc.push(handler.bind(this, Number(i++)));
|
|
753
|
-
});
|
|
754
|
-
this.values = values;
|
|
755
|
-
this.func = handler;
|
|
756
|
-
if (link) {
|
|
757
|
-
this.$enable();
|
|
758
|
-
}
|
|
759
|
-
else {
|
|
760
|
-
handler();
|
|
761
|
-
}
|
|
762
|
-
this.$seal();
|
|
944
|
+
this.listener.emitAdded(this[at], with_);
|
|
945
|
+
this.listener.emitRemoved(this[at], this[at]);
|
|
946
|
+
this[at] = with_;
|
|
947
|
+
return this;
|
|
763
948
|
}
|
|
764
|
-
|
|
765
|
-
|
|
949
|
+
enableReactivity() {
|
|
950
|
+
this.listener.enableReactivity();
|
|
766
951
|
}
|
|
767
|
-
|
|
768
|
-
this.
|
|
952
|
+
disableReactivity() {
|
|
953
|
+
this.listener.disableReactivity();
|
|
769
954
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
window.ArrayModel = ArrayModel;
|
|
958
|
+
|
|
959
|
+
// ./lib/models/map-model.js
|
|
960
|
+
/**
|
|
961
|
+
* A Map based memory
|
|
962
|
+
* @class MapModel
|
|
963
|
+
* @extends Map
|
|
964
|
+
* @implements IModel
|
|
965
|
+
*/
|
|
966
|
+
class MapModel extends Map {
|
|
967
|
+
/**
|
|
968
|
+
* Constructs a map model
|
|
969
|
+
* @param map {[*, *][]} input data
|
|
970
|
+
*/
|
|
971
|
+
constructor(map = []) {
|
|
972
|
+
super();
|
|
973
|
+
Object.defineProperty(this, 'listener', {
|
|
974
|
+
value: new Listener,
|
|
975
|
+
writable: false,
|
|
976
|
+
configurable: false
|
|
977
|
+
});
|
|
978
|
+
map.forEach(([key, value]) => {
|
|
979
|
+
super.set(key, value);
|
|
980
|
+
});
|
|
773
981
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
982
|
+
/**
|
|
983
|
+
* Calls Map.clear and notify abut changes
|
|
984
|
+
*/
|
|
985
|
+
clear() {
|
|
986
|
+
this.forEach((value, key) => {
|
|
987
|
+
this.listener.emitRemoved(key, value);
|
|
988
|
+
});
|
|
989
|
+
super.clear();
|
|
777
990
|
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
991
|
+
/**
|
|
992
|
+
* Calls Map.delete and notify abut changes
|
|
993
|
+
* @param key {*} key
|
|
994
|
+
* @return {boolean} true if removed something, otherwise false
|
|
995
|
+
*/
|
|
996
|
+
delete(key) {
|
|
997
|
+
const tmp = super.get(key);
|
|
998
|
+
if (tmp) {
|
|
999
|
+
this.listener.emitRemoved(key, tmp);
|
|
786
1000
|
}
|
|
787
|
-
return
|
|
1001
|
+
return super.delete(key);
|
|
788
1002
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
1003
|
+
/**
|
|
1004
|
+
* Calls Map.set and notify abut changes
|
|
1005
|
+
* @param key {*} key
|
|
1006
|
+
* @param value {*} value
|
|
1007
|
+
* @return {MapModel} a pointer to this
|
|
1008
|
+
*/
|
|
1009
|
+
set(key, value) {
|
|
1010
|
+
const tmp = super.get(key);
|
|
1011
|
+
if (tmp) {
|
|
1012
|
+
this.listener.emitRemoved(key, tmp);
|
|
795
1013
|
}
|
|
1014
|
+
super.set(key, value);
|
|
1015
|
+
this.listener.emitAdded(key, value);
|
|
796
1016
|
return this;
|
|
797
1017
|
}
|
|
798
|
-
|
|
799
|
-
this
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
this.
|
|
803
|
-
super.$destroy();
|
|
1018
|
+
enableReactivity() {
|
|
1019
|
+
this.listener.enableReactivity();
|
|
1020
|
+
}
|
|
1021
|
+
disableReactivity() {
|
|
1022
|
+
this.listener.disableReactivity();
|
|
804
1023
|
}
|
|
805
1024
|
}
|
|
806
1025
|
|
|
807
|
-
window.
|
|
1026
|
+
window.MapModel = MapModel;
|
|
808
1027
|
|
|
809
|
-
// ./lib/
|
|
1028
|
+
// ./lib/models/object-model.js
|
|
810
1029
|
/**
|
|
811
|
-
*
|
|
812
|
-
* @
|
|
813
|
-
* @extends IValue
|
|
1030
|
+
* Object based model
|
|
1031
|
+
* @extends Object
|
|
814
1032
|
*/
|
|
815
|
-
class
|
|
1033
|
+
class ObjectModel extends Object {
|
|
816
1034
|
/**
|
|
817
|
-
*
|
|
1035
|
+
* Constructs a object model
|
|
1036
|
+
* @param obj {Object} input data
|
|
818
1037
|
*/
|
|
819
|
-
constructor(
|
|
820
|
-
super(
|
|
821
|
-
this
|
|
822
|
-
this
|
|
823
|
-
|
|
1038
|
+
constructor(obj = {}) {
|
|
1039
|
+
super();
|
|
1040
|
+
this.container = Object.create(null);
|
|
1041
|
+
Object.defineProperty(this, 'listener', {
|
|
1042
|
+
value: new Listener,
|
|
1043
|
+
writable: false,
|
|
1044
|
+
configurable: false
|
|
1045
|
+
});
|
|
1046
|
+
for (const i in obj) {
|
|
1047
|
+
Object.defineProperty(this.container, i, {
|
|
1048
|
+
value: obj[i],
|
|
1049
|
+
configurable: true,
|
|
1050
|
+
writable: true,
|
|
1051
|
+
enumerable: true
|
|
1052
|
+
});
|
|
1053
|
+
this.listener.emitAdded(i, obj[i]);
|
|
1054
|
+
}
|
|
824
1055
|
}
|
|
825
|
-
|
|
826
|
-
|
|
1056
|
+
/**
|
|
1057
|
+
* Gets a value of a field
|
|
1058
|
+
* @param key {string}
|
|
1059
|
+
* @return {*}
|
|
1060
|
+
*/
|
|
1061
|
+
get(key) {
|
|
1062
|
+
return this.container[key];
|
|
827
1063
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1064
|
+
/**
|
|
1065
|
+
* Sets an object property value
|
|
1066
|
+
* @param key {string} property name
|
|
1067
|
+
* @param v {*} property value
|
|
1068
|
+
* @return {ObjectModel} a pointer to this
|
|
1069
|
+
*/
|
|
1070
|
+
set(key, v) {
|
|
1071
|
+
if (Reflect.has(this.container, key)) {
|
|
1072
|
+
this.listener.emitRemoved(key, this.container[key]);
|
|
1073
|
+
this.container[key] = v;
|
|
836
1074
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1075
|
+
else {
|
|
1076
|
+
Object.defineProperty(this.container, key, {
|
|
1077
|
+
value: v,
|
|
1078
|
+
configurable: true,
|
|
1079
|
+
writable: true,
|
|
1080
|
+
enumerable: true
|
|
842
1081
|
});
|
|
843
|
-
this.isEnabled = true;
|
|
844
1082
|
}
|
|
1083
|
+
this.listener.emitAdded(key, this.container[key]);
|
|
1084
|
+
return this;
|
|
845
1085
|
}
|
|
846
|
-
|
|
847
|
-
this.
|
|
1086
|
+
get values() {
|
|
1087
|
+
return this.container;
|
|
848
1088
|
}
|
|
849
|
-
|
|
850
|
-
|
|
1089
|
+
/**
|
|
1090
|
+
* Deletes an object property
|
|
1091
|
+
* @param key {string} property name
|
|
1092
|
+
*/
|
|
1093
|
+
delete(key) {
|
|
1094
|
+
if (this.container[key]) {
|
|
1095
|
+
this.listener.emitRemoved(key, this.container[key]);
|
|
1096
|
+
delete this.container[key];
|
|
1097
|
+
}
|
|
851
1098
|
}
|
|
852
|
-
|
|
853
|
-
this
|
|
1099
|
+
enableReactivity() {
|
|
1100
|
+
this.listener.enableReactivity();
|
|
854
1101
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
this.$onchange.clear();
|
|
1102
|
+
disableReactivity() {
|
|
1103
|
+
this.listener.disableReactivity();
|
|
858
1104
|
}
|
|
859
1105
|
}
|
|
860
1106
|
|
|
861
|
-
window.
|
|
1107
|
+
window.ObjectModel = ObjectModel;
|
|
862
1108
|
|
|
863
|
-
// ./lib/
|
|
1109
|
+
// ./lib/models/set-model.js
|
|
864
1110
|
/**
|
|
865
|
-
*
|
|
866
|
-
* @class
|
|
867
|
-
* @extends
|
|
868
|
-
* @
|
|
1111
|
+
* A Set based model
|
|
1112
|
+
* @class SetModel
|
|
1113
|
+
* @extends Set
|
|
1114
|
+
* @implements IModel
|
|
869
1115
|
*/
|
|
870
|
-
class
|
|
1116
|
+
class SetModel extends Set {
|
|
871
1117
|
/**
|
|
872
|
-
* Constructs a
|
|
873
|
-
* @param
|
|
874
|
-
* @param forwardOnly {boolean} ensure forward only synchronization
|
|
1118
|
+
* Constructs a set model based on a set
|
|
1119
|
+
* @param set {Set} input data
|
|
875
1120
|
*/
|
|
876
|
-
constructor(
|
|
877
|
-
super(
|
|
878
|
-
this
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
get $() {
|
|
887
|
-
// this is a ts bug
|
|
888
|
-
// eslint-disable-next-line
|
|
889
|
-
// @ts-ignore
|
|
890
|
-
return super.$;
|
|
891
|
-
}
|
|
892
|
-
set $(v) {
|
|
893
|
-
if (!this.$forwardOnly) {
|
|
894
|
-
this.$pointedValue.$ = v;
|
|
895
|
-
}
|
|
896
|
-
// this is a ts bug
|
|
897
|
-
// eslint-disable-next-line
|
|
898
|
-
// @ts-ignore
|
|
899
|
-
super.$ = v;
|
|
900
|
-
}
|
|
901
|
-
$enable() {
|
|
902
|
-
if (!this.isEnabled) {
|
|
903
|
-
this.isEnabled = true;
|
|
904
|
-
this.$pointedValue.$on(this.$handler);
|
|
905
|
-
this.$ = this.$pointedValue.$;
|
|
906
|
-
}
|
|
1121
|
+
constructor(set = []) {
|
|
1122
|
+
super();
|
|
1123
|
+
Object.defineProperty(this, 'listener', {
|
|
1124
|
+
value: new Listener,
|
|
1125
|
+
writable: false,
|
|
1126
|
+
configurable: false
|
|
1127
|
+
});
|
|
1128
|
+
set.forEach(item => {
|
|
1129
|
+
super.add(item);
|
|
1130
|
+
});
|
|
907
1131
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1132
|
+
/**
|
|
1133
|
+
* Calls Set.add and notify abut changes
|
|
1134
|
+
* @param value {*} value
|
|
1135
|
+
* @return {this} a pointer to this
|
|
1136
|
+
*/
|
|
1137
|
+
add(value) {
|
|
1138
|
+
if (!super.has(value)) {
|
|
1139
|
+
this.listener.emitAdded(value, value);
|
|
1140
|
+
super.add(value);
|
|
912
1141
|
}
|
|
1142
|
+
return this;
|
|
913
1143
|
}
|
|
914
|
-
$destroy() {
|
|
915
|
-
this.$disable();
|
|
916
|
-
super.$destroy();
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
window.Mirror = Mirror;
|
|
921
|
-
|
|
922
|
-
// ./lib/value/pointer.js
|
|
923
|
-
/**
|
|
924
|
-
* r/w pointer to a value
|
|
925
|
-
* @class Pointer
|
|
926
|
-
* @extends Mirror
|
|
927
|
-
*/
|
|
928
|
-
class Pointer extends Mirror {
|
|
929
1144
|
/**
|
|
930
|
-
*
|
|
931
|
-
* @param forwardOnly {boolean} forward only data flow
|
|
1145
|
+
* Calls Set.clear and notify abut changes
|
|
932
1146
|
*/
|
|
933
|
-
|
|
934
|
-
|
|
1147
|
+
clear() {
|
|
1148
|
+
this.forEach(item => {
|
|
1149
|
+
this.listener.emitRemoved(item, item);
|
|
1150
|
+
});
|
|
1151
|
+
super.clear();
|
|
935
1152
|
}
|
|
936
1153
|
/**
|
|
937
|
-
*
|
|
938
|
-
* @param value {
|
|
1154
|
+
* Calls Set.delete and notify abut changes
|
|
1155
|
+
* @param value {*}
|
|
1156
|
+
* @return {boolean} true if a value was deleted, otherwise false
|
|
939
1157
|
*/
|
|
940
|
-
|
|
941
|
-
if (
|
|
942
|
-
this
|
|
943
|
-
this.$pointedValue = value;
|
|
944
|
-
this.$enable();
|
|
1158
|
+
delete(value) {
|
|
1159
|
+
if (super.has(value)) {
|
|
1160
|
+
this.listener.emitRemoved(value, value);
|
|
945
1161
|
}
|
|
1162
|
+
return super.delete(value);
|
|
1163
|
+
}
|
|
1164
|
+
enableReactivity() {
|
|
1165
|
+
this.listener.enableReactivity();
|
|
1166
|
+
}
|
|
1167
|
+
disableReactivity() {
|
|
1168
|
+
this.listener.disableReactivity();
|
|
946
1169
|
}
|
|
947
1170
|
}
|
|
948
1171
|
|
|
949
|
-
window.
|
|
1172
|
+
window.SetModel = SetModel;
|
|
1173
|
+
|
|
1174
|
+
// ./lib/spec/html.js
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
// ./lib/spec/svg.js
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
// ./lib/spec/react.js
|
|
1183
|
+
|
|
1184
|
+
|
|
950
1185
|
|
|
951
1186
|
// ./lib/binding/binding.js
|
|
952
1187
|
/**
|
|
@@ -973,249 +1208,119 @@ class Binding extends Destroyable {
|
|
|
973
1208
|
* Just clear bindings
|
|
974
1209
|
*/
|
|
975
1210
|
$destroy() {
|
|
976
|
-
this.binding.$off(this.func);
|
|
977
|
-
super.$destroy();
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
window.Binding = Binding;
|
|
982
|
-
|
|
983
|
-
// ./lib/core/core.js
|
|
984
|
-
|
|
985
|
-
const currentStack = [];
|
|
986
|
-
function stack(node) {
|
|
987
|
-
currentStack.push(current);
|
|
988
|
-
current = node;
|
|
989
|
-
}
|
|
990
|
-
function unstack() {
|
|
991
|
-
current = currentStack.pop();
|
|
992
|
-
}
|
|
993
|
-
/**
|
|
994
|
-
* Private stuff of a reactive object
|
|
995
|
-
* @class ReactivePrivate
|
|
996
|
-
* @extends Destroyable
|
|
997
|
-
*/
|
|
998
|
-
class ReactivePrivate extends Destroyable {
|
|
999
|
-
constructor() {
|
|
1000
|
-
super();
|
|
1001
|
-
/**
|
|
1002
|
-
* A list of user-defined values
|
|
1003
|
-
* @type {Set}
|
|
1004
|
-
*/
|
|
1005
|
-
this.watch = new Set;
|
|
1006
|
-
/**
|
|
1007
|
-
* A list of user-defined bindings
|
|
1008
|
-
* @type {Set}
|
|
1009
|
-
*/
|
|
1010
|
-
this.bindings = new Set;
|
|
1011
|
-
/**
|
|
1012
|
-
* A list of user defined models
|
|
1013
|
-
*/
|
|
1014
|
-
this.models = new Set;
|
|
1015
|
-
/**
|
|
1016
|
-
* Reactivity switch state
|
|
1017
|
-
* @type {boolean}
|
|
1018
|
-
*/
|
|
1019
|
-
this.enabled = true;
|
|
1020
|
-
/**
|
|
1021
|
-
* The frozen state of object
|
|
1022
|
-
* @type {boolean}
|
|
1023
|
-
*/
|
|
1024
|
-
this.frozen = false;
|
|
1025
|
-
this.$seal();
|
|
1026
|
-
}
|
|
1027
|
-
$destroy() {
|
|
1028
|
-
this.watch.forEach(value => value.$destroy());
|
|
1029
|
-
this.watch.clear();
|
|
1030
|
-
this.bindings.forEach(binding => binding.$destroy());
|
|
1031
|
-
this.bindings.clear();
|
|
1032
|
-
this.models.forEach(model => model.disableReactivity());
|
|
1033
|
-
this.models.clear();
|
|
1034
|
-
this.freezeExpr && this.freezeExpr.$destroy();
|
|
1035
|
-
this.onDestroy && this.onDestroy();
|
|
1036
|
-
super.$destroy();
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
/**
|
|
1040
|
-
* A reactive object
|
|
1041
|
-
* @class Reactive
|
|
1042
|
-
* @extends Destroyable
|
|
1043
|
-
*/
|
|
1044
|
-
class Reactive extends Destroyable {
|
|
1045
|
-
constructor(input, $) {
|
|
1046
|
-
super();
|
|
1047
|
-
this.input = input;
|
|
1048
|
-
this.$ = $ || new ReactivePrivate;
|
|
1049
|
-
this.$seal();
|
|
1050
|
-
}
|
|
1051
|
-
/**
|
|
1052
|
-
* Get parent node
|
|
1053
|
-
*/
|
|
1054
|
-
get parent() {
|
|
1055
|
-
return this.$.parent;
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Create a reference
|
|
1059
|
-
* @param value {*} value to reference
|
|
1060
|
-
*/
|
|
1061
|
-
ref(value) {
|
|
1062
|
-
const $ = this.$;
|
|
1063
|
-
const ref = new Reference(value);
|
|
1064
|
-
$.watch.add(ref);
|
|
1065
|
-
return ref;
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* Create a mirror
|
|
1069
|
-
* @param value {IValue} value to mirror
|
|
1070
|
-
*/
|
|
1071
|
-
mirror(value) {
|
|
1072
|
-
const mirror = new Mirror(value, false);
|
|
1073
|
-
this.$.watch.add(mirror);
|
|
1074
|
-
return mirror;
|
|
1075
|
-
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Create a forward-only mirror
|
|
1078
|
-
* @param value {IValue} value to mirror
|
|
1079
|
-
*/
|
|
1080
|
-
forward(value) {
|
|
1081
|
-
const mirror = new Mirror(value, true);
|
|
1082
|
-
this.$.watch.add(mirror);
|
|
1083
|
-
return mirror;
|
|
1084
|
-
}
|
|
1085
|
-
/**
|
|
1086
|
-
* Creates a pointer
|
|
1087
|
-
* @param value {*} default value to point
|
|
1088
|
-
* @param forwardOnly {boolean} forward only sync
|
|
1089
|
-
*/
|
|
1090
|
-
point(value, forwardOnly = false) {
|
|
1091
|
-
const $ = this.$;
|
|
1092
|
-
const pointer = new Pointer(value, forwardOnly);
|
|
1093
|
-
$.watch.add(pointer);
|
|
1094
|
-
return pointer;
|
|
1095
|
-
}
|
|
1096
|
-
/**
|
|
1097
|
-
* Register a model
|
|
1098
|
-
* @param model
|
|
1099
|
-
*/
|
|
1100
|
-
register(model) {
|
|
1101
|
-
this.$.models.add(model);
|
|
1102
|
-
return model;
|
|
1103
|
-
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Creates a watcher
|
|
1106
|
-
* @param func {function} function to run on any argument change
|
|
1107
|
-
* @param values
|
|
1108
|
-
*/
|
|
1109
|
-
watch(func, ...values) {
|
|
1110
|
-
const $ = this.$;
|
|
1111
|
-
$.watch.add(new Expression(func, !this.$.frozen, ...values));
|
|
1112
|
-
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Creates a computed value
|
|
1115
|
-
* @param func {function} function to run on any argument change
|
|
1116
|
-
* @param values
|
|
1117
|
-
* @return {IValue} the created ivalue
|
|
1118
|
-
*/
|
|
1119
|
-
expr(func, ...values) {
|
|
1120
|
-
const res = new Expression(func, !this.$.frozen, ...values);
|
|
1121
|
-
const $ = this.$;
|
|
1122
|
-
$.watch.add(res);
|
|
1123
|
-
return res;
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* Enable reactivity of fields
|
|
1127
|
-
*/
|
|
1128
|
-
enable() {
|
|
1129
|
-
const $ = this.$;
|
|
1130
|
-
if (!$.enabled) {
|
|
1131
|
-
$.watch.forEach(watcher => {
|
|
1132
|
-
watcher.$enable();
|
|
1133
|
-
});
|
|
1134
|
-
$.models.forEach(model => {
|
|
1135
|
-
model.enableReactivity();
|
|
1136
|
-
});
|
|
1137
|
-
$.enabled = true;
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
/**
|
|
1141
|
-
* Disable reactivity of fields
|
|
1142
|
-
*/
|
|
1143
|
-
disable() {
|
|
1144
|
-
const $ = this.$;
|
|
1145
|
-
if ($.enabled) {
|
|
1146
|
-
$.watch.forEach(watcher => {
|
|
1147
|
-
watcher.$disable();
|
|
1148
|
-
});
|
|
1149
|
-
$.models.forEach(model => {
|
|
1150
|
-
model.disableReactivity();
|
|
1151
|
-
});
|
|
1152
|
-
$.enabled = false;
|
|
1153
|
-
}
|
|
1211
|
+
this.binding.$off(this.func);
|
|
1212
|
+
super.$destroy();
|
|
1154
1213
|
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
window.Binding = Binding;
|
|
1217
|
+
|
|
1218
|
+
// ./lib/binding/attribute.js
|
|
1219
|
+
/**
|
|
1220
|
+
* Represents an Attribute binding description
|
|
1221
|
+
* @class AttributeBinding
|
|
1222
|
+
* @extends Binding
|
|
1223
|
+
*/
|
|
1224
|
+
class AttributeBinding extends Binding {
|
|
1155
1225
|
/**
|
|
1156
|
-
*
|
|
1157
|
-
* @param
|
|
1158
|
-
* @param
|
|
1159
|
-
* @param
|
|
1226
|
+
* Constructs an attribute binding description
|
|
1227
|
+
* @param node {INode} the vasille node
|
|
1228
|
+
* @param name {String} the name of attribute
|
|
1229
|
+
* @param value {IValue} value to bind
|
|
1160
1230
|
*/
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
if (cond) {
|
|
1172
|
-
onOn === null || onOn === void 0 ? void 0 : onOn();
|
|
1173
|
-
this.enable();
|
|
1231
|
+
constructor(node, name, value) {
|
|
1232
|
+
super(value);
|
|
1233
|
+
this.init((value) => {
|
|
1234
|
+
if (value) {
|
|
1235
|
+
if (typeof value === 'boolean') {
|
|
1236
|
+
node.node.setAttribute(name, "");
|
|
1237
|
+
}
|
|
1238
|
+
else {
|
|
1239
|
+
node.node.setAttribute(name, `${value}`);
|
|
1240
|
+
}
|
|
1174
1241
|
}
|
|
1175
1242
|
else {
|
|
1176
|
-
|
|
1177
|
-
this.disable();
|
|
1243
|
+
node.node.removeAttribute(name);
|
|
1178
1244
|
}
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
}
|
|
1182
|
-
init() {
|
|
1183
|
-
this.applyOptions(this.input);
|
|
1184
|
-
return this.compose(this.input);
|
|
1185
|
-
}
|
|
1186
|
-
applyOptions(input) {
|
|
1187
|
-
// empty
|
|
1188
|
-
}
|
|
1189
|
-
applyOptionsNow() {
|
|
1190
|
-
this.applyOptions(this.input);
|
|
1191
|
-
}
|
|
1192
|
-
compose(input) {
|
|
1193
|
-
throw notOverwritten();
|
|
1194
|
-
}
|
|
1195
|
-
composeNow() {
|
|
1196
|
-
this.compose(this.input);
|
|
1245
|
+
});
|
|
1246
|
+
this.$seal();
|
|
1197
1247
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
window.AttributeBinding = AttributeBinding;
|
|
1251
|
+
|
|
1252
|
+
// ./lib/binding/class.js
|
|
1253
|
+
function addClass(node, cl) {
|
|
1254
|
+
node.node.classList.add(cl);
|
|
1255
|
+
}
|
|
1256
|
+
function removeClass(node, cl) {
|
|
1257
|
+
node.node.classList.remove(cl);
|
|
1258
|
+
}
|
|
1259
|
+
class StaticClassBinding extends Binding {
|
|
1260
|
+
constructor(node, name, value) {
|
|
1261
|
+
super(value);
|
|
1262
|
+
this.current = false;
|
|
1263
|
+
this.init((value) => {
|
|
1264
|
+
if (value !== this.current) {
|
|
1265
|
+
if (value) {
|
|
1266
|
+
addClass(node, name);
|
|
1267
|
+
}
|
|
1268
|
+
else {
|
|
1269
|
+
removeClass(node, name);
|
|
1270
|
+
}
|
|
1271
|
+
this.current = value;
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
this.$seal();
|
|
1206
1275
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1276
|
+
}
|
|
1277
|
+
class DynamicalClassBinding extends Binding {
|
|
1278
|
+
constructor(node, value) {
|
|
1279
|
+
super(value);
|
|
1280
|
+
this.current = "";
|
|
1281
|
+
this.init((value) => {
|
|
1282
|
+
if (this.current != value) {
|
|
1283
|
+
if (this.current.length) {
|
|
1284
|
+
removeClass(node, this.current);
|
|
1285
|
+
}
|
|
1286
|
+
if (value.length) {
|
|
1287
|
+
addClass(node, value);
|
|
1288
|
+
}
|
|
1289
|
+
this.current = value;
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
this.$seal();
|
|
1209
1293
|
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
window.StaticClassBinding = StaticClassBinding;
|
|
1297
|
+
window.DynamicalClassBinding = DynamicalClassBinding;
|
|
1298
|
+
|
|
1299
|
+
// ./lib/binding/style.js
|
|
1300
|
+
/**
|
|
1301
|
+
* Describes a style attribute binding
|
|
1302
|
+
* @class StyleBinding
|
|
1303
|
+
* @extends Binding
|
|
1304
|
+
*/
|
|
1305
|
+
class StyleBinding extends Binding {
|
|
1306
|
+
/**
|
|
1307
|
+
* Constructs a style binding attribute
|
|
1308
|
+
* @param node {INode} the vasille node
|
|
1309
|
+
* @param name {string} the name of style property
|
|
1310
|
+
* @param value {IValue} the value to bind
|
|
1311
|
+
*/
|
|
1312
|
+
constructor(node, name, value) {
|
|
1313
|
+
super(value);
|
|
1314
|
+
this.init((value) => {
|
|
1315
|
+
if (node.node instanceof HTMLElement) {
|
|
1316
|
+
node.node.style.setProperty(name, value);
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1319
|
+
this.$seal();
|
|
1214
1320
|
}
|
|
1215
1321
|
}
|
|
1216
1322
|
|
|
1217
|
-
window.
|
|
1218
|
-
window.Reactive = Reactive;
|
|
1323
|
+
window.StyleBinding = StyleBinding;
|
|
1219
1324
|
|
|
1220
1325
|
// ./lib/node/node.js
|
|
1221
1326
|
/**
|
|
@@ -1373,7 +1478,9 @@ class Fragment extends Reactive {
|
|
|
1373
1478
|
* @param input
|
|
1374
1479
|
* @param cb {function(Tag, *)} callback
|
|
1375
1480
|
*/
|
|
1376
|
-
tag(tagName, input, cb
|
|
1481
|
+
tag(tagName, input, cb
|
|
1482
|
+
// @ts-ignore
|
|
1483
|
+
) {
|
|
1377
1484
|
const $ = this.$;
|
|
1378
1485
|
const node = new Tag(input);
|
|
1379
1486
|
input.slot = cb || input.slot;
|
|
@@ -1381,6 +1488,7 @@ class Fragment extends Reactive {
|
|
|
1381
1488
|
node.init();
|
|
1382
1489
|
this.pushNode(node);
|
|
1383
1490
|
node.ready();
|
|
1491
|
+
// @ts-ignore
|
|
1384
1492
|
return node.node;
|
|
1385
1493
|
}
|
|
1386
1494
|
/**
|
|
@@ -2039,220 +2147,82 @@ class DebugPrivate extends FragmentPrivate {
|
|
|
2039
2147
|
this.bindings.add(new Expression((v) => {
|
|
2040
2148
|
this.node.replaceData(0, -1, v);
|
|
2041
2149
|
}, true, text));
|
|
2042
|
-
this.parent.appendNode(this.node);
|
|
2043
|
-
}
|
|
2044
|
-
/**
|
|
2045
|
-
* Clear node data
|
|
2046
|
-
*/
|
|
2047
|
-
$destroy() {
|
|
2048
|
-
this.node.remove();
|
|
2049
|
-
super.$destroy();
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
/**
|
|
2053
|
-
* Represents a debug node
|
|
2054
|
-
* @class DebugNode
|
|
2055
|
-
* @extends Fragment
|
|
2056
|
-
*/
|
|
2057
|
-
class DebugNode extends Fragment {
|
|
2058
|
-
constructor() {
|
|
2059
|
-
super({});
|
|
2060
|
-
/**
|
|
2061
|
-
* private data
|
|
2062
|
-
* @type {DebugNode}
|
|
2063
|
-
*/
|
|
2064
|
-
this.$ = new DebugPrivate();
|
|
2065
|
-
this.$seal();
|
|
2066
|
-
}
|
|
2067
|
-
preinit(app, parent, text) {
|
|
2068
|
-
const $ = this.$;
|
|
2069
|
-
if (!text) {
|
|
2070
|
-
throw internalError('wrong DebugNode::$preninit call');
|
|
2071
|
-
}
|
|
2072
|
-
$.preinitComment(app, parent, text);
|
|
2073
|
-
}
|
|
2074
|
-
/**
|
|
2075
|
-
* Runs garbage collector
|
|
2076
|
-
*/
|
|
2077
|
-
$destroy() {
|
|
2078
|
-
this.$.$destroy();
|
|
2079
|
-
super.$destroy();
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
|
|
2083
|
-
window.FragmentPrivate = FragmentPrivate;
|
|
2084
|
-
window.Fragment = Fragment;
|
|
2085
|
-
window.TextNodePrivate = TextNodePrivate;
|
|
2086
|
-
window.TextNode = TextNode;
|
|
2087
|
-
window.INodePrivate = INodePrivate;
|
|
2088
|
-
window.INode = INode;
|
|
2089
|
-
window.Tag = Tag;
|
|
2090
|
-
window.Extension = Extension;
|
|
2091
|
-
window.Component = Component;
|
|
2092
|
-
window.SwitchedNodePrivate = SwitchedNodePrivate;
|
|
2093
|
-
window.SwitchedNode = SwitchedNode;
|
|
2094
|
-
window.DebugPrivate = DebugPrivate;
|
|
2095
|
-
window.DebugNode = DebugNode;
|
|
2096
|
-
|
|
2097
|
-
// ./lib/node/app.js
|
|
2098
|
-
/**
|
|
2099
|
-
* Application Node
|
|
2100
|
-
* @class AppNode
|
|
2101
|
-
* @extends INode
|
|
2102
|
-
*/
|
|
2103
|
-
class AppNode extends INode {
|
|
2104
|
-
/**
|
|
2105
|
-
* @param input
|
|
2106
|
-
*/
|
|
2107
|
-
constructor(input) {
|
|
2108
|
-
super(input);
|
|
2109
|
-
this.debugUi = input.debugUi || false;
|
|
2110
|
-
this.$seal();
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
/**
|
|
2114
|
-
* Represents a Vasille.js application
|
|
2115
|
-
* @class App
|
|
2116
|
-
* @extends AppNode
|
|
2117
|
-
*/
|
|
2118
|
-
class App extends AppNode {
|
|
2119
|
-
/**
|
|
2120
|
-
* Constructs an app node
|
|
2121
|
-
* @param node {Element} The root of application
|
|
2122
|
-
* @param input
|
|
2123
|
-
*/
|
|
2124
|
-
constructor(node, input) {
|
|
2125
|
-
super(input);
|
|
2126
|
-
this.$.node = node;
|
|
2127
|
-
this.preinit(this, this);
|
|
2128
|
-
this.init();
|
|
2129
|
-
this.$seal();
|
|
2130
|
-
}
|
|
2131
|
-
appendNode(node) {
|
|
2132
|
-
this.$.node.appendChild(node);
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
class Portal extends AppNode {
|
|
2136
|
-
constructor(input) {
|
|
2137
|
-
super(input);
|
|
2138
|
-
this.$.node = input.node;
|
|
2139
|
-
this.$seal();
|
|
2140
|
-
}
|
|
2141
|
-
appendNode(node) {
|
|
2142
|
-
this.$.node.appendChild(node);
|
|
2150
|
+
this.parent.appendNode(this.node);
|
|
2143
2151
|
}
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
window.AppNode = AppNode;
|
|
2147
|
-
window.App = App;
|
|
2148
|
-
window.Portal = Portal;
|
|
2149
|
-
|
|
2150
|
-
// ./lib/binding/attribute.js
|
|
2151
|
-
/**
|
|
2152
|
-
* Represents an Attribute binding description
|
|
2153
|
-
* @class AttributeBinding
|
|
2154
|
-
* @extends Binding
|
|
2155
|
-
*/
|
|
2156
|
-
class AttributeBinding extends Binding {
|
|
2157
2152
|
/**
|
|
2158
|
-
*
|
|
2159
|
-
* @param node {INode} the vasille node
|
|
2160
|
-
* @param name {String} the name of attribute
|
|
2161
|
-
* @param value {IValue} value to bind
|
|
2153
|
+
* Clear node data
|
|
2162
2154
|
*/
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
if (value) {
|
|
2167
|
-
if (typeof value === 'boolean') {
|
|
2168
|
-
node.node.setAttribute(name, "");
|
|
2169
|
-
}
|
|
2170
|
-
else {
|
|
2171
|
-
node.node.setAttribute(name, `${value}`);
|
|
2172
|
-
}
|
|
2173
|
-
}
|
|
2174
|
-
else {
|
|
2175
|
-
node.node.removeAttribute(name);
|
|
2176
|
-
}
|
|
2177
|
-
});
|
|
2178
|
-
this.$seal();
|
|
2155
|
+
$destroy() {
|
|
2156
|
+
this.node.remove();
|
|
2157
|
+
super.$destroy();
|
|
2179
2158
|
}
|
|
2180
2159
|
}
|
|
2181
|
-
|
|
2182
|
-
window.AttributeBinding = AttributeBinding;
|
|
2183
|
-
|
|
2184
|
-
// ./lib/binding/style.js
|
|
2185
2160
|
/**
|
|
2186
|
-
*
|
|
2187
|
-
* @class
|
|
2188
|
-
* @extends
|
|
2161
|
+
* Represents a debug node
|
|
2162
|
+
* @class DebugNode
|
|
2163
|
+
* @extends Fragment
|
|
2189
2164
|
*/
|
|
2190
|
-
class
|
|
2165
|
+
class DebugNode extends Fragment {
|
|
2166
|
+
constructor() {
|
|
2167
|
+
super({});
|
|
2168
|
+
/**
|
|
2169
|
+
* private data
|
|
2170
|
+
* @type {DebugNode}
|
|
2171
|
+
*/
|
|
2172
|
+
this.$ = new DebugPrivate();
|
|
2173
|
+
this.$seal();
|
|
2174
|
+
}
|
|
2175
|
+
preinit(app, parent, text) {
|
|
2176
|
+
const $ = this.$;
|
|
2177
|
+
if (!text) {
|
|
2178
|
+
throw internalError('wrong DebugNode::$preninit call');
|
|
2179
|
+
}
|
|
2180
|
+
$.preinitComment(app, parent, text);
|
|
2181
|
+
}
|
|
2191
2182
|
/**
|
|
2192
|
-
*
|
|
2193
|
-
* @param node {INode} the vasille node
|
|
2194
|
-
* @param name {string} the name of style property
|
|
2195
|
-
* @param value {IValue} the value to bind
|
|
2183
|
+
* Runs garbage collector
|
|
2196
2184
|
*/
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
if (node.node instanceof HTMLElement) {
|
|
2201
|
-
node.node.style.setProperty(name, value);
|
|
2202
|
-
}
|
|
2203
|
-
});
|
|
2204
|
-
this.$seal();
|
|
2185
|
+
$destroy() {
|
|
2186
|
+
this.$.$destroy();
|
|
2187
|
+
super.$destroy();
|
|
2205
2188
|
}
|
|
2206
2189
|
}
|
|
2207
2190
|
|
|
2208
|
-
window.
|
|
2191
|
+
window.FragmentPrivate = FragmentPrivate;
|
|
2192
|
+
window.Fragment = Fragment;
|
|
2193
|
+
window.TextNodePrivate = TextNodePrivate;
|
|
2194
|
+
window.TextNode = TextNode;
|
|
2195
|
+
window.INodePrivate = INodePrivate;
|
|
2196
|
+
window.INode = INode;
|
|
2197
|
+
window.Tag = Tag;
|
|
2198
|
+
window.Extension = Extension;
|
|
2199
|
+
window.Component = Component;
|
|
2200
|
+
window.SwitchedNodePrivate = SwitchedNodePrivate;
|
|
2201
|
+
window.SwitchedNode = SwitchedNode;
|
|
2202
|
+
window.DebugPrivate = DebugPrivate;
|
|
2203
|
+
window.DebugNode = DebugNode;
|
|
2209
2204
|
|
|
2210
|
-
// ./lib/
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
removeClass(node, name);
|
|
2228
|
-
}
|
|
2229
|
-
this.current = value;
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
|
-
this.$seal();
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
class DynamicalClassBinding extends Binding {
|
|
2236
|
-
constructor(node, value) {
|
|
2237
|
-
super(value);
|
|
2238
|
-
this.current = "";
|
|
2239
|
-
this.init((value) => {
|
|
2240
|
-
if (this.current != value) {
|
|
2241
|
-
if (this.current.length) {
|
|
2242
|
-
removeClass(node, this.current);
|
|
2243
|
-
}
|
|
2244
|
-
if (value.length) {
|
|
2245
|
-
addClass(node, value);
|
|
2246
|
-
}
|
|
2247
|
-
this.current = value;
|
|
2248
|
-
}
|
|
2249
|
-
});
|
|
2250
|
-
this.$seal();
|
|
2205
|
+
// ./lib/node/watch.js
|
|
2206
|
+
/**
|
|
2207
|
+
* Watch Node
|
|
2208
|
+
* @class Watch
|
|
2209
|
+
* @extends Fragment
|
|
2210
|
+
*/
|
|
2211
|
+
class Watch extends Fragment {
|
|
2212
|
+
compose(input) {
|
|
2213
|
+
this.watch((value) => {
|
|
2214
|
+
this.children.forEach(child => {
|
|
2215
|
+
child.$destroy();
|
|
2216
|
+
});
|
|
2217
|
+
this.children.clear();
|
|
2218
|
+
this.lastChild = null;
|
|
2219
|
+
input.slot && input.slot(this, value);
|
|
2220
|
+
}, input.model);
|
|
2221
|
+
input.slot(this, input.model.$);
|
|
2251
2222
|
}
|
|
2252
2223
|
}
|
|
2253
2224
|
|
|
2254
|
-
window.
|
|
2255
|
-
window.DynamicalClassBinding = DynamicalClassBinding;
|
|
2225
|
+
window.Watch = Watch;
|
|
2256
2226
|
|
|
2257
2227
|
// ./lib/views/repeat-node.js
|
|
2258
2228
|
/**
|
|
@@ -2386,27 +2356,22 @@ class ArrayView extends BaseView {
|
|
|
2386
2356
|
|
|
2387
2357
|
window.ArrayView = ArrayView;
|
|
2388
2358
|
|
|
2389
|
-
// ./lib/
|
|
2359
|
+
// ./lib/views/map-view.js
|
|
2390
2360
|
/**
|
|
2391
|
-
*
|
|
2392
|
-
* @class
|
|
2393
|
-
* @extends
|
|
2361
|
+
* Create a children pack for each map value
|
|
2362
|
+
* @class MapView
|
|
2363
|
+
* @extends BaseView
|
|
2394
2364
|
*/
|
|
2395
|
-
class
|
|
2365
|
+
class MapView extends BaseView {
|
|
2396
2366
|
compose(input) {
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
this.children.clear();
|
|
2402
|
-
this.lastChild = null;
|
|
2403
|
-
input.slot && input.slot(this, value);
|
|
2404
|
-
}, input.model);
|
|
2405
|
-
input.slot(this, input.model.$);
|
|
2367
|
+
super.compose(input);
|
|
2368
|
+
input.model.forEach((value, key) => {
|
|
2369
|
+
this.createChild(input, key, value);
|
|
2370
|
+
});
|
|
2406
2371
|
}
|
|
2407
2372
|
}
|
|
2408
2373
|
|
|
2409
|
-
window.
|
|
2374
|
+
window.MapView = MapView;
|
|
2410
2375
|
|
|
2411
2376
|
// ./lib/views/object-view.js
|
|
2412
2377
|
/**
|
|
@@ -2427,23 +2392,6 @@ class ObjectView extends BaseView {
|
|
|
2427
2392
|
|
|
2428
2393
|
window.ObjectView = ObjectView;
|
|
2429
2394
|
|
|
2430
|
-
// ./lib/views/map-view.js
|
|
2431
|
-
/**
|
|
2432
|
-
* Create a children pack for each map value
|
|
2433
|
-
* @class MapView
|
|
2434
|
-
* @extends BaseView
|
|
2435
|
-
*/
|
|
2436
|
-
class MapView extends BaseView {
|
|
2437
|
-
compose(input) {
|
|
2438
|
-
super.compose(input);
|
|
2439
|
-
input.model.forEach((value, key) => {
|
|
2440
|
-
this.createChild(input, key, value);
|
|
2441
|
-
});
|
|
2442
|
-
}
|
|
2443
|
-
}
|
|
2444
|
-
|
|
2445
|
-
window.MapView = MapView;
|
|
2446
|
-
|
|
2447
2395
|
// ./lib/views/set-view.js
|
|
2448
2396
|
/**
|
|
2449
2397
|
* Create a children pack for each set value
|
|
@@ -2462,6 +2410,63 @@ class SetView extends BaseView {
|
|
|
2462
2410
|
|
|
2463
2411
|
window.SetView = SetView;
|
|
2464
2412
|
|
|
2413
|
+
// ./lib/index.js
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
|
|
2417
|
+
// ./lib/node/app.js
|
|
2418
|
+
/**
|
|
2419
|
+
* Application Node
|
|
2420
|
+
* @class AppNode
|
|
2421
|
+
* @extends INode
|
|
2422
|
+
*/
|
|
2423
|
+
class AppNode extends INode {
|
|
2424
|
+
/**
|
|
2425
|
+
* @param input
|
|
2426
|
+
*/
|
|
2427
|
+
constructor(input) {
|
|
2428
|
+
super(input);
|
|
2429
|
+
this.debugUi = input.debugUi || false;
|
|
2430
|
+
this.$seal();
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
/**
|
|
2434
|
+
* Represents a Vasille.js application
|
|
2435
|
+
* @class App
|
|
2436
|
+
* @extends AppNode
|
|
2437
|
+
*/
|
|
2438
|
+
class App extends AppNode {
|
|
2439
|
+
/**
|
|
2440
|
+
* Constructs an app node
|
|
2441
|
+
* @param node {Element} The root of application
|
|
2442
|
+
* @param input
|
|
2443
|
+
*/
|
|
2444
|
+
constructor(node, input) {
|
|
2445
|
+
super(input);
|
|
2446
|
+
this.$.node = node;
|
|
2447
|
+
this.preinit(this, this);
|
|
2448
|
+
this.init();
|
|
2449
|
+
this.$seal();
|
|
2450
|
+
}
|
|
2451
|
+
appendNode(node) {
|
|
2452
|
+
this.$.node.appendChild(node);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
class Portal extends AppNode {
|
|
2456
|
+
constructor(input) {
|
|
2457
|
+
super(input);
|
|
2458
|
+
this.$.node = input.node;
|
|
2459
|
+
this.$seal();
|
|
2460
|
+
}
|
|
2461
|
+
appendNode(node) {
|
|
2462
|
+
this.$.node.appendChild(node);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
window.AppNode = AppNode;
|
|
2467
|
+
window.App = App;
|
|
2468
|
+
window.Portal = Portal;
|
|
2469
|
+
|
|
2465
2470
|
// ./lib/functional/options.js
|
|
2466
2471
|
|
|
2467
2472
|
|