elexis/lib/$NodeManager.ts

66 lines
2.3 KiB
TypeScript
Raw Normal View History

import { $Container } from "./node/$Container";
import { $Node } from "./node/$Node";
import { $Text } from "./node/$Text";
export class $NodeManager {
2024-04-24 20:57:01 +08:00
$container: $Container;
$elementList = new Set<$Node>
constructor(container: $Container) {
2024-04-24 20:57:01 +08:00
this.$container = container;
}
add(element: $Node | string) {
if (typeof element === 'string') {
const text = new $Text(element);
2024-04-24 20:57:01 +08:00
this.$elementList.add(text);
(text as Mutable<$Node>).parent = this.$container;
} else {
2024-04-24 20:57:01 +08:00
this.$elementList.add(element);
(element as Mutable<$Node>).parent = this.$container;
}
}
remove(element: $Node) {
2024-04-24 20:57:01 +08:00
if (!this.$elementList.has(element)) return this;
this.$elementList.delete(element);
(element as Mutable<$Node>).parent = undefined;
return this;
}
removeAll(render = true) {
2024-04-24 20:57:01 +08:00
this.$elementList.forEach(ele => this.remove(ele));
if (render) this.render();
}
replace(target: $Node, replace: $Node) {
2024-04-24 20:57:01 +08:00
const array = this.array
array.splice(array.indexOf(target), 1, replace);
target.remove();
this.$elementList.clear();
array.forEach(node => this.$elementList.add(node));
return this;
}
render() {
const [domList, nodeList] = [this.array.map(node => node.dom), Array.from(this.dom.childNodes)];
const appendedNodeList: Node[] = []; // appended node list
// Rearrange
while (nodeList.length || domList.length) { // while nodeList or domList has item
const [node, dom] = [nodeList.at(0), domList.at(0)];
if (!dom) { if (node && !appendedNodeList.includes(node)) node.remove(); nodeList.shift()}
else if (!node) { if (!dom.$.__hidden) this.dom.append(dom); domList.shift();}
else if (dom !== node) {
if (!dom.$.__hidden) { this.dom.insertBefore(dom, node); appendedNodeList.push(dom) }
domList.shift();
}
else {
if (dom.$.__hidden) this.dom.removeChild(dom);
domList.shift(); nodeList.shift();
}
}
}
2024-04-24 20:57:01 +08:00
get array() {return [...this.$elementList.values()]};
2024-04-24 20:57:01 +08:00
get dom() {return this.$container.dom}
}