2024-04-23 18:18:43 +08:00
|
|
|
import { $Container } from "./node/$Container";
|
|
|
|
import { $Node } from "./node/$Node";
|
2024-02-03 09:33:34 +08:00
|
|
|
|
|
|
|
export class $NodeManager {
|
2024-08-29 02:27:14 +08:00
|
|
|
readonly $container: $Container;
|
|
|
|
readonly childList = new Set<$Node>
|
2024-02-03 09:33:34 +08:00
|
|
|
constructor(container: $Container) {
|
2024-04-24 20:57:01 +08:00
|
|
|
this.$container = container;
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|
|
|
|
|
2024-08-29 02:27:14 +08:00
|
|
|
add(element: $Node, position = -1) {
|
|
|
|
if (position === -1 || this.childList.size - 1 === position) {
|
|
|
|
this.childList.add(element);
|
|
|
|
} else {
|
|
|
|
const children = [...this.childList]
|
|
|
|
children.splice(position, 0, element);
|
|
|
|
this.childList.clear();
|
|
|
|
children.forEach(child => this.childList.add(child));
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|
2024-10-17 11:54:28 +08:00
|
|
|
(element as Mutable<$Node>).parent = this.$container;
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
remove(element: $Node) {
|
2024-08-29 02:27:14 +08:00
|
|
|
if (!this.childList.has(element)) return this;
|
|
|
|
this.childList.delete(element);
|
2024-04-24 20:57:01 +08:00
|
|
|
(element as Mutable<$Node>).parent = undefined;
|
2024-02-13 19:38:46 +08:00
|
|
|
return this;
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|
|
|
|
|
2024-03-28 20:03:03 +08:00
|
|
|
removeAll(render = true) {
|
2024-08-29 02:27:14 +08:00
|
|
|
this.childList.forEach(ele => this.remove(ele));
|
2024-03-28 20:03:03 +08:00
|
|
|
if (render) this.render();
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|
|
|
|
|
2024-02-13 19:38:46 +08:00
|
|
|
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();
|
2024-08-29 02:27:14 +08:00
|
|
|
this.childList.clear();
|
|
|
|
array.forEach(node => this.childList.add(node));
|
2024-10-17 11:54:28 +08:00
|
|
|
(replace as Mutable<$Node>).parent = this.$container;
|
2024-02-13 19:38:46 +08:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2024-02-03 09:33:34 +08:00
|
|
|
render() {
|
2024-04-20 20:46:11 +08:00
|
|
|
const [domList, nodeList] = [this.array.map(node => node.dom), Array.from(this.dom.childNodes)];
|
2024-02-13 19:38:46 +08:00
|
|
|
const appendedNodeList: Node[] = []; // appended node list
|
2024-02-03 09:33:34 +08:00
|
|
|
// Rearrange
|
2024-02-13 19:38:46 +08:00
|
|
|
while (nodeList.length || domList.length) { // while nodeList or domList has item
|
2024-02-03 09:33:34 +08:00
|
|
|
const [node, dom] = [nodeList.at(0), domList.at(0)];
|
2024-02-13 19:38:46 +08:00
|
|
|
if (!dom) { if (node && !appendedNodeList.includes(node)) node.remove(); nodeList.shift()}
|
2024-10-17 11:54:28 +08:00
|
|
|
else if (!node) { if (!dom.$.hide()) this.dom.append(dom); domList.shift();}
|
2024-02-13 19:38:46 +08:00
|
|
|
else if (dom !== node) {
|
2024-10-17 11:54:28 +08:00
|
|
|
if (!dom.$.hide()) { this.dom.insertBefore(dom, node); appendedNodeList.push(dom) }
|
2024-02-13 19:38:46 +08:00
|
|
|
domList.shift();
|
|
|
|
}
|
2024-02-03 09:33:34 +08:00
|
|
|
else {
|
2024-10-17 11:54:28 +08:00
|
|
|
if (dom.$.hide()) this.dom.removeChild(dom);
|
2024-02-03 09:33:34 +08:00
|
|
|
domList.shift(); nodeList.shift();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-17 11:54:28 +08:00
|
|
|
indexOf(target: $Node) {
|
|
|
|
return this.array.indexOf(target);
|
|
|
|
}
|
|
|
|
|
2024-08-29 02:27:14 +08:00
|
|
|
get array() {return [...this.childList.values()]};
|
2024-04-20 20:46:11 +08:00
|
|
|
|
2024-04-24 20:57:01 +08:00
|
|
|
get dom() {return this.$container.dom}
|
2024-02-03 09:33:34 +08:00
|
|
|
}
|