jsx-framework-test-pb 0.1.0 → 0.1.2
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.
|
@@ -5,5 +5,5 @@ interface FiberNode {
|
|
|
5
5
|
key: string | null;
|
|
6
6
|
index: number;
|
|
7
7
|
}
|
|
8
|
-
export declare function reconcile(parent: HTMLElement, newElements: any[], oldFibers?: FiberNode[]): FiberNode[];
|
|
8
|
+
export declare function reconcile(parent: HTMLElement, newElements: any[] | any, oldFibers?: FiberNode[]): FiberNode[];
|
|
9
9
|
export {};
|
|
@@ -1,43 +1,74 @@
|
|
|
1
|
-
import { createElement } from
|
|
2
|
-
import { isElement } from
|
|
3
|
-
|
|
1
|
+
import { createElement } from "./createElement";
|
|
2
|
+
import { isElement } from "../utils";
|
|
3
|
+
function canReuse(oldElement, newElement) {
|
|
4
|
+
if (typeof oldElement !== typeof newElement)
|
|
5
|
+
return false;
|
|
6
|
+
if (typeof oldElement !== "object" || !isElement(oldElement) || !isElement(newElement)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return oldElement.type === newElement.type;
|
|
10
|
+
}
|
|
11
|
+
function updateElement(dom, element) {
|
|
12
|
+
if (!isElement(element))
|
|
13
|
+
return;
|
|
14
|
+
const { props } = element;
|
|
15
|
+
Object.keys(props).forEach((key) => {
|
|
16
|
+
if (key === "children") {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
else if (key.startsWith("on") && typeof props[key] === "function") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
else if (key === "className") {
|
|
23
|
+
dom.setAttribute("class", props[key]);
|
|
24
|
+
}
|
|
25
|
+
else if (key === "style" && typeof props[key] === "object") {
|
|
26
|
+
Object.assign(dom.style, props[key]);
|
|
27
|
+
}
|
|
28
|
+
else if (key !== "key" && props[key] != null) {
|
|
29
|
+
dom.setAttribute(key, String(props[key]));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function getInsertionPoint(parent, targetIndex) {
|
|
34
|
+
return parent.childNodes.item(targetIndex) ?? null;
|
|
35
|
+
}
|
|
4
36
|
export function reconcile(parent, newElements, oldFibers = []) {
|
|
5
37
|
const newFibers = [];
|
|
6
38
|
const newElementsArray = Array.isArray(newElements) ? newElements : [newElements];
|
|
7
39
|
const oldFibersByKey = new Map();
|
|
8
40
|
const oldFibersByIndex = new Map();
|
|
9
|
-
oldFibers.forEach((fiber,
|
|
10
|
-
if (fiber.key
|
|
41
|
+
oldFibers.forEach((fiber, i) => {
|
|
42
|
+
if (fiber.key != null)
|
|
11
43
|
oldFibersByKey.set(fiber.key, fiber);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
oldFibersByIndex.set(index, fiber);
|
|
15
|
-
}
|
|
44
|
+
else
|
|
45
|
+
oldFibersByIndex.set(i, fiber);
|
|
16
46
|
});
|
|
17
|
-
const
|
|
18
|
-
if (!parent.contains(anchor)) {
|
|
19
|
-
parent.appendChild(anchor);
|
|
20
|
-
}
|
|
47
|
+
const reusedOldDoms = new Set();
|
|
21
48
|
newElementsArray.forEach((element, index) => {
|
|
22
49
|
const key = isElement(element) ? element.key : null;
|
|
23
|
-
let fiber;
|
|
24
50
|
let oldFiber;
|
|
25
|
-
if (key
|
|
51
|
+
if (key != null) {
|
|
26
52
|
oldFiber = oldFibersByKey.get(key);
|
|
27
|
-
|
|
53
|
+
if (oldFiber)
|
|
54
|
+
oldFibersByKey.delete(key);
|
|
28
55
|
}
|
|
29
56
|
else {
|
|
30
57
|
oldFiber = oldFibersByIndex.get(index);
|
|
31
|
-
|
|
58
|
+
if (oldFiber)
|
|
59
|
+
oldFibersByIndex.delete(index);
|
|
32
60
|
}
|
|
61
|
+
let fiber;
|
|
33
62
|
if (oldFiber && canReuse(oldFiber.element, element)) {
|
|
34
63
|
fiber = {
|
|
35
64
|
element,
|
|
36
65
|
dom: oldFiber.dom,
|
|
37
66
|
parent: null,
|
|
38
67
|
key,
|
|
39
|
-
index
|
|
68
|
+
index,
|
|
40
69
|
};
|
|
70
|
+
if (fiber.dom)
|
|
71
|
+
reusedOldDoms.add(fiber.dom);
|
|
41
72
|
if (oldFiber.dom && isElement(element)) {
|
|
42
73
|
updateElement(oldFiber.dom, element);
|
|
43
74
|
}
|
|
@@ -49,55 +80,28 @@ export function reconcile(parent, newElements, oldFibers = []) {
|
|
|
49
80
|
dom,
|
|
50
81
|
parent: null,
|
|
51
82
|
key,
|
|
52
|
-
index
|
|
83
|
+
index,
|
|
53
84
|
};
|
|
85
|
+
if (oldFiber?.dom && oldFiber.dom.parentNode === parent) {
|
|
86
|
+
parent.removeChild(oldFiber.dom);
|
|
87
|
+
}
|
|
54
88
|
if (dom) {
|
|
55
|
-
parent
|
|
89
|
+
const before = getInsertionPoint(parent, index);
|
|
90
|
+
parent.insertBefore(dom, before);
|
|
56
91
|
}
|
|
57
|
-
|
|
58
|
-
|
|
92
|
+
}
|
|
93
|
+
if (fiber.dom) {
|
|
94
|
+
const before = getInsertionPoint(parent, index);
|
|
95
|
+
if (fiber.dom !== before) {
|
|
96
|
+
parent.insertBefore(fiber.dom, before);
|
|
59
97
|
}
|
|
60
98
|
}
|
|
61
99
|
newFibers.push(fiber);
|
|
62
|
-
if (fiber.dom && fiber.dom.nextSibling !== anchor) {
|
|
63
|
-
parent.insertBefore(fiber.dom, anchor);
|
|
64
|
-
}
|
|
65
100
|
});
|
|
66
|
-
[...oldFibersByKey.values(), ...oldFibersByIndex.values()].forEach(fiber => {
|
|
67
|
-
if (fiber.dom) {
|
|
101
|
+
[...oldFibersByKey.values(), ...oldFibersByIndex.values()].forEach((fiber) => {
|
|
102
|
+
if (fiber.dom && fiber.dom.parentNode === parent && !reusedOldDoms.has(fiber.dom)) {
|
|
68
103
|
parent.removeChild(fiber.dom);
|
|
69
104
|
}
|
|
70
105
|
});
|
|
71
106
|
return newFibers;
|
|
72
107
|
}
|
|
73
|
-
function canReuse(oldElement, newElement) {
|
|
74
|
-
if (typeof oldElement !== typeof newElement) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
if (typeof oldElement !== 'object' || !isElement(oldElement) || !isElement(newElement)) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
return oldElement.type === newElement.type;
|
|
81
|
-
}
|
|
82
|
-
function updateElement(dom, element) {
|
|
83
|
-
if (!isElement(element))
|
|
84
|
-
return;
|
|
85
|
-
const { props } = element;
|
|
86
|
-
Object.keys(props).forEach(key => {
|
|
87
|
-
if (key === 'children') {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
else if (key.startsWith('on') && typeof props[key] === 'function') {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
else if (key === 'className') {
|
|
94
|
-
dom.setAttribute('class', props[key]);
|
|
95
|
-
}
|
|
96
|
-
else if (key === 'style' && typeof props[key] === 'object') {
|
|
97
|
-
Object.assign(dom.style, props[key]);
|
|
98
|
-
}
|
|
99
|
-
else if (key !== 'key' && props[key] != null) {
|
|
100
|
-
dom.setAttribute(key, String(props[key]));
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface ElementProps {
|
|
|
16
16
|
children?: ElementChild | ElementChild[];
|
|
17
17
|
[key: string]: any;
|
|
18
18
|
}
|
|
19
|
-
export type ElementChild = Element | string | number | boolean | null | undefined;
|
|
19
|
+
export type ElementChild = Element | string | number | boolean | null | undefined | (() => any);
|
|
20
20
|
export type FC<P = {}> = (props: P) => Element | null;
|
|
21
21
|
export interface CSSProperties {
|
|
22
22
|
[key: string]: string | number;
|