vasille 4.3.0 → 5.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 +47 -31
- package/lib/dev/components.js +82 -0
- package/lib/dev/core.js +15 -0
- package/lib/dev/index.js +8 -0
- package/lib/dev/inspectable.js +113 -0
- package/lib/dev/models.js +147 -0
- package/lib/dev/node.js +59 -0
- package/lib/dev/runner.js +141 -0
- package/lib/dev/state.js +194 -0
- package/lib/dev/views.js +62 -0
- package/lib/index.js +1 -2
- package/lib/node/app.js +1 -1
- package/lib/node/node.js +16 -34
- package/lib/runner/web/binding/class.js +2 -15
- package/lib/runner/web/runner.js +25 -53
- package/lib/value/expression.js +3 -2
- package/lib/views/repeat-node.js +6 -2
- package/package.json +7 -1
- package/types/dev/components.d.ts +20 -0
- package/types/dev/core.d.ts +8 -0
- package/types/dev/index.d.ts +8 -0
- package/types/dev/inspectable.d.ts +244 -0
- package/types/dev/models.d.ts +38 -0
- package/types/dev/node.d.ts +12 -0
- package/types/dev/runner.d.ts +37 -0
- package/types/dev/state.d.ts +53 -0
- package/types/dev/views.d.ts +22 -0
- package/types/index.d.ts +2 -3
- package/types/node/app.d.ts +8 -9
- package/types/node/node.d.ts +17 -34
- package/types/node/runner.d.ts +2 -5
- package/types/node/watch.d.ts +5 -6
- package/types/runner/web/runner.d.ts +21 -25
- package/types/value/expression.d.ts +2 -1
- package/types/views/array-view.d.ts +3 -2
- package/types/views/base-view.d.ts +4 -4
- package/types/views/map-view.d.ts +2 -1
- package/types/views/repeat-node.d.ts +8 -7
- package/types/views/set-view.d.ts +3 -3
- package/lib/value/pointer.js +0 -61
- package/types/value/pointer.d.ts +0 -46
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { IValue } from "../core/ivalue.js";
|
|
2
|
+
import { Runner, Tag, TextNode } from "../runner/web/runner.js";
|
|
3
|
+
import { provideId, toDevId, toDevIdOrValue, toDevObject, toDevValue, } from "./inspectable.js";
|
|
4
|
+
import { DevExpression, DevReference } from "./state.js";
|
|
5
|
+
export class PositionedText {
|
|
6
|
+
text;
|
|
7
|
+
position;
|
|
8
|
+
constructor(text, position) {
|
|
9
|
+
this.text = text;
|
|
10
|
+
this.position = position;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function positionedText(text, position) {
|
|
14
|
+
return new PositionedText(text, position);
|
|
15
|
+
}
|
|
16
|
+
export class DevTextNode extends TextNode {
|
|
17
|
+
id;
|
|
18
|
+
constructor(input, runner, usage, inspector) {
|
|
19
|
+
super(input, runner);
|
|
20
|
+
this.id = provideId();
|
|
21
|
+
inspector.createNode({
|
|
22
|
+
id: this.id,
|
|
23
|
+
time: Date.now(),
|
|
24
|
+
text: toDevIdOrValue(input.text),
|
|
25
|
+
position: usage,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
destroy() {
|
|
29
|
+
this.runner.inspector.destroy({ id: this.id, time: Date.now() });
|
|
30
|
+
super.destroy();
|
|
31
|
+
}
|
|
32
|
+
compose() {
|
|
33
|
+
super.compose();
|
|
34
|
+
Object.defineProperty(this.node, "vasille", { value: this.id, configurable: false, enumerable: false });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function remapObject(obj, transform) {
|
|
38
|
+
const r = {};
|
|
39
|
+
for (const key in obj) {
|
|
40
|
+
r[key] = transform(obj[key]);
|
|
41
|
+
}
|
|
42
|
+
return r;
|
|
43
|
+
}
|
|
44
|
+
export class DevTag extends Tag {
|
|
45
|
+
id;
|
|
46
|
+
constructor(options, runner, tagName, usage, inspector) {
|
|
47
|
+
super(options, runner, tagName);
|
|
48
|
+
this.id = provideId();
|
|
49
|
+
inspector.createTag({
|
|
50
|
+
id: this.id,
|
|
51
|
+
time: Date.now(),
|
|
52
|
+
tagName: tagName,
|
|
53
|
+
usage: usage,
|
|
54
|
+
callback: options.k && toDevIdOrValue(options.k),
|
|
55
|
+
attr: options.a && toDevObject(options.a),
|
|
56
|
+
class: options.c &&
|
|
57
|
+
options.c.map(item => {
|
|
58
|
+
if (typeof item === "string") {
|
|
59
|
+
return item;
|
|
60
|
+
}
|
|
61
|
+
if (item instanceof DevReference || item instanceof DevExpression) {
|
|
62
|
+
return item.id;
|
|
63
|
+
}
|
|
64
|
+
if (item instanceof IValue) {
|
|
65
|
+
return JSON.stringify(item.V);
|
|
66
|
+
}
|
|
67
|
+
return remapObject(item, toDevIdOrValue);
|
|
68
|
+
}),
|
|
69
|
+
style: options.s &&
|
|
70
|
+
remapObject(options.s, value => {
|
|
71
|
+
return typeof value === "number"
|
|
72
|
+
? `${value}px`
|
|
73
|
+
: value instanceof Array
|
|
74
|
+
? value.map(v => `${v}px`).join(" ")
|
|
75
|
+
: typeof value === "string"
|
|
76
|
+
? value
|
|
77
|
+
: (toDevId(value) ?? "");
|
|
78
|
+
}),
|
|
79
|
+
events: options.e && remapObject(options.e, toDevValue),
|
|
80
|
+
bind: options.b && remapObject(options.b, toDevIdOrValue),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
applyOptions(options) {
|
|
84
|
+
if (options.e) {
|
|
85
|
+
for (const [key, handler] of Object.entries(options.e)) {
|
|
86
|
+
if (handler instanceof Array) {
|
|
87
|
+
const userHandler = handler[0];
|
|
88
|
+
handler[0] = ev => {
|
|
89
|
+
this.runner.inspector.eventTrigger({
|
|
90
|
+
tagId: this.id,
|
|
91
|
+
eventName: key,
|
|
92
|
+
time: Date.now(),
|
|
93
|
+
});
|
|
94
|
+
userHandler(ev);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
options[key] = ev => {
|
|
99
|
+
this.runner.inspector.eventTrigger({
|
|
100
|
+
tagId: this.id,
|
|
101
|
+
eventName: key,
|
|
102
|
+
time: Date.now(),
|
|
103
|
+
});
|
|
104
|
+
handler(ev);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
super.applyOptions(options);
|
|
110
|
+
}
|
|
111
|
+
getNode() {
|
|
112
|
+
return this.node;
|
|
113
|
+
}
|
|
114
|
+
destroy() {
|
|
115
|
+
this.runner.inspector.destroy({ id: this.id, time: Date.now() });
|
|
116
|
+
super.destroy();
|
|
117
|
+
}
|
|
118
|
+
compose() {
|
|
119
|
+
super.compose();
|
|
120
|
+
Object.defineProperty(this.element, "vasille", { value: this.id, configurable: false, enumerable: false });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export class DevRunner extends Runner {
|
|
124
|
+
inspector;
|
|
125
|
+
constructor(document, inspector) {
|
|
126
|
+
super(document);
|
|
127
|
+
this.inspector = inspector;
|
|
128
|
+
}
|
|
129
|
+
textNode(text) {
|
|
130
|
+
if (text instanceof PositionedText) {
|
|
131
|
+
return new DevTextNode({ text: text.text }, this, text.position, this.inspector);
|
|
132
|
+
}
|
|
133
|
+
return new TextNode({ text: text }, this);
|
|
134
|
+
}
|
|
135
|
+
tag(tagName, input, cb) {
|
|
136
|
+
if (cb) {
|
|
137
|
+
input.l = cb;
|
|
138
|
+
}
|
|
139
|
+
return new DevTag(input, this, tagName, input.usage, this.inspector);
|
|
140
|
+
}
|
|
141
|
+
}
|
package/lib/dev/state.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { IValue } from "../core/ivalue.js";
|
|
2
|
+
import { provideId, toDevValue, } from "./inspectable.js";
|
|
3
|
+
export class DevIValue extends IValue {
|
|
4
|
+
}
|
|
5
|
+
export class BaseDevReference extends DevIValue {
|
|
6
|
+
state;
|
|
7
|
+
onChange;
|
|
8
|
+
constructor(value) {
|
|
9
|
+
super();
|
|
10
|
+
this.state = value;
|
|
11
|
+
this.onChange = new Set();
|
|
12
|
+
}
|
|
13
|
+
get V() {
|
|
14
|
+
return this.state;
|
|
15
|
+
}
|
|
16
|
+
set V(value) {
|
|
17
|
+
this.update(value);
|
|
18
|
+
}
|
|
19
|
+
update(value, position) {
|
|
20
|
+
if (this.state !== value) {
|
|
21
|
+
this.state = value;
|
|
22
|
+
this.shareUpdate(position);
|
|
23
|
+
this.onChange.forEach(handler => {
|
|
24
|
+
try {
|
|
25
|
+
handler(value, position);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
this.shareError(e, position);
|
|
29
|
+
reportError(e);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
on(handler) {
|
|
35
|
+
this.onChange.add(handler);
|
|
36
|
+
}
|
|
37
|
+
off(handler) {
|
|
38
|
+
this.onChange.delete(handler);
|
|
39
|
+
}
|
|
40
|
+
shareUpdate(position) {
|
|
41
|
+
void position;
|
|
42
|
+
}
|
|
43
|
+
shareError(error, position) {
|
|
44
|
+
void error;
|
|
45
|
+
void position;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class DevReference extends BaseDevReference {
|
|
49
|
+
id;
|
|
50
|
+
inspector;
|
|
51
|
+
constructor(value, declaration, inspector) {
|
|
52
|
+
super(value);
|
|
53
|
+
this.id = provideId();
|
|
54
|
+
this.inspector = inspector;
|
|
55
|
+
inspector?.newReference({
|
|
56
|
+
id: this.id,
|
|
57
|
+
declaration: declaration,
|
|
58
|
+
value: toDevValue(this.state),
|
|
59
|
+
time: Date.now(),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
destroy() {
|
|
63
|
+
this.shareDestroy();
|
|
64
|
+
}
|
|
65
|
+
shareUpdate(position) {
|
|
66
|
+
this.inspector?.updateReference({
|
|
67
|
+
id: this.id,
|
|
68
|
+
time: Date.now(),
|
|
69
|
+
position: position,
|
|
70
|
+
value: toDevValue(this.state),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
shareError(error, position) {
|
|
74
|
+
this.inspector?.reportReferenceError({
|
|
75
|
+
targetId: this.id,
|
|
76
|
+
time: Date.now(),
|
|
77
|
+
error: error instanceof Error ? (error.stack ?? error.message) : `${error}`,
|
|
78
|
+
position: position,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
shareDestroy() {
|
|
82
|
+
this.inspector?.destroy({ id: this.id, time: Date.now() });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export class ExpressionDevReference extends BaseDevReference {
|
|
86
|
+
id;
|
|
87
|
+
inspector;
|
|
88
|
+
constructor(id, value, inspector) {
|
|
89
|
+
super(value);
|
|
90
|
+
this.id = id;
|
|
91
|
+
this.inspector = inspector;
|
|
92
|
+
}
|
|
93
|
+
shareError(error, position) {
|
|
94
|
+
this.inspector?.reportReferenceError({
|
|
95
|
+
targetId: this.id,
|
|
96
|
+
time: Date.now(),
|
|
97
|
+
error: error instanceof Error ? (error.stack ?? error.message) : `${error}`,
|
|
98
|
+
position: position,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export class DevExpression extends IValue {
|
|
103
|
+
id;
|
|
104
|
+
declaration;
|
|
105
|
+
inspector;
|
|
106
|
+
values;
|
|
107
|
+
valuesCache;
|
|
108
|
+
linkedFunc = [];
|
|
109
|
+
sync;
|
|
110
|
+
constructor(func, values, ctx, depsCode, declaration, inspector, isWatch) {
|
|
111
|
+
super();
|
|
112
|
+
const id = provideId();
|
|
113
|
+
const handler = (i, value, position) => {
|
|
114
|
+
try {
|
|
115
|
+
this.valuesCache[i] = value;
|
|
116
|
+
const newValue = func.apply(this, this.valuesCache);
|
|
117
|
+
if (this.sync.V !== newValue || isWatch) {
|
|
118
|
+
this.sync.update(newValue, position);
|
|
119
|
+
inspector?.updateExpression({
|
|
120
|
+
id: id,
|
|
121
|
+
time: Date.now(),
|
|
122
|
+
position: position,
|
|
123
|
+
value: newValue,
|
|
124
|
+
deps: this.valuesCache.map(toDevValue),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
inspector?.reportExpressionCalculationError({
|
|
130
|
+
targetId: id,
|
|
131
|
+
time: Date.now(),
|
|
132
|
+
error: e instanceof Error ? (e.stack ?? e.message) : `${e}`,
|
|
133
|
+
position: position,
|
|
134
|
+
deps: this.valuesCache.map(toDevValue),
|
|
135
|
+
});
|
|
136
|
+
reportError(e);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
this.valuesCache = values.map(item => item?.V);
|
|
140
|
+
this.sync = new ExpressionDevReference(id, func.apply(this, this.valuesCache), inspector);
|
|
141
|
+
this.id = id;
|
|
142
|
+
this.declaration = declaration;
|
|
143
|
+
this.inspector = inspector;
|
|
144
|
+
let i = 0;
|
|
145
|
+
values.forEach(value => {
|
|
146
|
+
const updater = handler.bind(this, Number(i++));
|
|
147
|
+
this.linkedFunc.push(updater);
|
|
148
|
+
value?.on(updater);
|
|
149
|
+
});
|
|
150
|
+
this.values = values;
|
|
151
|
+
ctx?.bind(this);
|
|
152
|
+
inspector?.newExpression({
|
|
153
|
+
id: this.id,
|
|
154
|
+
declaration: this.declaration,
|
|
155
|
+
isWatch: isWatch,
|
|
156
|
+
value: toDevValue(this.sync.V),
|
|
157
|
+
deps: values.map((dep, index) => {
|
|
158
|
+
if (dep instanceof DevReference || dep instanceof DevExpression) {
|
|
159
|
+
return {
|
|
160
|
+
code: depsCode[index],
|
|
161
|
+
id: dep.id,
|
|
162
|
+
value: toDevValue(dep.V),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return depsCode[index];
|
|
166
|
+
}),
|
|
167
|
+
time: Date.now(),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
update(value, position) {
|
|
171
|
+
this.sync.update(value, position);
|
|
172
|
+
}
|
|
173
|
+
get V() {
|
|
174
|
+
return this.sync.V;
|
|
175
|
+
}
|
|
176
|
+
set V(v) {
|
|
177
|
+
this.sync.V = v;
|
|
178
|
+
}
|
|
179
|
+
on(handler) {
|
|
180
|
+
this.sync.on(handler);
|
|
181
|
+
}
|
|
182
|
+
off(handler) {
|
|
183
|
+
this.sync.off(handler);
|
|
184
|
+
}
|
|
185
|
+
destroy() {
|
|
186
|
+
this.inspector?.destroy({ id: this.id, time: Date.now() });
|
|
187
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
188
|
+
this.values[i]?.off(this.linkedFunc[i]);
|
|
189
|
+
}
|
|
190
|
+
this.values.splice(0);
|
|
191
|
+
this.valuesCache.splice(0);
|
|
192
|
+
this.linkedFunc.splice(0);
|
|
193
|
+
}
|
|
194
|
+
}
|
package/lib/dev/views.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ArrayView } from "../views/array-view.js";
|
|
2
|
+
import { MapView } from "../views/map-view.js";
|
|
3
|
+
import { SetView } from "../views/set-view.js";
|
|
4
|
+
import { provideId, toDevObject } from "./inspectable.js";
|
|
5
|
+
import { DevFragment } from "./node.js";
|
|
6
|
+
export class DevArrayView extends ArrayView {
|
|
7
|
+
id;
|
|
8
|
+
constructor(input, runner, usage) {
|
|
9
|
+
super(input, runner);
|
|
10
|
+
this.id = provideId();
|
|
11
|
+
runner.inspector.createComponent({
|
|
12
|
+
id: this.id,
|
|
13
|
+
name: "ArrayView",
|
|
14
|
+
props: toDevObject(input),
|
|
15
|
+
usage: usage,
|
|
16
|
+
time: Date.now(),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
newChild(id, item) {
|
|
20
|
+
const frag = new DevFragment(this.runner, null, null, "ArrayViewItem", { item });
|
|
21
|
+
this.runner.inspector?.setElementParent({ parent: this.id, child: frag.id });
|
|
22
|
+
return frag;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class DevSetView extends SetView {
|
|
26
|
+
id;
|
|
27
|
+
constructor(input, runner, usage) {
|
|
28
|
+
super(input, runner);
|
|
29
|
+
this.id = provideId();
|
|
30
|
+
runner.inspector.createComponent({
|
|
31
|
+
id: this.id,
|
|
32
|
+
name: "SetView",
|
|
33
|
+
props: toDevObject(input),
|
|
34
|
+
usage: usage,
|
|
35
|
+
time: Date.now(),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
newChild(_id, item) {
|
|
39
|
+
const frag = new DevFragment(this.runner, null, null, "SetViewItem", { item });
|
|
40
|
+
this.runner.inspector.setElementParent({ parent: this.id, child: frag.id });
|
|
41
|
+
return frag;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export class DevMapView extends MapView {
|
|
45
|
+
id;
|
|
46
|
+
constructor(input, runner, usage) {
|
|
47
|
+
super(input, runner);
|
|
48
|
+
this.id = provideId();
|
|
49
|
+
runner.inspector.createComponent({
|
|
50
|
+
id: this.id,
|
|
51
|
+
name: "MapView",
|
|
52
|
+
props: toDevObject(input),
|
|
53
|
+
usage: usage,
|
|
54
|
+
time: Date.now(),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
newChild(key, value) {
|
|
58
|
+
const frag = new DevFragment(this.runner, null, null, "MapViewItem", { key, value });
|
|
59
|
+
this.runner.inspector.setElementParent({ parent: this.id, child: frag.id });
|
|
60
|
+
return frag;
|
|
61
|
+
}
|
|
62
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -6,9 +6,8 @@ export { Listener } from "./models/listener.js";
|
|
|
6
6
|
export { MapModel } from "./models/map-model.js";
|
|
7
7
|
export { SetModel } from "./models/set-model.js";
|
|
8
8
|
export { App, Portal } from "./node/app.js";
|
|
9
|
-
export { Fragment, Tag, TextNode,
|
|
9
|
+
export { Fragment, Tag, TextNode, SwitchedNode } from "./node/node.js";
|
|
10
10
|
export { Expression } from "./value/expression.js";
|
|
11
|
-
export { Forward, Backward } from "./value/pointer.js";
|
|
12
11
|
export { Reference } from "./value/reference.js";
|
|
13
12
|
export { ArrayView } from "./views/array-view.js";
|
|
14
13
|
export { BaseView } from "./views/base-view.js";
|
package/lib/node/app.js
CHANGED
|
@@ -9,7 +9,7 @@ export class App extends Root {
|
|
|
9
9
|
/**
|
|
10
10
|
* Constructs an app node
|
|
11
11
|
* @param node {Element} The root of application
|
|
12
|
-
* @param runner {
|
|
12
|
+
* @param runner {IRunner} A adapter which execute DOM manipulation
|
|
13
13
|
*/
|
|
14
14
|
constructor(node, runner) {
|
|
15
15
|
super(runner);
|
package/lib/node/node.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Reactive } from "../core/core.js";
|
|
2
2
|
import { IValue } from "../core/ivalue.js";
|
|
3
|
-
import {
|
|
4
|
-
import { Reference } from "../value/reference.js";
|
|
3
|
+
import { safe } from "../functional/safety.js";
|
|
5
4
|
/**
|
|
6
5
|
* This class is symbolic
|
|
7
6
|
* @extends Reactive
|
|
@@ -17,7 +16,7 @@ export class Root extends Reactive {
|
|
|
17
16
|
constructor(runner) {
|
|
18
17
|
super();
|
|
19
18
|
this.runner = runner;
|
|
20
|
-
this.children =
|
|
19
|
+
this.children = new Set();
|
|
21
20
|
}
|
|
22
21
|
/**
|
|
23
22
|
* Pushes a node to children immediately
|
|
@@ -50,11 +49,6 @@ export class Root extends Reactive {
|
|
|
50
49
|
this.pushNode(node);
|
|
51
50
|
node.compose();
|
|
52
51
|
}
|
|
53
|
-
debug(text) {
|
|
54
|
-
const node = this.runner.debugNode(text);
|
|
55
|
-
this.pushNode(node);
|
|
56
|
-
node.compose();
|
|
57
|
-
}
|
|
58
52
|
/**
|
|
59
53
|
* Defines a tag element
|
|
60
54
|
* @param tagName {String} the tag name
|
|
@@ -229,7 +223,6 @@ export class Tag extends INode {
|
|
|
229
223
|
this.runner.appendChild(this.node, node);
|
|
230
224
|
}
|
|
231
225
|
}
|
|
232
|
-
const alwaysTrue = new Reference(true);
|
|
233
226
|
/**
|
|
234
227
|
* Defines a node which can switch its children conditionally
|
|
235
228
|
*/
|
|
@@ -255,11 +248,11 @@ export class SwitchedNode extends Fragment {
|
|
|
255
248
|
constructor(runner, cases, _default) {
|
|
256
249
|
super(runner);
|
|
257
250
|
if (_default) {
|
|
258
|
-
cases.push({ $case:
|
|
251
|
+
cases.push({ $case: 1, slot: _default });
|
|
259
252
|
}
|
|
260
253
|
this.cases = cases;
|
|
261
254
|
this.sync = () => {
|
|
262
|
-
let i = this.cases.findIndex(item => item.$case.V);
|
|
255
|
+
let i = this.cases.findIndex(item => (item.$case instanceof IValue ? item.$case.V : item.$case));
|
|
263
256
|
if (i === this.index) {
|
|
264
257
|
return;
|
|
265
258
|
}
|
|
@@ -269,19 +262,22 @@ export class SwitchedNode extends Fragment {
|
|
|
269
262
|
this.lastChild = undefined;
|
|
270
263
|
}
|
|
271
264
|
if (i !== -1) {
|
|
272
|
-
const node =
|
|
265
|
+
const node = this.newChild(i);
|
|
273
266
|
node.parent = this;
|
|
274
267
|
this.lastChild = node;
|
|
275
268
|
this.children.add(node);
|
|
276
269
|
this.index = i;
|
|
277
|
-
this.cases[i].slot(node);
|
|
270
|
+
safe(this.cases[i].slot)(node);
|
|
278
271
|
}
|
|
279
272
|
else {
|
|
280
273
|
this.index = -1;
|
|
281
274
|
}
|
|
282
275
|
};
|
|
283
276
|
cases.forEach(_case => {
|
|
284
|
-
_case.$case
|
|
277
|
+
const item = _case.$case;
|
|
278
|
+
if (item instanceof IValue) {
|
|
279
|
+
item.on(this.sync);
|
|
280
|
+
}
|
|
285
281
|
});
|
|
286
282
|
}
|
|
287
283
|
compose() {
|
|
@@ -289,29 +285,15 @@ export class SwitchedNode extends Fragment {
|
|
|
289
285
|
}
|
|
290
286
|
destroy() {
|
|
291
287
|
this.cases.forEach(c => {
|
|
292
|
-
c.$case
|
|
288
|
+
const item = c.$case;
|
|
289
|
+
if (item instanceof IValue) {
|
|
290
|
+
item.off(this.sync);
|
|
291
|
+
}
|
|
293
292
|
});
|
|
294
293
|
this.cases.splice(0);
|
|
295
294
|
super.destroy();
|
|
296
295
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
* Represents a debug node
|
|
300
|
-
* @class DebugNode
|
|
301
|
-
* @extends Fragment
|
|
302
|
-
*/
|
|
303
|
-
export class DebugNode extends Fragment {
|
|
304
|
-
handler = null;
|
|
305
|
-
data;
|
|
306
|
-
constructor(input, runner) {
|
|
307
|
-
super(runner);
|
|
308
|
-
this.data = input.text;
|
|
309
|
-
}
|
|
310
|
-
destroy() {
|
|
311
|
-
/* istanbul ignore else */
|
|
312
|
-
if (this.handler) {
|
|
313
|
-
this.data.off(this.handler);
|
|
314
|
-
}
|
|
315
|
-
super.destroy();
|
|
296
|
+
newChild(_index) {
|
|
297
|
+
return new Fragment(this.runner);
|
|
316
298
|
}
|
|
317
299
|
}
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import { Binding } from "./binding.js";
|
|
2
2
|
export function addClass(node, cl) {
|
|
3
|
-
|
|
4
|
-
node.element.className = [...node.element.className.split(" "), cl].filter(item => !!item).join(" ");
|
|
5
|
-
}
|
|
6
|
-
else {
|
|
7
|
-
node.element.classList.add(cl);
|
|
8
|
-
}
|
|
3
|
+
node.element.classList.add(cl);
|
|
9
4
|
}
|
|
10
5
|
export function removeClass(node, cl) {
|
|
11
|
-
|
|
12
|
-
node.element.className = node.element.className
|
|
13
|
-
.split(" ")
|
|
14
|
-
.filter(name => name !== cl)
|
|
15
|
-
.join(" ");
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
node.element.classList.remove(cl);
|
|
19
|
-
}
|
|
6
|
+
node.element.classList.remove(cl);
|
|
20
7
|
}
|
|
21
8
|
export class StaticClassBinding extends Binding {
|
|
22
9
|
current = false;
|