Skip to content

Commit 39ff2fd

Browse files
authored
Merge pull request #11 from jwcjs/fix/runtime-circular-dependency
2 parents aee6ef7 + 3b2f54a commit 39ff2fd

File tree

4 files changed

+94
-97
lines changed

4 files changed

+94
-97
lines changed

packages/runtime/dom/dom.ts

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,96 @@
11
import { VNode } from "../v-dom";
2-
import { createElement, updateElement } from "./elements";
2+
import { camelToDash } from "../utils/others";
3+
4+
/**
5+
* Create a dom node according to the tag name of the vnode.
6+
*
7+
* 1. Create a dom node according to the tag name of the vnode.
8+
* 2. Set the attributes of the dom node.
9+
* 3. Create the child nodes of the dom node.
10+
*
11+
* @param node the vnode
12+
*/
13+
export function createElement(node: VNode): Node {
14+
// create a dom node according to the tag name of the vnode
15+
const el =
16+
node.tagName === "Fragment"
17+
? document.createDocumentFragment()
18+
: document.createElement(node.tagName);
19+
20+
// set the attributes of the dom node
21+
const attributes = node.attributes;
22+
for (const key in attributes) {
23+
if (key.startsWith("on")) {
24+
const eventName = key.slice(2).toLowerCase();
25+
el.addEventListener(eventName, attributes[key]);
26+
} else {
27+
node.tagName === "Fragment"
28+
? null
29+
: // @ts-ignore
30+
el.setAttribute(camelToDash(key), attributes[key]);
31+
}
32+
}
33+
34+
// create the child nodes of the dom node
35+
if (node.children) {
36+
for (const child of node.children) {
37+
if (typeof child === "string") {
38+
el.appendChild(document.createTextNode(child));
39+
continue;
40+
}
41+
el.appendChild(createElement(child));
42+
}
43+
}
44+
return el;
45+
}
46+
47+
/**
48+
* Update the attributes of the dom node.
49+
*
50+
* 1. Get the dom node of the vnode.
51+
* 2. Get the attributes of the vnode.
52+
* 3. Update the attributes of the dom node.
53+
* 4. Update the child nodes of the dom node.
54+
*
55+
* @param node the vnode
56+
*/
57+
export function updateElement(oldNode: VNode, newNode: VNode) {
58+
// get the dom node of the vnode
59+
const el = newNode.el! as HTMLElement;
60+
61+
// get the attributes of the vnode
62+
const attributes = newNode.attributes;
63+
64+
// update the attributes of the dom node
65+
for (const key in attributes) {
66+
if (key.startsWith("on")) {
67+
if (typeof oldNode?.attributes[key] === "function") {
68+
const eventName = key.slice(2).toLowerCase();
69+
el.removeEventListener(eventName, oldNode.attributes[key]);
70+
el.addEventListener(eventName, attributes[key]);
71+
}
72+
} else {
73+
el.setAttribute(camelToDash(key), attributes[key]);
74+
}
75+
}
76+
77+
for (const child of newNode.children) {
78+
if (typeof child === "string") {
79+
el.appendChild(document.createTextNode(child));
80+
continue;
81+
}
82+
el.appendChild(createElement(child));
83+
}
84+
85+
// update the child nodes of the dom node
86+
if (newNode.children) {
87+
for (const child of Object.values(newNode.children)) {
88+
updateDOM(undefined, child);
89+
}
90+
}
91+
92+
return el;
93+
}
394

495
/**
596
* Update the dom tree.

packages/runtime/dom/elements.ts

Lines changed: 0 additions & 94 deletions
This file was deleted.

packages/runtime/dom/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
export * from "./attrs";
22
export * from "./dom";
3-
export * from "./elements";

packages/runtime/v-dom/patch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { createElement } from "../dom";
12
import { updateAttributes } from "../dom/attrs";
2-
import { createElement } from "../dom/elements";
3+
34
import { VNode } from "./vnode";
45

56
export function patch(host: Node, vnode: VNode, old: VNode, index: number) {

0 commit comments

Comments
 (0)