Skip to content

Commit

Permalink
fix(runtime): dom functions in circular dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
wibus-wee committed Dec 19, 2022
1 parent aee6ef7 commit 3b2f54a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 97 deletions.
93 changes: 92 additions & 1 deletion packages/runtime/dom/dom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,96 @@
import { VNode } from "../v-dom";
import { createElement, updateElement } from "./elements";
import { camelToDash } from "../utils/others";

/**
* Create a dom node according to the tag name of the vnode.
*
* 1. Create a dom node according to the tag name of the vnode.
* 2. Set the attributes of the dom node.
* 3. Create the child nodes of the dom node.
*
* @param node the vnode
*/
export function createElement(node: VNode): Node {
// create a dom node according to the tag name of the vnode
const el =
node.tagName === "Fragment"
? document.createDocumentFragment()
: document.createElement(node.tagName);

// set the attributes of the dom node
const attributes = node.attributes;
for (const key in attributes) {
if (key.startsWith("on")) {
const eventName = key.slice(2).toLowerCase();
el.addEventListener(eventName, attributes[key]);
} else {
node.tagName === "Fragment"
? null
: // @ts-ignore
el.setAttribute(camelToDash(key), attributes[key]);
}
}

// create the child nodes of the dom node
if (node.children) {
for (const child of node.children) {
if (typeof child === "string") {
el.appendChild(document.createTextNode(child));
continue;
}
el.appendChild(createElement(child));
}
}
return el;
}

/**
* Update the attributes of the dom node.
*
* 1. Get the dom node of the vnode.
* 2. Get the attributes of the vnode.
* 3. Update the attributes of the dom node.
* 4. Update the child nodes of the dom node.
*
* @param node the vnode
*/
export function updateElement(oldNode: VNode, newNode: VNode) {
// get the dom node of the vnode
const el = newNode.el! as HTMLElement;

// get the attributes of the vnode
const attributes = newNode.attributes;

// update the attributes of the dom node
for (const key in attributes) {
if (key.startsWith("on")) {
if (typeof oldNode?.attributes[key] === "function") {
const eventName = key.slice(2).toLowerCase();
el.removeEventListener(eventName, oldNode.attributes[key]);
el.addEventListener(eventName, attributes[key]);
}
} else {
el.setAttribute(camelToDash(key), attributes[key]);
}
}

for (const child of newNode.children) {
if (typeof child === "string") {
el.appendChild(document.createTextNode(child));
continue;
}
el.appendChild(createElement(child));
}

// update the child nodes of the dom node
if (newNode.children) {
for (const child of Object.values(newNode.children)) {
updateDOM(undefined, child);
}
}

return el;
}

/**
* Update the dom tree.
Expand Down
94 changes: 0 additions & 94 deletions packages/runtime/dom/elements.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/runtime/dom/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./attrs";
export * from "./dom";
export * from "./elements";
3 changes: 2 additions & 1 deletion packages/runtime/v-dom/patch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createElement } from "../dom";
import { updateAttributes } from "../dom/attrs";
import { createElement } from "../dom/elements";

import { VNode } from "./vnode";

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

0 comments on commit 3b2f54a

Please sign in to comment.