valyrian.js 7.2.1 → 7.2.3
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/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +35 -32
- package/dist/hooks/index.mjs +35 -32
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -52
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +55 -52
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/signal/index.d.ts +19 -1
- package/dist/signal/index.d.ts.map +1 -1
- package/dist/signal/index.js +49 -32
- package/dist/signal/index.mjs +52 -35
- package/lib/hooks/index.ts +43 -54
- package/lib/index.ts +88 -79
- package/lib/interfaces.ts +1 -0
- package/lib/signal/index.ts +114 -55
- package/package.json +1 -1
package/dist/signal/index.js
CHANGED
|
@@ -24,54 +24,71 @@ __export(signal_exports, {
|
|
|
24
24
|
module.exports = __toCommonJS(signal_exports);
|
|
25
25
|
var import_valyrian = require("valyrian.js");
|
|
26
26
|
function Signal(initialValue) {
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
29
|
-
if (!
|
|
30
|
-
|
|
31
|
-
context.vnode.calls = -1;
|
|
32
|
-
context.vnode.subscribers = context.oldVnode?.subscribers || [];
|
|
33
|
-
context.vnode.initialChildren = [...context.vnode.children];
|
|
27
|
+
const { vnode, component } = { ...import_valyrian.current };
|
|
28
|
+
if (vnode) {
|
|
29
|
+
if (!vnode.components) {
|
|
30
|
+
vnode.components = [];
|
|
34
31
|
}
|
|
35
|
-
|
|
32
|
+
if (vnode.components.indexOf(component) === -1) {
|
|
33
|
+
vnode.signal_calls = -1;
|
|
34
|
+
vnode.components.push(component);
|
|
35
|
+
if (!component.signals) {
|
|
36
|
+
component.signals = [];
|
|
37
|
+
(0, import_valyrian.onUnmount)(() => Reflect.deleteProperty(component, "signals"));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
let signal2 = component.signals[++vnode.signal_calls];
|
|
36
41
|
if (signal2) {
|
|
42
|
+
signal2[3].length = 0;
|
|
37
43
|
return signal2;
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
let value = initialValue;
|
|
41
|
-
const
|
|
47
|
+
const subscriptions = [];
|
|
42
48
|
const subscribe = (callback) => {
|
|
43
|
-
if (
|
|
44
|
-
|
|
49
|
+
if (subscriptions.indexOf(callback) === -1) {
|
|
50
|
+
subscriptions.push(callback);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
let vnodesToUpdate = [];
|
|
54
|
+
const updateVnodes = () => {
|
|
55
|
+
let vnodesToUpdateCopy = vnodesToUpdate.filter((vnode2, index, self) => {
|
|
56
|
+
return self.findIndex((v2) => v2.dom === vnode2.dom) === index;
|
|
57
|
+
});
|
|
58
|
+
for (let i = 0, l = vnodesToUpdateCopy.length; i < l; i++) {
|
|
59
|
+
const vnode2 = vnodesToUpdateCopy[i];
|
|
60
|
+
let newVnode = (0, import_valyrian.v)(vnode2.tag, vnode2.props, ...vnode2.initialChildren);
|
|
61
|
+
newVnode.dom = vnode2.dom;
|
|
62
|
+
newVnode.isSVG = vnode2.isSVG;
|
|
63
|
+
(0, import_valyrian.updateVnode)(newVnode, vnode2);
|
|
45
64
|
}
|
|
46
65
|
};
|
|
47
66
|
function get() {
|
|
67
|
+
const { vnode: vnode2 } = import_valyrian.current;
|
|
68
|
+
if (vnode2 && vnodesToUpdate.indexOf(vnode2) === -1) {
|
|
69
|
+
if (!vnode2.initialChildren) {
|
|
70
|
+
vnode2.initialChildren = [...vnode2.children];
|
|
71
|
+
}
|
|
72
|
+
vnodesToUpdate.push(vnode2);
|
|
73
|
+
subscribe(updateVnodes);
|
|
74
|
+
}
|
|
48
75
|
return value;
|
|
49
76
|
}
|
|
50
|
-
get.value = value;
|
|
51
|
-
get.toJSON = get.valueOf = get;
|
|
52
|
-
get.toString = () => `${value}`;
|
|
53
77
|
const set = (newValue) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
78
|
+
if (import_valyrian.current.event) {
|
|
79
|
+
import_valyrian.current.event.preventDefault();
|
|
80
|
+
}
|
|
81
|
+
if (newValue === value) {
|
|
82
|
+
return;
|
|
58
83
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
newVnode.isSVG = context.vnode.isSVG;
|
|
63
|
-
context.vnode.subscribers.forEach(
|
|
64
|
-
(subscribers2) => subscribers2.length = 0
|
|
65
|
-
);
|
|
66
|
-
context.vnode.subscribers = [];
|
|
67
|
-
return (0, import_valyrian.updateVnode)(newVnode, context.vnode);
|
|
84
|
+
value = newValue;
|
|
85
|
+
for (let i = 0, l = subscriptions.length; i < l; i++) {
|
|
86
|
+
subscriptions[i](value);
|
|
68
87
|
}
|
|
69
|
-
return (0, import_valyrian.update)();
|
|
70
88
|
};
|
|
71
|
-
let signal = [get, set, subscribe];
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
context.vnode.subscribers.push(subscribers);
|
|
89
|
+
let signal = [get, set, subscribe, subscriptions];
|
|
90
|
+
if (vnode) {
|
|
91
|
+
component.signals.push(signal);
|
|
75
92
|
}
|
|
76
93
|
return signal;
|
|
77
94
|
}
|
package/dist/signal/index.mjs
CHANGED
|
@@ -1,54 +1,71 @@
|
|
|
1
1
|
// lib/signal/index.ts
|
|
2
|
-
import { current,
|
|
2
|
+
import { current, onUnmount, updateVnode, v } from "valyrian.js";
|
|
3
3
|
function Signal(initialValue) {
|
|
4
|
-
const
|
|
5
|
-
if (
|
|
6
|
-
if (!
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const { vnode, component } = { ...current };
|
|
5
|
+
if (vnode) {
|
|
6
|
+
if (!vnode.components) {
|
|
7
|
+
vnode.components = [];
|
|
8
|
+
}
|
|
9
|
+
if (vnode.components.indexOf(component) === -1) {
|
|
10
|
+
vnode.signal_calls = -1;
|
|
11
|
+
vnode.components.push(component);
|
|
12
|
+
if (!component.signals) {
|
|
13
|
+
component.signals = [];
|
|
14
|
+
onUnmount(() => Reflect.deleteProperty(component, "signals"));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
let signal2 = component.signals[++vnode.signal_calls];
|
|
13
18
|
if (signal2) {
|
|
19
|
+
signal2[3].length = 0;
|
|
14
20
|
return signal2;
|
|
15
21
|
}
|
|
16
22
|
}
|
|
17
23
|
let value = initialValue;
|
|
18
|
-
const
|
|
24
|
+
const subscriptions = [];
|
|
19
25
|
const subscribe = (callback) => {
|
|
20
|
-
if (
|
|
21
|
-
|
|
26
|
+
if (subscriptions.indexOf(callback) === -1) {
|
|
27
|
+
subscriptions.push(callback);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
let vnodesToUpdate = [];
|
|
31
|
+
const updateVnodes = () => {
|
|
32
|
+
let vnodesToUpdateCopy = vnodesToUpdate.filter((vnode2, index, self) => {
|
|
33
|
+
return self.findIndex((v2) => v2.dom === vnode2.dom) === index;
|
|
34
|
+
});
|
|
35
|
+
for (let i = 0, l = vnodesToUpdateCopy.length; i < l; i++) {
|
|
36
|
+
const vnode2 = vnodesToUpdateCopy[i];
|
|
37
|
+
let newVnode = v(vnode2.tag, vnode2.props, ...vnode2.initialChildren);
|
|
38
|
+
newVnode.dom = vnode2.dom;
|
|
39
|
+
newVnode.isSVG = vnode2.isSVG;
|
|
40
|
+
updateVnode(newVnode, vnode2);
|
|
22
41
|
}
|
|
23
42
|
};
|
|
24
43
|
function get() {
|
|
44
|
+
const { vnode: vnode2 } = current;
|
|
45
|
+
if (vnode2 && vnodesToUpdate.indexOf(vnode2) === -1) {
|
|
46
|
+
if (!vnode2.initialChildren) {
|
|
47
|
+
vnode2.initialChildren = [...vnode2.children];
|
|
48
|
+
}
|
|
49
|
+
vnodesToUpdate.push(vnode2);
|
|
50
|
+
subscribe(updateVnodes);
|
|
51
|
+
}
|
|
25
52
|
return value;
|
|
26
53
|
}
|
|
27
|
-
get.value = value;
|
|
28
|
-
get.toJSON = get.valueOf = get;
|
|
29
|
-
get.toString = () => `${value}`;
|
|
30
54
|
const set = (newValue) => {
|
|
55
|
+
if (current.event) {
|
|
56
|
+
current.event.preventDefault();
|
|
57
|
+
}
|
|
58
|
+
if (newValue === value) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
31
61
|
value = newValue;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
if (context.vnode) {
|
|
37
|
-
let newVnode = v(context.vnode.tag, context.vnode.props, ...context.vnode.initialChildren);
|
|
38
|
-
newVnode.dom = context.vnode.dom;
|
|
39
|
-
newVnode.isSVG = context.vnode.isSVG;
|
|
40
|
-
context.vnode.subscribers.forEach(
|
|
41
|
-
(subscribers2) => subscribers2.length = 0
|
|
42
|
-
);
|
|
43
|
-
context.vnode.subscribers = [];
|
|
44
|
-
return updateVnode(newVnode, context.vnode);
|
|
45
|
-
}
|
|
46
|
-
return update();
|
|
62
|
+
for (let i = 0, l = subscriptions.length; i < l; i++) {
|
|
63
|
+
subscriptions[i](value);
|
|
64
|
+
}
|
|
47
65
|
};
|
|
48
|
-
let signal = [get, set, subscribe];
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
context.vnode.subscribers.push(subscribers);
|
|
66
|
+
let signal = [get, set, subscribe, subscriptions];
|
|
67
|
+
if (vnode) {
|
|
68
|
+
component.signals.push(signal);
|
|
52
69
|
}
|
|
53
70
|
return signal;
|
|
54
71
|
}
|
package/lib/hooks/index.ts
CHANGED
|
@@ -34,35 +34,37 @@ export const createHook = function createHook({
|
|
|
34
34
|
returnValue
|
|
35
35
|
}: HookDefinition): Hook {
|
|
36
36
|
return (...args: any[]) => {
|
|
37
|
-
let { component, vnode
|
|
37
|
+
let { component, vnode } = current as CurrentOnPatch;
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
if (!vnode.components) {
|
|
41
|
-
vnode.components = [];
|
|
42
|
-
onUnmount(() => Reflect.deleteProperty(vnode, "components"));
|
|
43
|
-
}
|
|
39
|
+
let hook = null;
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
vnode.components
|
|
48
|
-
|
|
41
|
+
if (vnode) {
|
|
42
|
+
// Init the components array for the current vnode
|
|
43
|
+
if (!vnode.components) {
|
|
44
|
+
vnode.components = [];
|
|
45
|
+
}
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
if (vnode.components.indexOf(component) === -1) {
|
|
48
|
+
vnode.hook_calls = -1;
|
|
49
|
+
vnode.components.push(component);
|
|
50
|
+
if (!component.hooks) {
|
|
51
|
+
component.hooks = [];
|
|
52
|
+
onUnmount(() => Reflect.deleteProperty(component, "hooks"));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
hook = component.hooks[++vnode.hook_calls];
|
|
57
|
+
}
|
|
57
58
|
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
if (!oldVnode || !oldVnode.components || oldVnode.components[vnode.components.length - 1] !== component) {
|
|
59
|
+
// If the hook doesn't exist, create it
|
|
60
|
+
if (!hook) {
|
|
61
61
|
// create a new hook
|
|
62
62
|
hook = onCreate(...args);
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
if (vnode) {
|
|
65
|
+
// Add the hook to the component
|
|
66
|
+
component.hooks.push(hook);
|
|
67
|
+
}
|
|
66
68
|
|
|
67
69
|
// if we have a onRemove hook, add it to the onUnmount set
|
|
68
70
|
if (onRemove) {
|
|
@@ -70,24 +72,6 @@ export const createHook = function createHook({
|
|
|
70
72
|
onUnmount(() => onRemove(hook));
|
|
71
73
|
}
|
|
72
74
|
} else {
|
|
73
|
-
// old vnode has components, we are updating the component
|
|
74
|
-
|
|
75
|
-
// Set the calls property to the current component if it's not already set
|
|
76
|
-
if ("calls" in component === false) {
|
|
77
|
-
component.calls = -1;
|
|
78
|
-
onUnmount(() => Reflect.deleteProperty(component, "calls"));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Reset the calls property to -1 on cleanup so we can detect if the component is updated again
|
|
82
|
-
onCleanup(() => (component.calls = -1));
|
|
83
|
-
|
|
84
|
-
// Increment the calls property
|
|
85
|
-
component.calls++;
|
|
86
|
-
|
|
87
|
-
// Get the current hook from the component's hooks array
|
|
88
|
-
hook = component.hooks[component.calls];
|
|
89
|
-
|
|
90
|
-
// If we have an onUpdate hook, call it
|
|
91
75
|
if (onUpdateHook) {
|
|
92
76
|
onUpdateHook(hook, ...args);
|
|
93
77
|
}
|
|
@@ -118,22 +102,27 @@ function delayedUpdate() {
|
|
|
118
102
|
// Use state hook
|
|
119
103
|
export const useState = createHook({
|
|
120
104
|
onCreate: (value) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
105
|
+
function get() {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
get.value = value;
|
|
109
|
+
get.toJSON = get.valueOf = get;
|
|
110
|
+
get.toString = () => `${value}`;
|
|
111
|
+
|
|
112
|
+
function set(newValue) {
|
|
113
|
+
// Prevent default event if it exists
|
|
114
|
+
if (current.event) {
|
|
115
|
+
current.event.preventDefault();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (value !== newValue) {
|
|
119
|
+
value = newValue;
|
|
120
|
+
get.value = newValue;
|
|
121
|
+
delayedUpdate();
|
|
135
122
|
}
|
|
136
|
-
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return [get, set];
|
|
137
126
|
}
|
|
138
127
|
});
|
|
139
128
|
|
package/lib/index.ts
CHANGED
|
@@ -113,6 +113,8 @@ export interface Current {
|
|
|
113
113
|
vnode: VnodeWithDom | null;
|
|
114
114
|
// The old virtual node. It must have a DOM element associated with it.
|
|
115
115
|
oldVnode?: VnodeWithDom | null;
|
|
116
|
+
// The current event. It can be an event or null.
|
|
117
|
+
event: Event | null;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
// The V function is the main function for creating virtual nodes.
|
|
@@ -178,7 +180,7 @@ function domToVnode(dom: any): VnodeWithDom {
|
|
|
178
180
|
// Set the 'dom' property of the 'Vnode' instance to the child DOM node.
|
|
179
181
|
// Push the 'Vnode' instance to the 'children' array.
|
|
180
182
|
if (childDom.nodeType === 3) {
|
|
181
|
-
let vnode = new Vnode(textTag, {}, []);
|
|
183
|
+
let vnode = new Vnode(textTag, {}, [childDom.nodeValue]);
|
|
182
184
|
vnode.dom = childDom;
|
|
183
185
|
children.push(vnode as VnodeWithDom);
|
|
184
186
|
continue;
|
|
@@ -233,7 +235,8 @@ let isMounted = false;
|
|
|
233
235
|
export const current: Current = {
|
|
234
236
|
vnode: null,
|
|
235
237
|
oldVnode: null,
|
|
236
|
-
component: null
|
|
238
|
+
component: null,
|
|
239
|
+
event: null
|
|
237
240
|
};
|
|
238
241
|
|
|
239
242
|
/* Reserved props ----------------------------------------------------------- */
|
|
@@ -302,6 +305,9 @@ const eventListenerNames: Record<string, true> = {};
|
|
|
302
305
|
|
|
303
306
|
// This function is called when an event occurs
|
|
304
307
|
function eventListener(e: Event) {
|
|
308
|
+
// Set the current event to the event that occurred so that it can be prevented if necessary
|
|
309
|
+
current.event = e;
|
|
310
|
+
|
|
305
311
|
// Convert the target of the event to a DOM element
|
|
306
312
|
let dom = e.target as DomElement;
|
|
307
313
|
|
|
@@ -323,6 +329,8 @@ function eventListener(e: Event) {
|
|
|
323
329
|
}
|
|
324
330
|
dom = dom.parentNode as DomElement;
|
|
325
331
|
}
|
|
332
|
+
|
|
333
|
+
current.event = null;
|
|
326
334
|
}
|
|
327
335
|
|
|
328
336
|
/* Directives --------------------------------------------------------------- */
|
|
@@ -574,15 +582,12 @@ function sharedSetAttribute(name: string, value: any, newVnode: VnodeWithDom, ol
|
|
|
574
582
|
// If the attribute value is a function, add an event listener for the attribute
|
|
575
583
|
// name to the DOM element represented by mainVnode.
|
|
576
584
|
if (typeof value === "function") {
|
|
577
|
-
// We change the name of the event to lowercase to avoid issues with case sensitivity.
|
|
578
|
-
// Ex "onClick" and "onclick" are the same event.
|
|
579
|
-
let lowercaseName = name.toLowerCase();
|
|
580
585
|
// Only add the event listener if it hasn't been added yet.
|
|
581
|
-
if (
|
|
582
|
-
(mainVnode as VnodeWithDom).dom.addEventListener(
|
|
583
|
-
eventListenerNames[
|
|
586
|
+
if (name in eventListenerNames === false) {
|
|
587
|
+
(mainVnode as VnodeWithDom).dom.addEventListener(name.slice(2), eventListener);
|
|
588
|
+
eventListenerNames[name] = true;
|
|
584
589
|
}
|
|
585
|
-
newVnode.dom[`v-${
|
|
590
|
+
newVnode.dom[`v-${name}`] = value;
|
|
586
591
|
return;
|
|
587
592
|
}
|
|
588
593
|
|
|
@@ -660,6 +665,12 @@ export function updateAttributes(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom
|
|
|
660
665
|
|
|
661
666
|
// Patch a DOM node with a new VNode tree
|
|
662
667
|
export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
668
|
+
// If the new tree has no children, set the text content of the parent DOM element to an empty string
|
|
669
|
+
if (newVnode.children.length === 0) {
|
|
670
|
+
newVnode.dom.textContent = "";
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
663
674
|
// Get the children of the new and old virtual DOM nodes
|
|
664
675
|
let newTree = newVnode.children;
|
|
665
676
|
let oldTree = oldVnode?.children || [];
|
|
@@ -751,24 +762,22 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
|
751
762
|
let newChild = newTree[i];
|
|
752
763
|
|
|
753
764
|
// If the new child is a Vnode and is not a text node
|
|
754
|
-
if (newChild instanceof Vnode
|
|
755
|
-
// If the new child
|
|
756
|
-
if (typeof newChild.tag
|
|
757
|
-
|
|
765
|
+
if (newChild instanceof Vnode) {
|
|
766
|
+
// If the tag of the new child is not a string, it is a component
|
|
767
|
+
if (typeof newChild.tag !== "string") {
|
|
768
|
+
// Set the current component to the tag of the new child
|
|
769
|
+
current.component = newChild.tag;
|
|
770
|
+
// Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments
|
|
771
|
+
newTree.splice(
|
|
772
|
+
i--,
|
|
773
|
+
1,
|
|
774
|
+
("view" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(
|
|
775
|
+
newChild.props,
|
|
776
|
+
...newChild.children
|
|
777
|
+
)
|
|
778
|
+
);
|
|
758
779
|
}
|
|
759
780
|
|
|
760
|
-
// If the tag of the new child is not a string, it is a component
|
|
761
|
-
// Set the current component to the tag of the new child
|
|
762
|
-
current.component = newChild.tag;
|
|
763
|
-
// Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments
|
|
764
|
-
newTree.splice(
|
|
765
|
-
i--,
|
|
766
|
-
1,
|
|
767
|
-
("view" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(
|
|
768
|
-
newChild.props,
|
|
769
|
-
...newChild.children
|
|
770
|
-
)
|
|
771
|
-
);
|
|
772
781
|
continue;
|
|
773
782
|
}
|
|
774
783
|
|
|
@@ -785,38 +794,28 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
|
785
794
|
}
|
|
786
795
|
|
|
787
796
|
// If the new child is a Vnode, set the text of the Vnode to the text content of its dom property
|
|
788
|
-
|
|
789
|
-
// Set the new child to the text content of its dom property
|
|
790
|
-
newChild.children[0] = (newChild as VnodeWithDom).dom.textContent;
|
|
791
|
-
continue;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// If the new child is not a Vnode, wrap it in a text Vnode
|
|
795
|
-
newChild = newTree[i] = new Vnode(textTag, {}, [newChild]);
|
|
797
|
+
newTree[i] = new Vnode(textTag, {}, [newChild]);
|
|
796
798
|
}
|
|
797
799
|
|
|
798
800
|
// Patch the the old tree
|
|
799
801
|
for (let i = 0; i < newTree.length; i++) {
|
|
800
802
|
let newChild = newTree[i];
|
|
801
803
|
|
|
802
|
-
// If the new child is a text vnode
|
|
803
804
|
if (newChild.tag === textTag) {
|
|
805
|
+
// If no old child exists at the same index
|
|
806
|
+
if (i >= oldTreeLength) {
|
|
807
|
+
// Create a new text node for the new child
|
|
808
|
+
newChild.dom = document.createTextNode(newChild.children[0]);
|
|
809
|
+
// Append the new text node to the dom
|
|
810
|
+
newVnode.dom.appendChild(newChild.dom);
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
|
|
804
814
|
// If there is an old child at the same index
|
|
805
|
-
|
|
806
|
-
let oldChild = oldTree[i];
|
|
807
|
-
|
|
808
|
-
// If the old child is a text node
|
|
809
|
-
if (oldChild.tag === textTag) {
|
|
810
|
-
// Set the dom property of the text Vnode to the dom property of the old child
|
|
811
|
-
newChild.dom = oldChild.dom;
|
|
812
|
-
// If the text content of the old child is different from the new child, update the text content of the old child
|
|
813
|
-
// eslint-disable-next-line eqeqeq
|
|
814
|
-
if (newChild.children[0] != oldChild.dom.textContent) {
|
|
815
|
-
oldChild.dom.textContent = newChild.children[0];
|
|
816
|
-
}
|
|
817
|
-
continue;
|
|
818
|
-
}
|
|
815
|
+
let oldChild = oldTree[i];
|
|
819
816
|
|
|
817
|
+
// If the old child is not a text node
|
|
818
|
+
if (oldChild.tag !== textTag) {
|
|
820
819
|
// Create a new text node for the new child
|
|
821
820
|
newChild.dom = document.createTextNode(newChild.children[0]);
|
|
822
821
|
// Replace the old child in the dom with the new text node
|
|
@@ -824,10 +823,14 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
|
824
823
|
continue;
|
|
825
824
|
}
|
|
826
825
|
|
|
827
|
-
//
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
826
|
+
// If the old child is a text node
|
|
827
|
+
// Set the dom property of the text Vnode to the dom property of the old child
|
|
828
|
+
newChild.dom = oldChild.dom;
|
|
829
|
+
// If the text content of the old child is different from the new child, update the text content of the old child
|
|
830
|
+
// eslint-disable-next-line eqeqeq
|
|
831
|
+
if (newChild.children[0] != oldChild.dom.textContent) {
|
|
832
|
+
oldChild.dom.textContent = newChild.children[0];
|
|
833
|
+
}
|
|
831
834
|
continue;
|
|
832
835
|
}
|
|
833
836
|
|
|
@@ -835,26 +838,24 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
|
835
838
|
// Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element
|
|
836
839
|
newChild.isSVG = newVnode.isSVG || newChild.tag === "svg";
|
|
837
840
|
|
|
838
|
-
// If there is
|
|
839
|
-
if (i
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
841
|
+
// If there is no old child at the same index
|
|
842
|
+
if (i >= oldTreeLength) {
|
|
843
|
+
// Create a new dom element for the new child
|
|
844
|
+
newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);
|
|
845
|
+
// Update the attributes of the new child
|
|
846
|
+
updateAttributes(newChild as VnodeWithDom);
|
|
847
|
+
// Append the new child to the dom
|
|
848
|
+
newVnode.dom.appendChild(newChild.dom);
|
|
849
|
+
// Recursively patch the new child
|
|
850
|
+
patch(newChild as VnodeWithDom);
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
850
853
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
// Recursively patch the new and old children
|
|
854
|
-
patch(newChild as VnodeWithDom, oldChild);
|
|
855
|
-
continue;
|
|
856
|
-
}
|
|
854
|
+
// If there is an old child at the same index
|
|
855
|
+
let oldChild = oldTree[i];
|
|
857
856
|
|
|
857
|
+
// If the tag of the new child is different from the tag of the old child
|
|
858
|
+
if (newChild.tag !== oldChild.tag) {
|
|
858
859
|
// Create a new dom element for the new child
|
|
859
860
|
newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);
|
|
860
861
|
// Update the attributes of the new child
|
|
@@ -866,14 +867,19 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {
|
|
|
866
867
|
continue;
|
|
867
868
|
}
|
|
868
869
|
|
|
869
|
-
//
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
870
|
+
// If the tag of the new child is the same as the tag of the old child
|
|
871
|
+
// Set the dom property of the new child to the dom property of the old child
|
|
872
|
+
newChild.dom = oldChild.dom;
|
|
873
|
+
// If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child
|
|
874
|
+
if ("v-keep" in newChild.props && newChild.props["v-keep"] === oldChild.props["v-keep"]) {
|
|
875
|
+
newChild.children = oldChild.children;
|
|
876
|
+
continue;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// Update the attributes of the new child based on the old child
|
|
880
|
+
updateAttributes(newChild as VnodeWithDom, oldChild);
|
|
881
|
+
// Recursively patch the new and old children
|
|
882
|
+
patch(newChild as VnodeWithDom, oldChild);
|
|
877
883
|
}
|
|
878
884
|
|
|
879
885
|
// Remove any old children that are no longer present in the new tree
|
|
@@ -929,10 +935,13 @@ export function updateVnode(vnode: VnodeWithDom, oldVnode: VnodeWithDom): string
|
|
|
929
935
|
// Recursively patch the new and old main Vnodes
|
|
930
936
|
patch(vnode, oldVnode);
|
|
931
937
|
|
|
932
|
-
// Set the
|
|
938
|
+
// Set the oldVnode's tag, props, children, dom, and isSVG properties to the newVnode's tag, props, children, dom, and isSVG properties
|
|
939
|
+
// This is necessary to allow for the oldVnode to be used as the newVnode in the next update with the normal update function
|
|
933
940
|
oldVnode.tag = vnode.tag;
|
|
934
941
|
oldVnode.props = { ...vnode.props };
|
|
935
942
|
oldVnode.children = [...vnode.children];
|
|
943
|
+
oldVnode.dom = vnode.dom;
|
|
944
|
+
oldVnode.isSVG = vnode.isSVG;
|
|
936
945
|
|
|
937
946
|
// Call any update or mount functions that are registered with the onUpdateSet or onMountSet set
|
|
938
947
|
callSet(isMounted ? onUpdateSet : onMountSet);
|
package/lib/interfaces.ts
CHANGED
|
@@ -63,6 +63,7 @@ declare module "valyrian.js" {
|
|
|
63
63
|
component: Component | POJOComponent | null;
|
|
64
64
|
vnode: VnodeWithDom | null;
|
|
65
65
|
oldVnode?: VnodeWithDom | null;
|
|
66
|
+
event: Event | null;
|
|
66
67
|
}
|
|
67
68
|
export interface V {
|
|
68
69
|
(tagOrComponent: string | Component | POJOComponent, props: Props | null, ...children: Children):
|