vasille 2.3.8 → 3.0.0
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 +122 -0
- package/lib/binding/attribute.js +4 -5
- package/lib/binding/binding.js +4 -5
- package/lib/binding/class.js +2 -4
- package/lib/binding/style.js +12 -4
- package/lib/core/config.js +3 -0
- package/lib/core/core.js +39 -177
- package/lib/core/destroyable.js +1 -36
- package/lib/core/ivalue.js +6 -49
- package/lib/functional/safety.js +7 -0
- package/lib/index.js +7 -8
- package/lib/models/array-model.js +40 -107
- package/lib/models/listener.js +16 -80
- package/lib/models/map-model.js +6 -13
- package/lib/models/object-model.js +6 -6
- package/lib/models/set-model.js +5 -12
- package/lib/node/app.js +8 -27
- package/lib/node/node.js +294 -524
- package/lib/node/watch.js +10 -8
- package/lib/tsconfig-build.tsbuildinfo +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/value/expression.js +16 -41
- package/lib/value/mirror.js +9 -23
- package/lib/value/pointer.js +64 -16
- package/lib/value/reference.js +24 -29
- package/lib/views/array-view.js +5 -6
- package/lib/views/base-view.js +14 -26
- package/lib/views/map-view.js +4 -5
- package/lib/views/repeat-node.js +17 -34
- package/lib/views/set-view.js +7 -5
- package/lib-node/binding/attribute.js +4 -5
- package/lib-node/binding/binding.js +4 -5
- package/lib-node/binding/class.js +2 -4
- package/lib-node/binding/style.js +13 -4
- package/lib-node/core/config.js +6 -0
- package/lib-node/core/core.js +39 -180
- package/lib-node/core/destroyable.js +1 -36
- package/lib-node/core/ivalue.js +7 -51
- package/lib-node/functional/safety.js +12 -0
- package/lib-node/index.js +7 -12
- package/lib-node/models/array-model.js +41 -107
- package/lib-node/models/listener.js +16 -80
- package/lib-node/models/map-model.js +6 -13
- package/lib-node/models/object-model.js +6 -6
- package/lib-node/models/set-model.js +5 -12
- package/lib-node/node/app.js +8 -28
- package/lib-node/node/node.js +294 -529
- package/lib-node/node/watch.js +10 -8
- package/lib-node/tsconfig-build-node.tsbuildinfo +1 -1
- package/lib-node/value/expression.js +16 -41
- package/lib-node/value/mirror.js +9 -23
- package/lib-node/value/pointer.js +66 -17
- package/lib-node/value/reference.js +24 -29
- package/lib-node/views/array-view.js +5 -6
- package/lib-node/views/base-view.js +14 -27
- package/lib-node/views/map-view.js +4 -5
- package/lib-node/views/repeat-node.js +17 -35
- package/lib-node/views/set-view.js +7 -5
- package/package.json +4 -4
- package/types/binding/attribute.d.ts +2 -2
- package/types/binding/binding.d.ts +1 -1
- package/types/binding/style.d.ts +3 -2
- package/types/core/config.d.ts +3 -0
- package/types/core/core.d.ts +18 -93
- package/types/core/destroyable.d.ts +11 -6
- package/types/core/ivalue.d.ts +7 -24
- package/types/functional/options.d.ts +7 -22
- package/types/functional/safety.d.ts +2 -0
- package/types/index.d.ts +8 -10
- package/types/models/array-model.d.ts +6 -55
- package/types/models/listener.d.ts +0 -26
- package/types/models/map-model.d.ts +3 -4
- package/types/models/model.d.ts +2 -9
- package/types/models/set-model.d.ts +1 -2
- package/types/node/app.d.ts +7 -25
- package/types/node/node.d.ts +105 -222
- package/types/node/watch.d.ts +4 -5
- package/types/spec/html.d.ts +231 -231
- package/types/spec/svg.d.ts +166 -166
- package/types/tsconfig-types.tsbuildinfo +1 -1
- package/types/value/expression.d.ts +5 -7
- package/types/value/mirror.d.ts +4 -6
- package/types/value/pointer.d.ts +26 -9
- package/types/value/reference.d.ts +6 -7
- package/types/views/array-view.d.ts +3 -3
- package/types/views/base-view.d.ts +15 -23
- package/types/views/map-view.d.ts +2 -2
- package/types/views/repeat-node.d.ts +9 -23
- package/types/views/set-view.d.ts +3 -2
- package/cdn/es2015.js +0 -2480
- package/flow-typed/vasille.js +0 -2613
package/lib/node/node.js
CHANGED
|
@@ -1,86 +1,25 @@
|
|
|
1
|
-
import { Reactive
|
|
1
|
+
import { Reactive } from "../core/core";
|
|
2
2
|
import { IValue } from "../core/ivalue";
|
|
3
3
|
import { Reference } from "../value/reference";
|
|
4
4
|
import { Expression } from "../value/expression";
|
|
5
5
|
import { AttributeBinding } from "../binding/attribute";
|
|
6
6
|
import { StaticClassBinding, DynamicalClassBinding } from "../binding/class";
|
|
7
|
-
import { StyleBinding } from "../binding/style";
|
|
7
|
+
import { stringifyStyleValue, StyleBinding } from "../binding/style";
|
|
8
8
|
import { internalError, userError } from "../core/errors";
|
|
9
|
-
|
|
10
|
-
* Represents a Vasille.js node
|
|
11
|
-
* @class FragmentPrivate
|
|
12
|
-
* @extends ReactivePrivate
|
|
13
|
-
*/
|
|
14
|
-
export class FragmentPrivate extends ReactivePrivate {
|
|
15
|
-
constructor() {
|
|
16
|
-
super();
|
|
17
|
-
this.$seal();
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Pre-initializes the base of a fragment
|
|
21
|
-
* @param app {App} the app node
|
|
22
|
-
* @param parent {Fragment} the parent node
|
|
23
|
-
*/
|
|
24
|
-
preinit(app, parent) {
|
|
25
|
-
this.app = app;
|
|
26
|
-
this.parent = parent;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Unlinks all bindings
|
|
30
|
-
*/
|
|
31
|
-
$destroy() {
|
|
32
|
-
this.next = null;
|
|
33
|
-
this.prev = null;
|
|
34
|
-
super.$destroy();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
9
|
+
import { config } from "../core/config";
|
|
37
10
|
/**
|
|
38
11
|
* This class is symbolic
|
|
39
12
|
* @extends Reactive
|
|
40
13
|
*/
|
|
41
|
-
export class
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* @param input
|
|
45
|
-
* @param $ {FragmentPrivate}
|
|
46
|
-
*/
|
|
47
|
-
constructor(input, $) {
|
|
48
|
-
super(input, $ || new FragmentPrivate);
|
|
14
|
+
export class Root extends Reactive {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
49
17
|
/**
|
|
50
18
|
* The children list
|
|
51
19
|
* @type Array
|
|
52
20
|
*/
|
|
53
|
-
this.children = new Set;
|
|
54
|
-
this.lastChild =
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Gets the app of node
|
|
58
|
-
*/
|
|
59
|
-
get app() {
|
|
60
|
-
return this.$.app;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Prepare to init fragment
|
|
64
|
-
* @param app {AppNode} app of node
|
|
65
|
-
* @param parent {Fragment} parent of node
|
|
66
|
-
* @param data {*} additional data
|
|
67
|
-
*/
|
|
68
|
-
preinit(app, parent, data) {
|
|
69
|
-
const $ = this.$;
|
|
70
|
-
$.preinit(app, parent);
|
|
71
|
-
}
|
|
72
|
-
init() {
|
|
73
|
-
const ret = super.init();
|
|
74
|
-
this.ready();
|
|
75
|
-
return ret;
|
|
76
|
-
}
|
|
77
|
-
compose(input) {
|
|
78
|
-
input.slot && input.slot(this);
|
|
79
|
-
return {};
|
|
80
|
-
}
|
|
81
|
-
/** To be overloaded: ready event handler */
|
|
82
|
-
ready() {
|
|
83
|
-
// empty
|
|
21
|
+
this.children = new Set();
|
|
22
|
+
this.lastChild = undefined;
|
|
84
23
|
}
|
|
85
24
|
/**
|
|
86
25
|
* Pushes a node to children immediately
|
|
@@ -88,15 +27,12 @@ export class Fragment extends Reactive {
|
|
|
88
27
|
* @protected
|
|
89
28
|
*/
|
|
90
29
|
pushNode(node) {
|
|
91
|
-
|
|
92
|
-
this.lastChild.$.next = node;
|
|
93
|
-
}
|
|
94
|
-
node.$.prev = this.lastChild;
|
|
30
|
+
node.parent = this;
|
|
95
31
|
this.lastChild = node;
|
|
96
32
|
this.children.add(node);
|
|
97
33
|
}
|
|
98
34
|
/**
|
|
99
|
-
* Find first node in element if so exists
|
|
35
|
+
* Find the first node in the element if so exists
|
|
100
36
|
* @return {?Element}
|
|
101
37
|
* @protected
|
|
102
38
|
*/
|
|
@@ -107,53 +43,21 @@ export class Fragment extends Reactive {
|
|
|
107
43
|
});
|
|
108
44
|
return first;
|
|
109
45
|
}
|
|
110
|
-
/**
|
|
111
|
-
* Append a node to end of element
|
|
112
|
-
* @param node {Node} node to insert
|
|
113
|
-
*/
|
|
114
|
-
appendNode(node) {
|
|
115
|
-
const $ = this.$;
|
|
116
|
-
if ($.next) {
|
|
117
|
-
$.next.insertAdjacent(node);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
$.parent.appendNode(node);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Insert a node as a sibling of this
|
|
125
|
-
* @param node {Node} node to insert
|
|
126
|
-
*/
|
|
127
|
-
insertAdjacent(node) {
|
|
128
|
-
const child = this.findFirstChild();
|
|
129
|
-
const $ = this.$;
|
|
130
|
-
if (child) {
|
|
131
|
-
child.parentElement.insertBefore(node, child);
|
|
132
|
-
}
|
|
133
|
-
else if ($.next) {
|
|
134
|
-
$.next.insertAdjacent(node);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
$.parent.appendNode(node);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
46
|
/**
|
|
141
47
|
* Defines a text fragment
|
|
142
48
|
* @param text {String | IValue} A text fragment string
|
|
143
49
|
* @param cb {function (TextNode)} Callback if previous is slot name
|
|
144
50
|
*/
|
|
145
|
-
text(text
|
|
146
|
-
const
|
|
147
|
-
const node = new TextNode();
|
|
148
|
-
node.preinit($.app, this, text);
|
|
51
|
+
text(text) {
|
|
52
|
+
const node = new TextNode({ text });
|
|
149
53
|
this.pushNode(node);
|
|
150
|
-
|
|
54
|
+
node.compose();
|
|
151
55
|
}
|
|
152
56
|
debug(text) {
|
|
153
|
-
if (
|
|
154
|
-
const node = new DebugNode();
|
|
155
|
-
node.preinit(this.$.app, this, text);
|
|
57
|
+
if (config.debugUi) {
|
|
58
|
+
const node = new DebugNode({ text });
|
|
156
59
|
this.pushNode(node);
|
|
60
|
+
node.compose();
|
|
157
61
|
}
|
|
158
62
|
}
|
|
159
63
|
/**
|
|
@@ -162,18 +66,11 @@ export class Fragment extends Reactive {
|
|
|
162
66
|
* @param input
|
|
163
67
|
* @param cb {function(Tag, *)} callback
|
|
164
68
|
*/
|
|
165
|
-
tag(tagName, input, cb
|
|
166
|
-
|
|
167
|
-
) {
|
|
168
|
-
const $ = this.$;
|
|
169
|
-
const node = new Tag(input);
|
|
69
|
+
tag(tagName, input, cb) {
|
|
70
|
+
const tag = new Tag(input, tagName);
|
|
170
71
|
input.slot = cb || input.slot;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.pushNode(node);
|
|
174
|
-
node.ready();
|
|
175
|
-
// @ts-expect-error
|
|
176
|
-
return node.node;
|
|
72
|
+
this.pushNode(tag);
|
|
73
|
+
tag.compose();
|
|
177
74
|
}
|
|
178
75
|
/**
|
|
179
76
|
* Defines a custom element
|
|
@@ -181,12 +78,9 @@ export class Fragment extends Reactive {
|
|
|
181
78
|
* @param callback {function($ : *)}
|
|
182
79
|
*/
|
|
183
80
|
create(node, callback) {
|
|
184
|
-
const $ = this.$;
|
|
185
|
-
node.$.parent = this;
|
|
186
|
-
node.preinit($.app, this);
|
|
187
|
-
node.input.slot = callback || node.input.slot;
|
|
188
81
|
this.pushNode(node);
|
|
189
|
-
|
|
82
|
+
node.compose();
|
|
83
|
+
callback === null || callback === void 0 ? void 0 : callback(node);
|
|
190
84
|
}
|
|
191
85
|
/**
|
|
192
86
|
* Defines an if node
|
|
@@ -196,18 +90,15 @@ export class Fragment extends Reactive {
|
|
|
196
90
|
*/
|
|
197
91
|
if(cond, cb) {
|
|
198
92
|
const node = new SwitchedNode();
|
|
199
|
-
node.preinit(this.$.app, this);
|
|
200
|
-
node.init();
|
|
201
93
|
this.pushNode(node);
|
|
202
94
|
node.addCase(this.case(cond, cb));
|
|
203
|
-
node.ready();
|
|
204
95
|
}
|
|
205
96
|
else(cb) {
|
|
206
97
|
if (this.lastChild instanceof SwitchedNode) {
|
|
207
98
|
this.lastChild.addCase(this.default(cb));
|
|
208
99
|
}
|
|
209
100
|
else {
|
|
210
|
-
throw userError(
|
|
101
|
+
throw userError("wrong `else` function use", "logic-error");
|
|
211
102
|
}
|
|
212
103
|
}
|
|
213
104
|
elif(cond, cb) {
|
|
@@ -215,7 +106,7 @@ export class Fragment extends Reactive {
|
|
|
215
106
|
this.lastChild.addCase(this.case(cond, cb));
|
|
216
107
|
}
|
|
217
108
|
else {
|
|
218
|
-
throw userError(
|
|
109
|
+
throw userError("wrong `elif` function use", "logic-error");
|
|
219
110
|
}
|
|
220
111
|
}
|
|
221
112
|
/**
|
|
@@ -234,139 +125,139 @@ export class Fragment extends Reactive {
|
|
|
234
125
|
default(cb) {
|
|
235
126
|
return { cond: trueIValue, cb };
|
|
236
127
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
128
|
+
destroy() {
|
|
129
|
+
this.children.forEach(child => child.destroy());
|
|
130
|
+
this.children.clear();
|
|
131
|
+
this.lastChild = undefined;
|
|
132
|
+
super.destroy();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export class Fragment extends Root {
|
|
136
|
+
constructor(input, name) {
|
|
137
|
+
super(input);
|
|
138
|
+
this.name = name;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Pushes a node to children immediately
|
|
142
|
+
* @param node {Fragment} A node to push
|
|
143
|
+
* @protected
|
|
144
|
+
*/
|
|
145
|
+
pushNode(node) {
|
|
146
|
+
if (this.lastChild) {
|
|
147
|
+
this.lastChild.next = node;
|
|
243
148
|
}
|
|
244
|
-
|
|
149
|
+
node.prev = this.lastChild;
|
|
150
|
+
super.pushNode(node);
|
|
245
151
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Append a node to end of element
|
|
154
|
+
* @param node {Node} node to insert
|
|
155
|
+
*/
|
|
156
|
+
appendNode(node) {
|
|
157
|
+
if (this.next) {
|
|
158
|
+
this.next.insertAdjacent(node);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
this.parent.appendNode(node);
|
|
162
|
+
}
|
|
251
163
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Insert a node as a sibling of this
|
|
166
|
+
* @param node {Node} node to insert
|
|
167
|
+
*/
|
|
168
|
+
insertAdjacent(node) {
|
|
169
|
+
const child = this.findFirstChild();
|
|
170
|
+
if (child) {
|
|
171
|
+
const parent = child.parentElement;
|
|
172
|
+
if (parent) {
|
|
173
|
+
child.parentElement.insertBefore(node, child);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (this.next) {
|
|
177
|
+
this.next.insertAdjacent(node);
|
|
256
178
|
}
|
|
257
|
-
|
|
258
|
-
|
|
179
|
+
else {
|
|
180
|
+
this.parent.appendNode(node);
|
|
259
181
|
}
|
|
260
182
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
183
|
+
compose() {
|
|
184
|
+
// do nothing
|
|
185
|
+
// to override it
|
|
186
|
+
}
|
|
187
|
+
insertBefore(node) {
|
|
188
|
+
node.prev = this.prev;
|
|
189
|
+
node.next = this;
|
|
190
|
+
if (this.prev) {
|
|
191
|
+
this.prev.next = node;
|
|
267
192
|
}
|
|
268
|
-
|
|
193
|
+
this.prev = node;
|
|
269
194
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
* @class TextNodePrivate
|
|
275
|
-
* @extends FragmentPrivate
|
|
276
|
-
*/
|
|
277
|
-
export class TextNodePrivate extends FragmentPrivate {
|
|
278
|
-
constructor() {
|
|
279
|
-
super();
|
|
280
|
-
this.$seal();
|
|
195
|
+
insertAfter(node) {
|
|
196
|
+
node.prev = this;
|
|
197
|
+
node.next = this.next;
|
|
198
|
+
this.next = node;
|
|
281
199
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
preinitText(app, parent, text) {
|
|
289
|
-
super.preinit(app, parent);
|
|
290
|
-
this.node = document.createTextNode(text instanceof IValue ? text.$ : text);
|
|
291
|
-
if (text instanceof IValue) {
|
|
292
|
-
this.bindings.add(new Expression((v) => {
|
|
293
|
-
this.node.replaceData(0, -1, v);
|
|
294
|
-
}, true, text));
|
|
200
|
+
remove() {
|
|
201
|
+
if (this.next) {
|
|
202
|
+
this.next.prev = this.prev;
|
|
203
|
+
}
|
|
204
|
+
if (this.prev) {
|
|
205
|
+
this.prev.next = this.next;
|
|
295
206
|
}
|
|
296
207
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
super
|
|
208
|
+
destroy() {
|
|
209
|
+
if (this.parent.lastChild === this) {
|
|
210
|
+
this.parent.lastChild = this.prev;
|
|
211
|
+
}
|
|
212
|
+
super.destroy();
|
|
302
213
|
}
|
|
303
214
|
}
|
|
215
|
+
const trueIValue = new Reference(true);
|
|
304
216
|
/**
|
|
305
217
|
* Represents a text node
|
|
306
218
|
* @class TextNode
|
|
307
219
|
* @extends Fragment
|
|
308
220
|
*/
|
|
309
221
|
export class TextNode extends Fragment {
|
|
310
|
-
constructor(
|
|
311
|
-
super(
|
|
312
|
-
this.$seal();
|
|
222
|
+
constructor(input) {
|
|
223
|
+
super(input, ":text");
|
|
313
224
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
225
|
+
compose() {
|
|
226
|
+
var _a, _b;
|
|
227
|
+
const text = this.input.text;
|
|
228
|
+
this.node = document.createTextNode((_b = (_a = (text instanceof IValue ? text.$ : text)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "");
|
|
229
|
+
if (text instanceof IValue) {
|
|
230
|
+
this.register(new Expression((v) => {
|
|
231
|
+
var _a;
|
|
232
|
+
this.node.replaceData(0, -1, (_a = v === null || v === void 0 ? void 0 : v.toString()) !== null && _a !== void 0 ? _a : "");
|
|
233
|
+
}, text));
|
|
318
234
|
}
|
|
319
|
-
|
|
320
|
-
$.parent.appendNode($.node);
|
|
235
|
+
this.parent.appendNode(this.node);
|
|
321
236
|
}
|
|
322
237
|
findFirstChild() {
|
|
323
|
-
return this
|
|
238
|
+
return this.node;
|
|
324
239
|
}
|
|
325
|
-
|
|
326
|
-
this
|
|
327
|
-
|
|
328
|
-
super.$destroy();
|
|
240
|
+
destroy() {
|
|
241
|
+
this.node.remove();
|
|
242
|
+
super.destroy();
|
|
329
243
|
}
|
|
330
244
|
}
|
|
331
245
|
/**
|
|
332
|
-
*
|
|
333
|
-
* @class
|
|
334
|
-
* @extends
|
|
246
|
+
* Vasille node which can manipulate an element node
|
|
247
|
+
* @class INode
|
|
248
|
+
* @extends Fragment
|
|
335
249
|
*/
|
|
336
|
-
export class
|
|
250
|
+
export class INode extends Fragment {
|
|
337
251
|
constructor() {
|
|
338
|
-
super();
|
|
252
|
+
super(...arguments);
|
|
339
253
|
/**
|
|
340
254
|
* Defines if node is unmounted
|
|
341
255
|
* @type {boolean}
|
|
342
256
|
*/
|
|
343
257
|
this.unmounted = false;
|
|
344
|
-
this.$seal();
|
|
345
|
-
}
|
|
346
|
-
$destroy() {
|
|
347
|
-
super.$destroy();
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Vasille node which can manipulate an element node
|
|
352
|
-
* @class INode
|
|
353
|
-
* @extends Fragment
|
|
354
|
-
*/
|
|
355
|
-
export class INode extends Fragment {
|
|
356
|
-
/**
|
|
357
|
-
* Constructs a base node
|
|
358
|
-
* @param input
|
|
359
|
-
* @param $ {?INodePrivate}
|
|
360
|
-
*/
|
|
361
|
-
constructor(input, $) {
|
|
362
|
-
super(input, $ || new INodePrivate);
|
|
363
|
-
this.$seal();
|
|
364
258
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
*/
|
|
368
|
-
get node() {
|
|
369
|
-
return this.$.node;
|
|
259
|
+
get element() {
|
|
260
|
+
return this.node;
|
|
370
261
|
}
|
|
371
262
|
/**
|
|
372
263
|
* Bind attribute value
|
|
@@ -374,9 +265,7 @@ export class INode extends Fragment {
|
|
|
374
265
|
* @param value {IValue} value
|
|
375
266
|
*/
|
|
376
267
|
attr(name, value) {
|
|
377
|
-
|
|
378
|
-
const attr = new AttributeBinding(this, name, value);
|
|
379
|
-
$.bindings.add(attr);
|
|
268
|
+
this.register(new AttributeBinding(this, name, value));
|
|
380
269
|
}
|
|
381
270
|
/**
|
|
382
271
|
* Set attribute value
|
|
@@ -384,13 +273,13 @@ export class INode extends Fragment {
|
|
|
384
273
|
* @param value {string} value
|
|
385
274
|
*/
|
|
386
275
|
setAttr(name, value) {
|
|
387
|
-
if (typeof value ===
|
|
276
|
+
if (typeof value === "boolean") {
|
|
388
277
|
if (value) {
|
|
389
|
-
this
|
|
278
|
+
this.node.setAttribute(name, "");
|
|
390
279
|
}
|
|
391
280
|
}
|
|
392
|
-
else {
|
|
393
|
-
this
|
|
281
|
+
else if (value !== null && value !== undefined) {
|
|
282
|
+
this.node.setAttribute(name, `${value}`);
|
|
394
283
|
}
|
|
395
284
|
return this;
|
|
396
285
|
}
|
|
@@ -399,25 +288,21 @@ export class INode extends Fragment {
|
|
|
399
288
|
* @param cl {string} Class name
|
|
400
289
|
*/
|
|
401
290
|
addClass(cl) {
|
|
402
|
-
this
|
|
403
|
-
return this;
|
|
291
|
+
this.node.classList.add(cl);
|
|
404
292
|
}
|
|
405
293
|
/**
|
|
406
294
|
* Adds some CSS classes
|
|
407
|
-
* @param
|
|
295
|
+
* @param cl {string} classes names
|
|
408
296
|
*/
|
|
409
|
-
|
|
410
|
-
this
|
|
411
|
-
return this;
|
|
297
|
+
removeClass(cl) {
|
|
298
|
+
this.node.classList.remove(cl);
|
|
412
299
|
}
|
|
413
300
|
/**
|
|
414
301
|
* Bind a CSS class
|
|
415
302
|
* @param className {IValue}
|
|
416
303
|
*/
|
|
417
304
|
bindClass(className) {
|
|
418
|
-
|
|
419
|
-
$.bindings.add(new DynamicalClassBinding(this, className));
|
|
420
|
-
return this;
|
|
305
|
+
this.register(new DynamicalClassBinding(this, className));
|
|
421
306
|
}
|
|
422
307
|
/**
|
|
423
308
|
* Bind a floating class name
|
|
@@ -425,8 +310,7 @@ export class INode extends Fragment {
|
|
|
425
310
|
* @param className {string} class name
|
|
426
311
|
*/
|
|
427
312
|
floatingClass(cond, className) {
|
|
428
|
-
this
|
|
429
|
-
return this;
|
|
313
|
+
this.register(new StaticClassBinding(this, className, cond));
|
|
430
314
|
}
|
|
431
315
|
/**
|
|
432
316
|
* Defines a style attribute
|
|
@@ -434,14 +318,12 @@ export class INode extends Fragment {
|
|
|
434
318
|
* @param value {IValue} value
|
|
435
319
|
*/
|
|
436
320
|
style(name, value) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
$.bindings.add(new StyleBinding(this, name, value));
|
|
321
|
+
if (this.node instanceof HTMLElement) {
|
|
322
|
+
this.register(new StyleBinding(this, name, value));
|
|
440
323
|
}
|
|
441
324
|
else {
|
|
442
|
-
throw userError(
|
|
325
|
+
throw userError("style can be applied to HTML elements only", "non-html-element");
|
|
443
326
|
}
|
|
444
|
-
return this;
|
|
445
327
|
}
|
|
446
328
|
/**
|
|
447
329
|
* Sets a style property value
|
|
@@ -449,8 +331,8 @@ export class INode extends Fragment {
|
|
|
449
331
|
* @param value {string} Property value
|
|
450
332
|
*/
|
|
451
333
|
setStyle(prop, value) {
|
|
452
|
-
if (this
|
|
453
|
-
this
|
|
334
|
+
if (this.node instanceof HTMLElement) {
|
|
335
|
+
this.node.style.setProperty(prop, stringifyStyleValue(value));
|
|
454
336
|
}
|
|
455
337
|
else {
|
|
456
338
|
throw userError("Style can be set for HTML elements only", "non-html-element");
|
|
@@ -464,31 +346,39 @@ export class INode extends Fragment {
|
|
|
464
346
|
* @param options {Object | boolean} addEventListener options
|
|
465
347
|
*/
|
|
466
348
|
listen(name, handler, options) {
|
|
467
|
-
this
|
|
468
|
-
return this;
|
|
349
|
+
this.node.addEventListener(name, handler, options);
|
|
469
350
|
}
|
|
470
351
|
insertAdjacent(node) {
|
|
471
|
-
this
|
|
352
|
+
const parent = this.node.parentNode;
|
|
353
|
+
if (parent) {
|
|
354
|
+
parent.insertBefore(node, this.node);
|
|
355
|
+
}
|
|
472
356
|
}
|
|
473
357
|
/**
|
|
474
358
|
* A v-show & ngShow alternative
|
|
475
359
|
* @param cond {IValue} show condition
|
|
476
360
|
*/
|
|
477
361
|
bindShow(cond) {
|
|
478
|
-
const
|
|
479
|
-
const node = $.node;
|
|
362
|
+
const node = this.node;
|
|
480
363
|
if (node instanceof HTMLElement) {
|
|
481
364
|
let lastDisplay = node.style.display;
|
|
482
365
|
const htmlNode = node;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
366
|
+
this.register(new Expression(cond => {
|
|
367
|
+
if (cond) {
|
|
368
|
+
if (htmlNode.style.display === "none") {
|
|
369
|
+
htmlNode.style.display = lastDisplay;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
if (htmlNode.style.display !== "none") {
|
|
374
|
+
lastDisplay = htmlNode.style.display;
|
|
375
|
+
htmlNode.style.display = "none";
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}, cond));
|
|
489
379
|
}
|
|
490
380
|
else {
|
|
491
|
-
throw userError(
|
|
381
|
+
throw userError("the element must be a html element", "bind-show");
|
|
492
382
|
}
|
|
493
383
|
}
|
|
494
384
|
/**
|
|
@@ -496,8 +386,7 @@ export class INode extends Fragment {
|
|
|
496
386
|
* @param value {IValue}
|
|
497
387
|
*/
|
|
498
388
|
bindDomApi(name, value) {
|
|
499
|
-
const
|
|
500
|
-
const node = $.node;
|
|
389
|
+
const node = this.node;
|
|
501
390
|
if (node instanceof HTMLElement) {
|
|
502
391
|
node[name] = value.$;
|
|
503
392
|
this.watch((v) => {
|
|
@@ -508,91 +397,71 @@ export class INode extends Fragment {
|
|
|
508
397
|
throw userError("HTML can be bound for HTML nodes only", "dom-error");
|
|
509
398
|
}
|
|
510
399
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
const value =
|
|
400
|
+
applyAttrs(attrs) {
|
|
401
|
+
for (const name in attrs) {
|
|
402
|
+
const value = attrs[name];
|
|
514
403
|
if (value instanceof IValue) {
|
|
515
404
|
this.attr(name, value);
|
|
516
405
|
}
|
|
517
406
|
else {
|
|
518
407
|
this.setAttr(name, value);
|
|
519
408
|
}
|
|
520
|
-
});
|
|
521
|
-
if (options.class) {
|
|
522
|
-
const handleClass = (name, value) => {
|
|
523
|
-
if (value instanceof IValue) {
|
|
524
|
-
this.floatingClass(value, name);
|
|
525
|
-
}
|
|
526
|
-
else if (value && name !== '$') {
|
|
527
|
-
this.addClass(name);
|
|
528
|
-
}
|
|
529
|
-
else {
|
|
530
|
-
this.removeClasse(name);
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
if (Array.isArray(options.class)) {
|
|
534
|
-
options.class.forEach(item => {
|
|
535
|
-
if (item instanceof IValue) {
|
|
536
|
-
this.bindClass(item);
|
|
537
|
-
}
|
|
538
|
-
else if (typeof item == "string") {
|
|
539
|
-
this.addClass(item);
|
|
540
|
-
}
|
|
541
|
-
else {
|
|
542
|
-
Reflect.ownKeys(item).forEach((name) => {
|
|
543
|
-
handleClass(name, item[name]);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
else {
|
|
549
|
-
options.class.$.forEach(item => {
|
|
550
|
-
this.bindClass(item);
|
|
551
|
-
});
|
|
552
|
-
Reflect.ownKeys(options.class).forEach((name) => {
|
|
553
|
-
handleClass(name, options.class[name]);
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
409
|
}
|
|
557
|
-
|
|
558
|
-
|
|
410
|
+
}
|
|
411
|
+
applyStyle(style) {
|
|
412
|
+
for (const name in style) {
|
|
413
|
+
const value = style[name];
|
|
559
414
|
if (value instanceof IValue) {
|
|
560
415
|
this.style(name, value);
|
|
561
416
|
}
|
|
562
|
-
else
|
|
417
|
+
else {
|
|
563
418
|
this.setStyle(name, value);
|
|
564
419
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
applyBind(bind) {
|
|
423
|
+
const inode = this.node;
|
|
424
|
+
for (const k in bind) {
|
|
425
|
+
const value = bind[k];
|
|
426
|
+
if (!(value instanceof IValue)) {
|
|
427
|
+
inode[k] = value;
|
|
428
|
+
return;
|
|
572
429
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
inode.oninput = () => value.$ = inode.value;
|
|
430
|
+
this.bindDomApi(k, value);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
applyOptions(options) {
|
|
434
|
+
options.attr && this.applyAttrs(options.attr);
|
|
435
|
+
options.class &&
|
|
436
|
+
options.class.forEach(item => {
|
|
437
|
+
if (item instanceof IValue) {
|
|
438
|
+
this.bindClass(item);
|
|
583
439
|
}
|
|
584
|
-
else if (
|
|
585
|
-
|
|
440
|
+
else if (typeof item == "string") {
|
|
441
|
+
this.addClass(item);
|
|
586
442
|
}
|
|
587
|
-
else
|
|
588
|
-
|
|
443
|
+
else {
|
|
444
|
+
for (const name in item) {
|
|
445
|
+
const value = item[name];
|
|
446
|
+
if (value instanceof IValue) {
|
|
447
|
+
this.floatingClass(value, name);
|
|
448
|
+
}
|
|
449
|
+
else if (value && name !== "$") {
|
|
450
|
+
this.addClass(name);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
this.removeClass(name);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
589
456
|
}
|
|
590
|
-
this.bindDomApi(k, value);
|
|
591
457
|
});
|
|
458
|
+
options.style && this.applyStyle(options.style);
|
|
459
|
+
if (options.events) {
|
|
460
|
+
for (const name of Object.keys(options.events)) {
|
|
461
|
+
this.listen(name, options.events[name]);
|
|
462
|
+
}
|
|
592
463
|
}
|
|
593
|
-
options
|
|
594
|
-
this.node[key] = options["v:set"][key];
|
|
595
|
-
});
|
|
464
|
+
options.bind && this.applyBind(options.bind);
|
|
596
465
|
}
|
|
597
466
|
}
|
|
598
467
|
/**
|
|
@@ -601,34 +470,31 @@ export class INode extends Fragment {
|
|
|
601
470
|
* @extends INode
|
|
602
471
|
*/
|
|
603
472
|
export class Tag extends INode {
|
|
604
|
-
constructor(input) {
|
|
605
|
-
super(input);
|
|
606
|
-
this.$seal();
|
|
473
|
+
constructor(input, tagName) {
|
|
474
|
+
super(input, tagName);
|
|
607
475
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
476
|
+
compose() {
|
|
477
|
+
var _a, _b, _c, _d;
|
|
478
|
+
if (!this.name) {
|
|
479
|
+
throw internalError("wrong Tag constructor call");
|
|
611
480
|
}
|
|
612
|
-
const node = document.createElement(
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
compose(input) {
|
|
619
|
-
input.slot && input.slot(this);
|
|
620
|
-
return {};
|
|
481
|
+
const node = document.createElement(this.name);
|
|
482
|
+
this.node = node;
|
|
483
|
+
this.applyOptions(this.input);
|
|
484
|
+
this.parent.appendNode(node);
|
|
485
|
+
(_b = (_a = this.input).callback) === null || _b === void 0 ? void 0 : _b.call(_a, this.node);
|
|
486
|
+
(_d = (_c = this.input).slot) === null || _d === void 0 ? void 0 : _d.call(_c, this);
|
|
621
487
|
}
|
|
622
488
|
findFirstChild() {
|
|
623
|
-
return this
|
|
489
|
+
return this.unmounted ? undefined : this.node;
|
|
624
490
|
}
|
|
625
491
|
insertAdjacent(node) {
|
|
626
|
-
if (this
|
|
627
|
-
if (this
|
|
628
|
-
this
|
|
492
|
+
if (this.unmounted) {
|
|
493
|
+
if (this.next) {
|
|
494
|
+
this.next.insertAdjacent(node);
|
|
629
495
|
}
|
|
630
496
|
else {
|
|
631
|
-
this
|
|
497
|
+
this.parent.appendNode(node);
|
|
632
498
|
}
|
|
633
499
|
}
|
|
634
500
|
else {
|
|
@@ -636,30 +502,37 @@ export class Tag extends INode {
|
|
|
636
502
|
}
|
|
637
503
|
}
|
|
638
504
|
appendNode(node) {
|
|
639
|
-
this
|
|
505
|
+
this.node.appendChild(node);
|
|
506
|
+
}
|
|
507
|
+
extent(options) {
|
|
508
|
+
this.applyOptions(options);
|
|
640
509
|
}
|
|
641
510
|
/**
|
|
642
511
|
* Mount/Unmount a node
|
|
643
512
|
* @param cond {IValue} show condition
|
|
644
513
|
*/
|
|
645
514
|
bindMount(cond) {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
this.insertAdjacent($.node);
|
|
653
|
-
$.unmounted = false;
|
|
515
|
+
this.register(new Expression(cond => {
|
|
516
|
+
if (cond) {
|
|
517
|
+
if (this.unmounted) {
|
|
518
|
+
this.insertAdjacent(this.node);
|
|
519
|
+
this.unmounted = false;
|
|
520
|
+
}
|
|
654
521
|
}
|
|
655
|
-
|
|
522
|
+
else {
|
|
523
|
+
if (!this.unmounted) {
|
|
524
|
+
this.node.remove();
|
|
525
|
+
this.unmounted = true;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}, cond));
|
|
656
529
|
}
|
|
657
530
|
/**
|
|
658
531
|
* Runs GC
|
|
659
532
|
*/
|
|
660
|
-
|
|
533
|
+
destroy() {
|
|
661
534
|
this.node.remove();
|
|
662
|
-
super
|
|
535
|
+
super.destroy();
|
|
663
536
|
}
|
|
664
537
|
}
|
|
665
538
|
/**
|
|
@@ -667,180 +540,80 @@ export class Tag extends INode {
|
|
|
667
540
|
* @class Extension
|
|
668
541
|
* @extends INode
|
|
669
542
|
*/
|
|
670
|
-
export class Extension extends
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
let
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
if (it && it instanceof INode) {
|
|
678
|
-
$.node = it.node;
|
|
543
|
+
export class Extension extends Fragment {
|
|
544
|
+
tag(tagName, input) {
|
|
545
|
+
var _a;
|
|
546
|
+
let parent = this.parent;
|
|
547
|
+
const target = tagName.toLowerCase();
|
|
548
|
+
while (parent instanceof Fragment && !(parent instanceof Tag)) {
|
|
549
|
+
parent = parent.parent;
|
|
679
550
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
551
|
+
if (parent instanceof Tag && parent.element.tagName.toLowerCase() === target) {
|
|
552
|
+
parent.extent(input);
|
|
553
|
+
(_a = input.slot) === null || _a === void 0 ? void 0 : _a.call(input, parent);
|
|
683
554
|
}
|
|
684
555
|
}
|
|
685
|
-
extend(options) {
|
|
686
|
-
this.applyOptions(options);
|
|
687
|
-
}
|
|
688
|
-
$destroy() {
|
|
689
|
-
super.$destroy();
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Node which cas has just a child
|
|
694
|
-
* @class Component
|
|
695
|
-
* @extends Extension
|
|
696
|
-
*/
|
|
697
|
-
export class Component extends Extension {
|
|
698
|
-
init() {
|
|
699
|
-
const ret = super.composeNow();
|
|
700
|
-
this.ready();
|
|
701
|
-
super.applyOptionsNow();
|
|
702
|
-
return ret;
|
|
703
|
-
}
|
|
704
|
-
ready() {
|
|
705
|
-
super.ready();
|
|
706
|
-
if (this.children.size !== 1) {
|
|
707
|
-
throw userError("Component must have a child only", "dom-error");
|
|
708
|
-
}
|
|
709
|
-
const child = this.lastChild;
|
|
710
|
-
if (child instanceof Tag || child instanceof Component) {
|
|
711
|
-
const $ = this.$;
|
|
712
|
-
$.node = child.node;
|
|
713
|
-
}
|
|
714
|
-
else {
|
|
715
|
-
throw userError("Component child must be Tag or Component", "dom-error");
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
preinit(app, parent) {
|
|
719
|
-
this.$.preinit(app, parent);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Private part of switch node
|
|
724
|
-
* @class SwitchedNodePrivate
|
|
725
|
-
* @extends INodePrivate
|
|
726
|
-
*/
|
|
727
|
-
export class SwitchedNodePrivate extends FragmentPrivate {
|
|
728
|
-
constructor() {
|
|
729
|
-
super();
|
|
730
|
-
/**
|
|
731
|
-
* Array of possible cases
|
|
732
|
-
* @type {Array<{cond : IValue<boolean>, cb : function(Fragment)}>}
|
|
733
|
-
*/
|
|
734
|
-
this.cases = [];
|
|
735
|
-
this.$seal();
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Runs GC
|
|
739
|
-
*/
|
|
740
|
-
$destroy() {
|
|
741
|
-
this.cases.forEach(c => {
|
|
742
|
-
delete c.cond;
|
|
743
|
-
delete c.cb;
|
|
744
|
-
});
|
|
745
|
-
this.cases.splice(0);
|
|
746
|
-
super.$destroy();
|
|
747
|
-
}
|
|
748
556
|
}
|
|
749
557
|
/**
|
|
750
|
-
* Defines a node
|
|
558
|
+
* Defines a node which can switch its children conditionally
|
|
751
559
|
*/
|
|
752
560
|
export class SwitchedNode extends Fragment {
|
|
753
561
|
/**
|
|
754
562
|
* Constructs a switch node and define a sync function
|
|
755
563
|
*/
|
|
756
564
|
constructor() {
|
|
757
|
-
super({},
|
|
758
|
-
|
|
759
|
-
|
|
565
|
+
super({}, ":switch");
|
|
566
|
+
/**
|
|
567
|
+
* Array of possible cases
|
|
568
|
+
* @type {Array<{cond : IValue<unknown>, cb : function(Fragment)}>}
|
|
569
|
+
*/
|
|
570
|
+
this.cases = [];
|
|
571
|
+
this.sync = () => {
|
|
760
572
|
let i = 0;
|
|
761
|
-
for (; i <
|
|
762
|
-
if (
|
|
573
|
+
for (; i < this.cases.length; i++) {
|
|
574
|
+
if (this.cases[i].cond.$) {
|
|
763
575
|
break;
|
|
764
576
|
}
|
|
765
577
|
}
|
|
766
|
-
if (i ===
|
|
578
|
+
if (i === this.index) {
|
|
767
579
|
return;
|
|
768
580
|
}
|
|
769
581
|
if (this.lastChild) {
|
|
770
|
-
this.lastChild
|
|
582
|
+
this.lastChild.destroy();
|
|
771
583
|
this.children.clear();
|
|
772
|
-
this.lastChild =
|
|
584
|
+
this.lastChild = undefined;
|
|
773
585
|
}
|
|
774
|
-
if (i !==
|
|
775
|
-
|
|
776
|
-
this.createChild(
|
|
586
|
+
if (i !== this.cases.length) {
|
|
587
|
+
this.index = i;
|
|
588
|
+
this.createChild(this.cases[i].cb);
|
|
777
589
|
}
|
|
778
590
|
else {
|
|
779
|
-
|
|
591
|
+
this.index = -1;
|
|
780
592
|
}
|
|
781
593
|
};
|
|
782
|
-
this.$seal();
|
|
783
594
|
}
|
|
784
595
|
addCase(case_) {
|
|
785
|
-
this
|
|
786
|
-
case_.cond
|
|
787
|
-
this
|
|
596
|
+
this.cases.push(case_);
|
|
597
|
+
case_.cond.on(this.sync);
|
|
598
|
+
this.sync();
|
|
788
599
|
}
|
|
789
600
|
/**
|
|
790
601
|
* Creates a child node
|
|
791
602
|
* @param cb {function(Fragment)} Call-back
|
|
792
603
|
*/
|
|
793
604
|
createChild(cb) {
|
|
794
|
-
const node = new Fragment({});
|
|
795
|
-
node.
|
|
796
|
-
node.init();
|
|
605
|
+
const node = new Fragment({}, ":case");
|
|
606
|
+
node.parent = this;
|
|
797
607
|
this.lastChild = node;
|
|
798
608
|
this.children.add(node);
|
|
799
609
|
cb(node);
|
|
800
610
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
c.cond.$on($.sync);
|
|
805
|
-
});
|
|
806
|
-
$.sync();
|
|
807
|
-
}
|
|
808
|
-
$destroy() {
|
|
809
|
-
const $ = this.$;
|
|
810
|
-
$.cases.forEach(c => {
|
|
811
|
-
c.cond.$off($.sync);
|
|
611
|
+
destroy() {
|
|
612
|
+
this.cases.forEach(c => {
|
|
613
|
+
c.cond.off(this.sync);
|
|
812
614
|
});
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* The private part of a text node
|
|
818
|
-
*/
|
|
819
|
-
export class DebugPrivate extends FragmentPrivate {
|
|
820
|
-
constructor() {
|
|
821
|
-
super();
|
|
822
|
-
this.$seal();
|
|
823
|
-
}
|
|
824
|
-
/**
|
|
825
|
-
* Pre-initializes a text node
|
|
826
|
-
* @param app {App} the app node
|
|
827
|
-
* @param parent {Fragment} parent node
|
|
828
|
-
* @param text {String | IValue}
|
|
829
|
-
*/
|
|
830
|
-
preinitComment(app, parent, text) {
|
|
831
|
-
super.preinit(app, parent);
|
|
832
|
-
this.node = document.createComment(text.$);
|
|
833
|
-
this.bindings.add(new Expression((v) => {
|
|
834
|
-
this.node.replaceData(0, -1, v);
|
|
835
|
-
}, true, text));
|
|
836
|
-
this.parent.appendNode(this.node);
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Clear node data
|
|
840
|
-
*/
|
|
841
|
-
$destroy() {
|
|
842
|
-
this.node.remove();
|
|
843
|
-
super.$destroy();
|
|
615
|
+
this.cases.splice(0);
|
|
616
|
+
super.destroy();
|
|
844
617
|
}
|
|
845
618
|
}
|
|
846
619
|
/**
|
|
@@ -849,27 +622,24 @@ export class DebugPrivate extends FragmentPrivate {
|
|
|
849
622
|
* @extends Fragment
|
|
850
623
|
*/
|
|
851
624
|
export class DebugNode extends Fragment {
|
|
852
|
-
constructor() {
|
|
853
|
-
super(
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
this
|
|
859
|
-
this
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
throw internalError('wrong DebugNode::$preninit call');
|
|
865
|
-
}
|
|
866
|
-
$.preinitComment(app, parent, text);
|
|
625
|
+
constructor(input) {
|
|
626
|
+
super(input, ":debug");
|
|
627
|
+
}
|
|
628
|
+
compose() {
|
|
629
|
+
var _a, _b;
|
|
630
|
+
const text = this.input.text;
|
|
631
|
+
this.node = document.createComment((_b = (_a = text.$) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "");
|
|
632
|
+
this.register(new Expression((v) => {
|
|
633
|
+
var _a;
|
|
634
|
+
this.node.replaceData(0, -1, (_a = v === null || v === void 0 ? void 0 : v.toString()) !== null && _a !== void 0 ? _a : "");
|
|
635
|
+
}, text));
|
|
636
|
+
this.parent.appendNode(this.node);
|
|
867
637
|
}
|
|
868
638
|
/**
|
|
869
639
|
* Runs garbage collector
|
|
870
640
|
*/
|
|
871
|
-
|
|
872
|
-
this
|
|
873
|
-
super
|
|
641
|
+
destroy() {
|
|
642
|
+
this.node.remove();
|
|
643
|
+
super.destroy();
|
|
874
644
|
}
|
|
875
645
|
}
|