@ryupold/vode 0.9.6 → 0.11.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/.github/workflows/npm-publish.yml +1 -5
- package/README.md +7 -0
- package/package.json +3 -2
- package/src/vode.ts +198 -212
- package/vode.mjs +941 -0
package/vode.mjs
ADDED
|
@@ -0,0 +1,941 @@
|
|
|
1
|
+
// src/vode.ts
|
|
2
|
+
var EmptyPatch = {};
|
|
3
|
+
function createState(state) {
|
|
4
|
+
return state;
|
|
5
|
+
}
|
|
6
|
+
function createPatch(p) {
|
|
7
|
+
return p;
|
|
8
|
+
}
|
|
9
|
+
function vode(tag, props, ...children) {
|
|
10
|
+
if (Array.isArray(tag)) {
|
|
11
|
+
return tag;
|
|
12
|
+
}
|
|
13
|
+
if (props) {
|
|
14
|
+
return [tag, props, ...children];
|
|
15
|
+
}
|
|
16
|
+
return [tag, ...children];
|
|
17
|
+
}
|
|
18
|
+
function app(container, initialState, dom, ...initialPatches) {
|
|
19
|
+
const _vode = {};
|
|
20
|
+
_vode.stats = { renderTime: 0, renderCount: 0, queueLengthBeforeRender: 0, queueLengthAfterRender: 0, liveEffectCount: 0, patchCount: 0, renderPatchCount: 0 };
|
|
21
|
+
Object.defineProperty(initialState, "patch", {
|
|
22
|
+
enumerable: false,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: false,
|
|
25
|
+
value: async (action) => {
|
|
26
|
+
if (!action || typeof action !== "function" && typeof action !== "object")
|
|
27
|
+
return;
|
|
28
|
+
_vode.stats.patchCount++;
|
|
29
|
+
if (action?.next) {
|
|
30
|
+
const generator = action;
|
|
31
|
+
_vode.stats.liveEffectCount++;
|
|
32
|
+
try {
|
|
33
|
+
let v = await generator.next();
|
|
34
|
+
while (v.done === false) {
|
|
35
|
+
_vode.stats.liveEffectCount++;
|
|
36
|
+
try {
|
|
37
|
+
_vode.patch(v.value);
|
|
38
|
+
v = await generator.next();
|
|
39
|
+
} finally {
|
|
40
|
+
_vode.stats.liveEffectCount--;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
_vode.patch(v.value);
|
|
44
|
+
} finally {
|
|
45
|
+
_vode.stats.liveEffectCount--;
|
|
46
|
+
}
|
|
47
|
+
} else if (action.then) {
|
|
48
|
+
_vode.stats.liveEffectCount++;
|
|
49
|
+
try {
|
|
50
|
+
const nextState = await action;
|
|
51
|
+
_vode.patch(nextState);
|
|
52
|
+
} finally {
|
|
53
|
+
_vode.stats.liveEffectCount--;
|
|
54
|
+
}
|
|
55
|
+
} else if (Array.isArray(action)) {
|
|
56
|
+
if (typeof action[0] === "function") {
|
|
57
|
+
if (action.length > 1)
|
|
58
|
+
_vode.patch(action[0](_vode.state, ...action.slice(1)));
|
|
59
|
+
else
|
|
60
|
+
_vode.patch(action[0](_vode.state));
|
|
61
|
+
} else {
|
|
62
|
+
_vode.stats.patchCount--;
|
|
63
|
+
}
|
|
64
|
+
} else if (typeof action === "function") {
|
|
65
|
+
_vode.patch(action(_vode.state));
|
|
66
|
+
} else {
|
|
67
|
+
_vode.stats.renderPatchCount++;
|
|
68
|
+
_vode.q.push(action);
|
|
69
|
+
if (!_vode.isRendering)
|
|
70
|
+
_vode.render();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
Object.defineProperty(_vode, "render", {
|
|
75
|
+
enumerable: false,
|
|
76
|
+
configurable: true,
|
|
77
|
+
writable: false,
|
|
78
|
+
value: () => requestAnimationFrame(() => {
|
|
79
|
+
if (_vode.isRendering || _vode.q.length === 0)
|
|
80
|
+
return;
|
|
81
|
+
_vode.isRendering = true;
|
|
82
|
+
const sw = Date.now();
|
|
83
|
+
try {
|
|
84
|
+
_vode.stats.queueLengthBeforeRender = _vode.q.length;
|
|
85
|
+
while (_vode.q.length > 0) {
|
|
86
|
+
const patch = _vode.q.shift();
|
|
87
|
+
if (patch === EmptyPatch)
|
|
88
|
+
continue;
|
|
89
|
+
mergeState(_vode.state, patch);
|
|
90
|
+
}
|
|
91
|
+
_vode.vode = render(_vode.state, _vode.patch, container, 0, _vode.vode, dom(_vode.state));
|
|
92
|
+
} finally {
|
|
93
|
+
_vode.isRendering = false;
|
|
94
|
+
_vode.stats.renderCount++;
|
|
95
|
+
_vode.stats.renderTime = Date.now() - sw;
|
|
96
|
+
_vode.stats.queueLengthAfterRender = _vode.q.length;
|
|
97
|
+
if (_vode.q.length > 0) {
|
|
98
|
+
_vode.render();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
});
|
|
103
|
+
_vode.patch = initialState.patch;
|
|
104
|
+
_vode.state = initialState;
|
|
105
|
+
_vode.q = [];
|
|
106
|
+
const root = container;
|
|
107
|
+
root._vode = _vode;
|
|
108
|
+
const initialVode = dom(initialState);
|
|
109
|
+
_vode.vode = initialVode;
|
|
110
|
+
_vode.vode = render(initialState, _vode.patch, container, 0, undefined, initialVode);
|
|
111
|
+
for (const effect of initialPatches) {
|
|
112
|
+
_vode.patch(effect);
|
|
113
|
+
}
|
|
114
|
+
return _vode.patch;
|
|
115
|
+
}
|
|
116
|
+
function memo(compare, componentOrProps) {
|
|
117
|
+
componentOrProps.__memo = compare;
|
|
118
|
+
return componentOrProps;
|
|
119
|
+
}
|
|
120
|
+
function tag(v) {
|
|
121
|
+
return v ? Array.isArray(v) ? v[0] : typeof v === "string" || v.nodeType === Node.TEXT_NODE ? "#text" : undefined : undefined;
|
|
122
|
+
}
|
|
123
|
+
function props(vode2) {
|
|
124
|
+
if (Array.isArray(vode2) && vode2.length > 1 && vode2[1] && !Array.isArray(vode2[1])) {
|
|
125
|
+
if (typeof vode2[1] === "object" && vode2[1].nodeType !== Node.TEXT_NODE) {
|
|
126
|
+
return vode2[1];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
function mergeClass(a, b) {
|
|
132
|
+
if (!a)
|
|
133
|
+
return b;
|
|
134
|
+
if (!b)
|
|
135
|
+
return a;
|
|
136
|
+
if (typeof a === "string" && typeof b === "string") {
|
|
137
|
+
const aSplit = a.split(" ");
|
|
138
|
+
const bSplit = b.split(" ");
|
|
139
|
+
const classSet = new Set([...aSplit, ...bSplit]);
|
|
140
|
+
return Array.from(classSet).join(" ").trim();
|
|
141
|
+
} else if (typeof a === "string" && Array.isArray(b)) {
|
|
142
|
+
const classSet = new Set([...b, ...a.split(" ")]);
|
|
143
|
+
return Array.from(classSet).join(" ").trim();
|
|
144
|
+
} else if (Array.isArray(a) && typeof b === "string") {
|
|
145
|
+
const classSet = new Set([...a, ...b.split(" ")]);
|
|
146
|
+
return Array.from(classSet).join(" ").trim();
|
|
147
|
+
} else if (Array.isArray(a) && Array.isArray(b)) {
|
|
148
|
+
const classSet = new Set([...a, ...b]);
|
|
149
|
+
return Array.from(classSet).join(" ").trim();
|
|
150
|
+
} else if (typeof a === "string" && typeof b === "object") {
|
|
151
|
+
return { [a]: true, ...b };
|
|
152
|
+
} else if (typeof a === "object" && typeof b === "string") {
|
|
153
|
+
return { ...a, [b]: true };
|
|
154
|
+
} else if (typeof a === "object" && typeof b === "object") {
|
|
155
|
+
return { ...a, ...b };
|
|
156
|
+
} else if (typeof a === "object" && Array.isArray(b)) {
|
|
157
|
+
const aa = { ...a };
|
|
158
|
+
for (const item of b) {
|
|
159
|
+
aa[item] = true;
|
|
160
|
+
}
|
|
161
|
+
return aa;
|
|
162
|
+
} else if (Array.isArray(a) && typeof b === "object") {
|
|
163
|
+
const aa = {};
|
|
164
|
+
for (const item of a) {
|
|
165
|
+
aa[item] = true;
|
|
166
|
+
}
|
|
167
|
+
for (const bKey of b.keys) {
|
|
168
|
+
aa[bKey] = b[bKey];
|
|
169
|
+
}
|
|
170
|
+
return b;
|
|
171
|
+
}
|
|
172
|
+
throw new Error(`cannot merge classes of ${a} (${typeof a}) and ${b} (${typeof b})`);
|
|
173
|
+
}
|
|
174
|
+
function children(vode2) {
|
|
175
|
+
const start = childrenStart(vode2);
|
|
176
|
+
if (start > 0) {
|
|
177
|
+
return vode2.slice(start);
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
function childCount(vode2) {
|
|
182
|
+
return vode2.length - childrenStart(vode2);
|
|
183
|
+
}
|
|
184
|
+
function child(vode2, index) {
|
|
185
|
+
return vode2[index + childrenStart(vode2)];
|
|
186
|
+
}
|
|
187
|
+
function childrenStart(vode2) {
|
|
188
|
+
return props(vode2) ? 2 : 1;
|
|
189
|
+
}
|
|
190
|
+
function merge(first, ...p) {
|
|
191
|
+
first = mergeState({}, first);
|
|
192
|
+
for (const pp of p) {
|
|
193
|
+
if (!pp)
|
|
194
|
+
continue;
|
|
195
|
+
first = mergeState(first, pp);
|
|
196
|
+
}
|
|
197
|
+
return first;
|
|
198
|
+
}
|
|
199
|
+
function mergeState(target, source) {
|
|
200
|
+
if (!source)
|
|
201
|
+
return target;
|
|
202
|
+
for (const key in source) {
|
|
203
|
+
const value = source[key];
|
|
204
|
+
if (value && typeof value === "object") {
|
|
205
|
+
const targetValue = target[key];
|
|
206
|
+
if (targetValue) {
|
|
207
|
+
if (Array.isArray(value)) {
|
|
208
|
+
target[key] = [...value];
|
|
209
|
+
} else if (value instanceof Date && targetValue !== value) {
|
|
210
|
+
target[key] = new Date(value);
|
|
211
|
+
} else {
|
|
212
|
+
if (Array.isArray(targetValue))
|
|
213
|
+
target[key] = mergeState({}, value);
|
|
214
|
+
else if (typeof targetValue === "object")
|
|
215
|
+
mergeState(target[key], value);
|
|
216
|
+
else
|
|
217
|
+
target[key] = mergeState({}, value);
|
|
218
|
+
}
|
|
219
|
+
} else if (Array.isArray(value)) {
|
|
220
|
+
target[key] = [...value];
|
|
221
|
+
} else if (value instanceof Date) {
|
|
222
|
+
target[key] = new Date(value);
|
|
223
|
+
} else {
|
|
224
|
+
target[key] = mergeState({}, value);
|
|
225
|
+
}
|
|
226
|
+
} else if (value === undefined) {
|
|
227
|
+
delete target[key];
|
|
228
|
+
} else {
|
|
229
|
+
target[key] = value;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return target;
|
|
233
|
+
}
|
|
234
|
+
function render(state, patch, parent, childIndex, oldVode, newVode, svg) {
|
|
235
|
+
newVode = remember(state, newVode, oldVode);
|
|
236
|
+
const isNoVode = !newVode || typeof newVode === "number" || typeof newVode === "boolean";
|
|
237
|
+
if (newVode === oldVode || !oldVode && isNoVode) {
|
|
238
|
+
return oldVode;
|
|
239
|
+
}
|
|
240
|
+
const oldIsText = oldVode?.nodeType === Node.TEXT_NODE;
|
|
241
|
+
const oldNode = oldIsText ? oldVode : oldVode?.node;
|
|
242
|
+
if (isNoVode) {
|
|
243
|
+
oldNode?.onUnmount && patch(oldNode.onUnmount(oldNode));
|
|
244
|
+
oldNode?.remove();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const isText = !isNoVode && isTextVode(newVode);
|
|
248
|
+
const isNode = !isNoVode && isNaturalVode(newVode);
|
|
249
|
+
const alreadyAttached = !!newVode && typeof newVode !== "string" && !!(newVode?.node || newVode?.nodeType === Node.TEXT_NODE);
|
|
250
|
+
if (!isText && !isNode && !alreadyAttached && !oldVode) {
|
|
251
|
+
throw new Error("Invalid vode: " + typeof newVode + " " + JSON.stringify(newVode));
|
|
252
|
+
} else if (alreadyAttached && isText) {
|
|
253
|
+
newVode = newVode.wholeText;
|
|
254
|
+
} else if (alreadyAttached && isNode) {
|
|
255
|
+
newVode = [...newVode];
|
|
256
|
+
}
|
|
257
|
+
if (oldIsText && isText) {
|
|
258
|
+
if (oldNode.nodeValue !== newVode) {
|
|
259
|
+
oldNode.nodeValue = newVode;
|
|
260
|
+
}
|
|
261
|
+
return oldVode;
|
|
262
|
+
}
|
|
263
|
+
if (isText && (!oldNode || !oldIsText)) {
|
|
264
|
+
const text = document.createTextNode(newVode);
|
|
265
|
+
if (oldNode) {
|
|
266
|
+
oldNode.onUnmount && patch(oldNode.onUnmount(oldNode));
|
|
267
|
+
oldNode.replaceWith(text);
|
|
268
|
+
} else {
|
|
269
|
+
if (parent.childNodes[childIndex]) {
|
|
270
|
+
parent.insertBefore(text, parent.childNodes[childIndex]);
|
|
271
|
+
} else {
|
|
272
|
+
parent.appendChild(text);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return text;
|
|
276
|
+
}
|
|
277
|
+
if (isNode && (!oldNode || oldIsText || oldVode[0] !== newVode[0])) {
|
|
278
|
+
svg = svg || newVode[0] === "svg";
|
|
279
|
+
const newNode = svg ? document.createElementNS("http://www.w3.org/2000/svg", newVode[0]) : document.createElement(newVode[0]);
|
|
280
|
+
newVode.node = newNode;
|
|
281
|
+
const newvode = newVode;
|
|
282
|
+
if (1 in newvode) {
|
|
283
|
+
newvode[1] = remember(state, newvode[1], undefined);
|
|
284
|
+
}
|
|
285
|
+
const properties = props(newVode);
|
|
286
|
+
patchProperties(patch, newNode, undefined, properties, svg);
|
|
287
|
+
if (oldNode) {
|
|
288
|
+
oldNode.onUnmount && patch(oldNode.onUnmount(oldNode));
|
|
289
|
+
oldNode.replaceWith(newNode);
|
|
290
|
+
} else {
|
|
291
|
+
if (parent.childNodes[childIndex]) {
|
|
292
|
+
parent.insertBefore(newNode, parent.childNodes[childIndex]);
|
|
293
|
+
} else {
|
|
294
|
+
parent.appendChild(newNode);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const newChildren = children(newVode);
|
|
298
|
+
if (newChildren) {
|
|
299
|
+
for (let i = 0;i < newChildren.length; i++) {
|
|
300
|
+
const child2 = newChildren[i];
|
|
301
|
+
const attached = render(state, patch, newNode, i, undefined, child2, svg);
|
|
302
|
+
newVode[properties ? i + 2 : i + 1] = attached;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
newNode.onMount && patch(newNode.onMount(newNode));
|
|
306
|
+
return newVode;
|
|
307
|
+
}
|
|
308
|
+
if (!oldIsText && isNode && oldVode[0] === newVode[0]) {
|
|
309
|
+
svg = svg || newVode[0] === "svg";
|
|
310
|
+
newVode.node = oldNode;
|
|
311
|
+
const newvode = newVode;
|
|
312
|
+
const oldvode = oldVode;
|
|
313
|
+
let hasProps = false;
|
|
314
|
+
if (newvode[1]?.__memo) {
|
|
315
|
+
const prev = newvode[1];
|
|
316
|
+
newvode[1] = remember(state, newvode[1], oldvode[1]);
|
|
317
|
+
if (prev !== newvode[1]) {
|
|
318
|
+
const properties = props(newVode);
|
|
319
|
+
patchProperties(patch, oldNode, props(oldVode), properties, svg);
|
|
320
|
+
hasProps = !!properties;
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
const properties = props(newVode);
|
|
324
|
+
patchProperties(patch, oldNode, props(oldVode), properties, svg);
|
|
325
|
+
hasProps = !!properties;
|
|
326
|
+
}
|
|
327
|
+
const newKids = children(newVode);
|
|
328
|
+
const oldKids = children(oldVode);
|
|
329
|
+
if (newKids) {
|
|
330
|
+
for (let i = 0;i < newKids.length; i++) {
|
|
331
|
+
const child2 = newKids[i];
|
|
332
|
+
const oldChild = oldKids && oldKids[i];
|
|
333
|
+
const attached = render(state, patch, oldNode, i, oldChild, child2, svg);
|
|
334
|
+
if (attached) {
|
|
335
|
+
newVode[hasProps ? i + 2 : i + 1] = attached;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
for (let i = newKids.length;oldKids && i < oldKids.length; i++) {
|
|
339
|
+
if (oldKids[i]?.node)
|
|
340
|
+
oldKids[i].node.remove();
|
|
341
|
+
else if (oldKids[i]?.nodeType === Node.TEXT_NODE)
|
|
342
|
+
oldKids[i].remove();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
for (let i = newKids?.length || 0;i < oldKids?.length; i++) {
|
|
346
|
+
if (oldKids[i]?.node)
|
|
347
|
+
oldKids[i].node.remove();
|
|
348
|
+
else if (oldKids[i]?.nodeType === Node.TEXT_NODE)
|
|
349
|
+
oldKids[i].remove();
|
|
350
|
+
}
|
|
351
|
+
return newVode;
|
|
352
|
+
}
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
function isNaturalVode(x) {
|
|
356
|
+
return Array.isArray(x) && x.length > 0 && typeof x[0] === "string";
|
|
357
|
+
}
|
|
358
|
+
function isTextVode(x) {
|
|
359
|
+
return typeof x === "string" || x?.nodeType === Node.TEXT_NODE;
|
|
360
|
+
}
|
|
361
|
+
function remember(state, present, past) {
|
|
362
|
+
if (typeof present !== "function")
|
|
363
|
+
return present;
|
|
364
|
+
const presentMemo = present?.__memo;
|
|
365
|
+
const pastMemo = past?.__memo;
|
|
366
|
+
if (Array.isArray(presentMemo) && Array.isArray(pastMemo) && presentMemo.length === pastMemo.length) {
|
|
367
|
+
let same = true;
|
|
368
|
+
for (let i = 0;i < presentMemo.length; i++) {
|
|
369
|
+
if (presentMemo[i] !== pastMemo[i]) {
|
|
370
|
+
same = false;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (same)
|
|
375
|
+
return past;
|
|
376
|
+
}
|
|
377
|
+
const newRender = unwrap(present, state);
|
|
378
|
+
if (typeof newRender === "object") {
|
|
379
|
+
newRender.__memo = present?.__memo;
|
|
380
|
+
}
|
|
381
|
+
return newRender;
|
|
382
|
+
}
|
|
383
|
+
function unwrap(c, s) {
|
|
384
|
+
if (typeof c === "function") {
|
|
385
|
+
return unwrap(c(s), s);
|
|
386
|
+
} else {
|
|
387
|
+
return c;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function patchProperties(patch, node, oldProps, newProps, isSvg) {
|
|
391
|
+
if (!newProps && !oldProps)
|
|
392
|
+
return;
|
|
393
|
+
if (!oldProps) {
|
|
394
|
+
for (const key in newProps) {
|
|
395
|
+
const newValue = newProps[key];
|
|
396
|
+
newProps[key] = patchProperty(patch, node, key, undefined, newValue, isSvg);
|
|
397
|
+
}
|
|
398
|
+
} else if (newProps) {
|
|
399
|
+
const combinedKeys = new Set([...Object.keys(oldProps), ...Object.keys(newProps)]);
|
|
400
|
+
for (const key of combinedKeys) {
|
|
401
|
+
const oldValue = oldProps[key];
|
|
402
|
+
const newValue = newProps[key];
|
|
403
|
+
if (key[0] === "o" && key[1] === "n") {
|
|
404
|
+
const oldEvent = node["__" + key];
|
|
405
|
+
if (oldEvent && oldEvent !== newValue || !oldEvent && oldValue !== newValue) {
|
|
406
|
+
newProps[key] = patchProperty(patch, node, key, oldValue, newValue, isSvg);
|
|
407
|
+
}
|
|
408
|
+
node["__" + key] = newValue;
|
|
409
|
+
} else if (oldValue !== newValue) {
|
|
410
|
+
newProps[key] = patchProperty(patch, node, key, oldValue, newValue, isSvg);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
} else {
|
|
414
|
+
for (const key in oldProps) {
|
|
415
|
+
const oldValue = oldProps[key];
|
|
416
|
+
oldProps[key] = patchProperty(patch, node, key, oldValue, undefined, isSvg);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function patchProperty(patch, node, key, oldValue, newValue, isSvg) {
|
|
421
|
+
if (key === "style") {
|
|
422
|
+
if (!newValue) {
|
|
423
|
+
node.style.cssText = "";
|
|
424
|
+
} else if (oldValue) {
|
|
425
|
+
for (let k in { ...oldValue, ...newValue }) {
|
|
426
|
+
if (!oldValue || newValue[k] !== oldValue[k]) {
|
|
427
|
+
node.style[k] = newValue[k];
|
|
428
|
+
} else if (oldValue[k] && !newValue[k]) {
|
|
429
|
+
node.style[k] = undefined;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
for (let k in newValue) {
|
|
434
|
+
node.style[k] = newValue[k];
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
} else if (key === "class") {
|
|
438
|
+
if (isSvg) {
|
|
439
|
+
if (newValue) {
|
|
440
|
+
const newClass = classString(newValue);
|
|
441
|
+
node.classList.value = newClass;
|
|
442
|
+
} else {
|
|
443
|
+
node.classList.value = "";
|
|
444
|
+
}
|
|
445
|
+
} else {
|
|
446
|
+
if (newValue) {
|
|
447
|
+
const newClass = classString(newValue);
|
|
448
|
+
node.className = newClass;
|
|
449
|
+
} else {
|
|
450
|
+
node.className = "";
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
} else if (key[0] === "o" && key[1] === "n") {
|
|
454
|
+
if (newValue) {
|
|
455
|
+
let eventHandler = null;
|
|
456
|
+
if (typeof newValue === "function") {
|
|
457
|
+
const action = newValue;
|
|
458
|
+
eventHandler = (evt) => patch([action, evt]);
|
|
459
|
+
} else if (Array.isArray(newValue)) {
|
|
460
|
+
const arr = newValue;
|
|
461
|
+
const action = newValue[0];
|
|
462
|
+
if (arr.length > 1) {
|
|
463
|
+
eventHandler = () => patch([action, ...arr.slice(1)]);
|
|
464
|
+
} else {
|
|
465
|
+
eventHandler = (evt) => patch([action, evt]);
|
|
466
|
+
}
|
|
467
|
+
} else if (typeof newValue === "object") {
|
|
468
|
+
eventHandler = () => patch(newValue);
|
|
469
|
+
}
|
|
470
|
+
node[key] = eventHandler;
|
|
471
|
+
} else {
|
|
472
|
+
node[key] = null;
|
|
473
|
+
}
|
|
474
|
+
} else if (newValue !== null && newValue !== undefined && newValue !== false) {
|
|
475
|
+
node.setAttribute(key, newValue);
|
|
476
|
+
} else {
|
|
477
|
+
node.removeAttribute(key);
|
|
478
|
+
}
|
|
479
|
+
return newValue;
|
|
480
|
+
}
|
|
481
|
+
function classString(classProp) {
|
|
482
|
+
if (typeof classProp === "string") {
|
|
483
|
+
return classProp;
|
|
484
|
+
} else if (Array.isArray(classProp)) {
|
|
485
|
+
return classProp.map(classString).join(" ");
|
|
486
|
+
} else if (typeof classProp === "object") {
|
|
487
|
+
return Object.keys(classProp).filter((k) => classProp[k]).join(" ");
|
|
488
|
+
} else {
|
|
489
|
+
return "";
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// src/vode-tags.ts
|
|
493
|
+
var A = "a";
|
|
494
|
+
var ABBR = "abbr";
|
|
495
|
+
var ADDRESS = "address";
|
|
496
|
+
var AREA = "area";
|
|
497
|
+
var ARTICLE = "article";
|
|
498
|
+
var ASIDE = "aside";
|
|
499
|
+
var AUDIO = "audio";
|
|
500
|
+
var B = "b";
|
|
501
|
+
var BASE = "base";
|
|
502
|
+
var BDI = "bdi";
|
|
503
|
+
var BDO = "bdo";
|
|
504
|
+
var BLOCKQUOTE = "blockquote";
|
|
505
|
+
var BODY = "body";
|
|
506
|
+
var BR = "br";
|
|
507
|
+
var BUTTON = "button";
|
|
508
|
+
var CANVAS = "canvas";
|
|
509
|
+
var CAPTION = "caption";
|
|
510
|
+
var CITE = "cite";
|
|
511
|
+
var CODE = "code";
|
|
512
|
+
var COL = "col";
|
|
513
|
+
var COLGROUP = "colgroup";
|
|
514
|
+
var DATA = "data";
|
|
515
|
+
var DATALIST = "datalist";
|
|
516
|
+
var DD = "dd";
|
|
517
|
+
var DEL = "del";
|
|
518
|
+
var DETAILS = "details";
|
|
519
|
+
var DFN = "dfn";
|
|
520
|
+
var DIALOG = "dialog";
|
|
521
|
+
var DIV = "div";
|
|
522
|
+
var DL = "dl";
|
|
523
|
+
var DT = "dt";
|
|
524
|
+
var EM = "em";
|
|
525
|
+
var EMBED = "embed";
|
|
526
|
+
var FIELDSET = "fieldset";
|
|
527
|
+
var FIGCAPTION = "figcaption";
|
|
528
|
+
var FIGURE = "figure";
|
|
529
|
+
var FOOTER = "footer";
|
|
530
|
+
var FORM = "form";
|
|
531
|
+
var H1 = "h1";
|
|
532
|
+
var H2 = "h2";
|
|
533
|
+
var H3 = "h3";
|
|
534
|
+
var H4 = "h4";
|
|
535
|
+
var H5 = "h5";
|
|
536
|
+
var H6 = "h6";
|
|
537
|
+
var HEAD = "head";
|
|
538
|
+
var HEADER = "header";
|
|
539
|
+
var HGROUP = "hgroup";
|
|
540
|
+
var HR = "hr";
|
|
541
|
+
var HTML = "html";
|
|
542
|
+
var I = "i";
|
|
543
|
+
var IFRAME = "iframe";
|
|
544
|
+
var IMG = "img";
|
|
545
|
+
var INPUT = "input";
|
|
546
|
+
var INS = "ins";
|
|
547
|
+
var KBD = "kbd";
|
|
548
|
+
var LABEL = "label";
|
|
549
|
+
var LEGEND = "legend";
|
|
550
|
+
var LI = "li";
|
|
551
|
+
var LINK = "link";
|
|
552
|
+
var MAIN = "main";
|
|
553
|
+
var MAP = "map";
|
|
554
|
+
var MARK = "mark";
|
|
555
|
+
var MENU = "menu";
|
|
556
|
+
var META = "meta";
|
|
557
|
+
var METER = "meter";
|
|
558
|
+
var NAV = "nav";
|
|
559
|
+
var NOSCRIPT = "noscript";
|
|
560
|
+
var OBJECT = "object";
|
|
561
|
+
var OL = "ol";
|
|
562
|
+
var OPTGROUP = "optgroup";
|
|
563
|
+
var OPTION = "option";
|
|
564
|
+
var OUTPUT = "output";
|
|
565
|
+
var P = "p";
|
|
566
|
+
var PICTURE = "picture";
|
|
567
|
+
var PRE = "pre";
|
|
568
|
+
var PROGRESS = "progress";
|
|
569
|
+
var Q = "q";
|
|
570
|
+
var RP = "rp";
|
|
571
|
+
var RT = "rt";
|
|
572
|
+
var RUBY = "ruby";
|
|
573
|
+
var S = "s";
|
|
574
|
+
var SAMP = "samp";
|
|
575
|
+
var SCRIPT = "script";
|
|
576
|
+
var SECTION = "section";
|
|
577
|
+
var SELECT = "select";
|
|
578
|
+
var SLOT = "slot";
|
|
579
|
+
var SMALL = "small";
|
|
580
|
+
var SOURCE = "source";
|
|
581
|
+
var SPAN = "span";
|
|
582
|
+
var STRONG = "strong";
|
|
583
|
+
var STYLE = "style";
|
|
584
|
+
var SUB = "sub";
|
|
585
|
+
var SUMMARY = "summary";
|
|
586
|
+
var SUP = "sup";
|
|
587
|
+
var TABLE = "table";
|
|
588
|
+
var TBODY = "tbody";
|
|
589
|
+
var TD = "td";
|
|
590
|
+
var TEMPLATE = "template";
|
|
591
|
+
var TEXTAREA = "textarea";
|
|
592
|
+
var TFOOT = "tfoot";
|
|
593
|
+
var TH = "th";
|
|
594
|
+
var THEAD = "thead";
|
|
595
|
+
var TIME = "time";
|
|
596
|
+
var TITLE = "title";
|
|
597
|
+
var TR = "tr";
|
|
598
|
+
var TRACK = "track";
|
|
599
|
+
var U = "u";
|
|
600
|
+
var UL = "ul";
|
|
601
|
+
var VIDEO = "video";
|
|
602
|
+
var WBR = "wbr";
|
|
603
|
+
var ANIMATE = "animate";
|
|
604
|
+
var ANIMATEMOTION = "animateMotion";
|
|
605
|
+
var ANIMATETRANSFORM = "animateTransform";
|
|
606
|
+
var CIRCLE = "circle";
|
|
607
|
+
var CLIPPATH = "clipPath";
|
|
608
|
+
var DEFS = "defs";
|
|
609
|
+
var DESC = "desc";
|
|
610
|
+
var ELLIPSE = "ellipse";
|
|
611
|
+
var FEBLEND = "feBlend";
|
|
612
|
+
var FECOLORMATRIX = "feColorMatrix";
|
|
613
|
+
var FECOMPONENTTRANSFER = "feComponentTransfer";
|
|
614
|
+
var FECOMPOSITE = "feComposite";
|
|
615
|
+
var FECONVOLVEMATRIX = "feConvolveMatrix";
|
|
616
|
+
var FEDIFFUSELIGHTING = "feDiffuseLighting";
|
|
617
|
+
var FEDISPLACEMENTMAP = "feDisplacementMap";
|
|
618
|
+
var FEDISTANTLIGHT = "feDistantLight";
|
|
619
|
+
var FEDROPSHADOW = "feDropShadow";
|
|
620
|
+
var FEFLOOD = "feFlood";
|
|
621
|
+
var FEFUNCA = "feFuncA";
|
|
622
|
+
var FEFUNCB = "feFuncB";
|
|
623
|
+
var FEFUNCG = "feFuncG";
|
|
624
|
+
var FEFUNCR = "feFuncR";
|
|
625
|
+
var FEGAUSSIANBLUR = "feGaussianBlur";
|
|
626
|
+
var FEIMAGE = "feImage";
|
|
627
|
+
var FEMERGE = "feMerge";
|
|
628
|
+
var FEMERGENODE = "feMergeNode";
|
|
629
|
+
var FEMORPHOLOGY = "feMorphology";
|
|
630
|
+
var FEOFFSET = "feOffset";
|
|
631
|
+
var FEPOINTLIGHT = "fePointLight";
|
|
632
|
+
var FESPECULARLIGHTING = "feSpecularLighting";
|
|
633
|
+
var FESPOTLIGHT = "feSpotLight";
|
|
634
|
+
var FETILE = "feTile";
|
|
635
|
+
var FETURBULENCE = "feTurbulence";
|
|
636
|
+
var FILTER = "filter";
|
|
637
|
+
var FOREIGNOBJECT = "foreignObject";
|
|
638
|
+
var G = "g";
|
|
639
|
+
var IMAGE = "image";
|
|
640
|
+
var LINE = "line";
|
|
641
|
+
var LINEARGRADIENT = "linearGradient";
|
|
642
|
+
var MARKER = "marker";
|
|
643
|
+
var MASK = "mask";
|
|
644
|
+
var METADATA = "metadata";
|
|
645
|
+
var MPATH = "mpath";
|
|
646
|
+
var PATH = "path";
|
|
647
|
+
var PATTERN = "pattern";
|
|
648
|
+
var POLYGON = "polygon";
|
|
649
|
+
var POLYLINE = "polyline";
|
|
650
|
+
var RADIALGRADIENT = "radialGradient";
|
|
651
|
+
var RECT = "rect";
|
|
652
|
+
var SET = "set";
|
|
653
|
+
var STOP = "stop";
|
|
654
|
+
var SVG = "svg";
|
|
655
|
+
var SWITCH = "switch";
|
|
656
|
+
var SYMBOL = "symbol";
|
|
657
|
+
var TEXT = "text";
|
|
658
|
+
var TEXTPATH = "textPath";
|
|
659
|
+
var TSPAN = "tspan";
|
|
660
|
+
var USE = "use";
|
|
661
|
+
var VIEW = "view";
|
|
662
|
+
var ANNOTATION = "annotation";
|
|
663
|
+
var ANNOTATION_XML = "annotation-xml";
|
|
664
|
+
var MACTION = "maction";
|
|
665
|
+
var MATH = "math";
|
|
666
|
+
var MERROR = "merror";
|
|
667
|
+
var MFRAC = "mfrac";
|
|
668
|
+
var MI = "mi";
|
|
669
|
+
var MMULTISCRIPTS = "mmultiscripts";
|
|
670
|
+
var MN = "mn";
|
|
671
|
+
var MO = "mo";
|
|
672
|
+
var MOVER = "mover";
|
|
673
|
+
var MPADDED = "mpadded";
|
|
674
|
+
var MPHANTOM = "mphantom";
|
|
675
|
+
var MPRESCRIPTS = "mprescripts";
|
|
676
|
+
var MROOT = "mroot";
|
|
677
|
+
var MROW = "mrow";
|
|
678
|
+
var MS = "ms";
|
|
679
|
+
var MSPACE = "mspace";
|
|
680
|
+
var MSQRT = "msqrt";
|
|
681
|
+
var MSTYLE = "mstyle";
|
|
682
|
+
var MSUB = "msub";
|
|
683
|
+
var MSUBSUP = "msubsup";
|
|
684
|
+
var MSUP = "msup";
|
|
685
|
+
var MTABLE = "mtable";
|
|
686
|
+
var MTD = "mtd";
|
|
687
|
+
var MTEXT = "mtext";
|
|
688
|
+
var MTR = "mtr";
|
|
689
|
+
var MUNDER = "munder";
|
|
690
|
+
var MUNDEROVER = "munderover";
|
|
691
|
+
var SEMANTICS = "semantics";
|
|
692
|
+
// src/html.ts
|
|
693
|
+
function htmlToVode(html) {
|
|
694
|
+
const div = document.createElement("div");
|
|
695
|
+
div.innerHTML = html.trim();
|
|
696
|
+
const vodes = [];
|
|
697
|
+
for (const child2 of div.childNodes) {
|
|
698
|
+
const v = elementToVode(child2);
|
|
699
|
+
if (v != null)
|
|
700
|
+
vodes.push(v);
|
|
701
|
+
}
|
|
702
|
+
return vodes;
|
|
703
|
+
}
|
|
704
|
+
function elementToVode(element) {
|
|
705
|
+
if (element.nodeType === Node.TEXT_NODE) {
|
|
706
|
+
return element.textContent;
|
|
707
|
+
}
|
|
708
|
+
if (element.nodeType !== Node.ELEMENT_NODE) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
const vode2 = [element.tagName.toLowerCase()];
|
|
712
|
+
if (element.hasAttributes()) {
|
|
713
|
+
const props2 = {};
|
|
714
|
+
for (const att of element.attributes) {
|
|
715
|
+
props2[att.name] = att.value;
|
|
716
|
+
}
|
|
717
|
+
vode2.push(props2);
|
|
718
|
+
}
|
|
719
|
+
for (const child2 of element.childNodes) {
|
|
720
|
+
const v = elementToVode(child2);
|
|
721
|
+
if (v && (typeof v !== "string" || v.length > 0))
|
|
722
|
+
vode2.push(v);
|
|
723
|
+
}
|
|
724
|
+
return vode2;
|
|
725
|
+
}
|
|
726
|
+
export {
|
|
727
|
+
vode,
|
|
728
|
+
tag,
|
|
729
|
+
props,
|
|
730
|
+
mergeClass,
|
|
731
|
+
merge,
|
|
732
|
+
memo,
|
|
733
|
+
htmlToVode,
|
|
734
|
+
createState,
|
|
735
|
+
createPatch,
|
|
736
|
+
childrenStart,
|
|
737
|
+
children,
|
|
738
|
+
childCount,
|
|
739
|
+
child,
|
|
740
|
+
app,
|
|
741
|
+
WBR,
|
|
742
|
+
VIEW,
|
|
743
|
+
VIDEO,
|
|
744
|
+
USE,
|
|
745
|
+
UL,
|
|
746
|
+
U,
|
|
747
|
+
TSPAN,
|
|
748
|
+
TRACK,
|
|
749
|
+
TR,
|
|
750
|
+
TITLE,
|
|
751
|
+
TIME,
|
|
752
|
+
THEAD,
|
|
753
|
+
TH,
|
|
754
|
+
TFOOT,
|
|
755
|
+
TEXTPATH,
|
|
756
|
+
TEXTAREA,
|
|
757
|
+
TEXT,
|
|
758
|
+
TEMPLATE,
|
|
759
|
+
TD,
|
|
760
|
+
TBODY,
|
|
761
|
+
TABLE,
|
|
762
|
+
SYMBOL,
|
|
763
|
+
SWITCH,
|
|
764
|
+
SVG,
|
|
765
|
+
SUP,
|
|
766
|
+
SUMMARY,
|
|
767
|
+
SUB,
|
|
768
|
+
STYLE,
|
|
769
|
+
STRONG,
|
|
770
|
+
STOP,
|
|
771
|
+
SPAN,
|
|
772
|
+
SOURCE,
|
|
773
|
+
SMALL,
|
|
774
|
+
SLOT,
|
|
775
|
+
SET,
|
|
776
|
+
SEMANTICS,
|
|
777
|
+
SELECT,
|
|
778
|
+
SECTION,
|
|
779
|
+
SCRIPT,
|
|
780
|
+
SAMP,
|
|
781
|
+
S,
|
|
782
|
+
RUBY,
|
|
783
|
+
RT,
|
|
784
|
+
RP,
|
|
785
|
+
RECT,
|
|
786
|
+
RADIALGRADIENT,
|
|
787
|
+
Q,
|
|
788
|
+
PROGRESS,
|
|
789
|
+
PRE,
|
|
790
|
+
POLYLINE,
|
|
791
|
+
POLYGON,
|
|
792
|
+
PICTURE,
|
|
793
|
+
PATTERN,
|
|
794
|
+
PATH,
|
|
795
|
+
P,
|
|
796
|
+
OUTPUT,
|
|
797
|
+
OPTION,
|
|
798
|
+
OPTGROUP,
|
|
799
|
+
OL,
|
|
800
|
+
OBJECT,
|
|
801
|
+
NOSCRIPT,
|
|
802
|
+
NAV,
|
|
803
|
+
MUNDEROVER,
|
|
804
|
+
MUNDER,
|
|
805
|
+
MTR,
|
|
806
|
+
MTEXT,
|
|
807
|
+
MTD,
|
|
808
|
+
MTABLE,
|
|
809
|
+
MSUP,
|
|
810
|
+
MSUBSUP,
|
|
811
|
+
MSUB,
|
|
812
|
+
MSTYLE,
|
|
813
|
+
MSQRT,
|
|
814
|
+
MSPACE,
|
|
815
|
+
MS,
|
|
816
|
+
MROW,
|
|
817
|
+
MROOT,
|
|
818
|
+
MPRESCRIPTS,
|
|
819
|
+
MPHANTOM,
|
|
820
|
+
MPATH,
|
|
821
|
+
MPADDED,
|
|
822
|
+
MOVER,
|
|
823
|
+
MO,
|
|
824
|
+
MN,
|
|
825
|
+
MMULTISCRIPTS,
|
|
826
|
+
MI,
|
|
827
|
+
MFRAC,
|
|
828
|
+
METER,
|
|
829
|
+
METADATA,
|
|
830
|
+
META,
|
|
831
|
+
MERROR,
|
|
832
|
+
MENU,
|
|
833
|
+
MATH,
|
|
834
|
+
MASK,
|
|
835
|
+
MARKER,
|
|
836
|
+
MARK,
|
|
837
|
+
MAP,
|
|
838
|
+
MAIN,
|
|
839
|
+
MACTION,
|
|
840
|
+
LINK,
|
|
841
|
+
LINEARGRADIENT,
|
|
842
|
+
LINE,
|
|
843
|
+
LI,
|
|
844
|
+
LEGEND,
|
|
845
|
+
LABEL,
|
|
846
|
+
KBD,
|
|
847
|
+
INS,
|
|
848
|
+
INPUT,
|
|
849
|
+
IMG,
|
|
850
|
+
IMAGE,
|
|
851
|
+
IFRAME,
|
|
852
|
+
I,
|
|
853
|
+
HTML,
|
|
854
|
+
HR,
|
|
855
|
+
HGROUP,
|
|
856
|
+
HEADER,
|
|
857
|
+
HEAD,
|
|
858
|
+
H6,
|
|
859
|
+
H5,
|
|
860
|
+
H4,
|
|
861
|
+
H3,
|
|
862
|
+
H2,
|
|
863
|
+
H1,
|
|
864
|
+
G,
|
|
865
|
+
FORM,
|
|
866
|
+
FOREIGNOBJECT,
|
|
867
|
+
FOOTER,
|
|
868
|
+
FILTER,
|
|
869
|
+
FIGURE,
|
|
870
|
+
FIGCAPTION,
|
|
871
|
+
FIELDSET,
|
|
872
|
+
FETURBULENCE,
|
|
873
|
+
FETILE,
|
|
874
|
+
FESPOTLIGHT,
|
|
875
|
+
FESPECULARLIGHTING,
|
|
876
|
+
FEPOINTLIGHT,
|
|
877
|
+
FEOFFSET,
|
|
878
|
+
FEMORPHOLOGY,
|
|
879
|
+
FEMERGENODE,
|
|
880
|
+
FEMERGE,
|
|
881
|
+
FEIMAGE,
|
|
882
|
+
FEGAUSSIANBLUR,
|
|
883
|
+
FEFUNCR,
|
|
884
|
+
FEFUNCG,
|
|
885
|
+
FEFUNCB,
|
|
886
|
+
FEFUNCA,
|
|
887
|
+
FEFLOOD,
|
|
888
|
+
FEDROPSHADOW,
|
|
889
|
+
FEDISTANTLIGHT,
|
|
890
|
+
FEDISPLACEMENTMAP,
|
|
891
|
+
FEDIFFUSELIGHTING,
|
|
892
|
+
FECONVOLVEMATRIX,
|
|
893
|
+
FECOMPOSITE,
|
|
894
|
+
FECOMPONENTTRANSFER,
|
|
895
|
+
FECOLORMATRIX,
|
|
896
|
+
FEBLEND,
|
|
897
|
+
EmptyPatch,
|
|
898
|
+
EMBED,
|
|
899
|
+
EM,
|
|
900
|
+
ELLIPSE,
|
|
901
|
+
DT,
|
|
902
|
+
DL,
|
|
903
|
+
DIV,
|
|
904
|
+
DIALOG,
|
|
905
|
+
DFN,
|
|
906
|
+
DETAILS,
|
|
907
|
+
DESC,
|
|
908
|
+
DEL,
|
|
909
|
+
DEFS,
|
|
910
|
+
DD,
|
|
911
|
+
DATALIST,
|
|
912
|
+
DATA,
|
|
913
|
+
COLGROUP,
|
|
914
|
+
COL,
|
|
915
|
+
CODE,
|
|
916
|
+
CLIPPATH,
|
|
917
|
+
CITE,
|
|
918
|
+
CIRCLE,
|
|
919
|
+
CAPTION,
|
|
920
|
+
CANVAS,
|
|
921
|
+
BUTTON,
|
|
922
|
+
BR,
|
|
923
|
+
BODY,
|
|
924
|
+
BLOCKQUOTE,
|
|
925
|
+
BDO,
|
|
926
|
+
BDI,
|
|
927
|
+
BASE,
|
|
928
|
+
B,
|
|
929
|
+
AUDIO,
|
|
930
|
+
ASIDE,
|
|
931
|
+
ARTICLE,
|
|
932
|
+
AREA,
|
|
933
|
+
ANNOTATION_XML,
|
|
934
|
+
ANNOTATION,
|
|
935
|
+
ANIMATETRANSFORM,
|
|
936
|
+
ANIMATEMOTION,
|
|
937
|
+
ANIMATE,
|
|
938
|
+
ADDRESS,
|
|
939
|
+
ABBR,
|
|
940
|
+
A
|
|
941
|
+
};
|