mirror of
https://github.com/murashit/codex-panel.git
synced 2026-07-22 17:30:31 +00:00
48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
import { render, type ComponentChild as UiNode } from "preact";
|
|
|
|
const roots = new WeakSet<HTMLElement>();
|
|
const guardedContainers = new WeakSet<HTMLElement>();
|
|
const internalMutationContainers = new WeakSet<HTMLElement>();
|
|
|
|
// Obsidian-owned containers can be emptied outside Preact during view rebuilds.
|
|
// Keep each host element as an explicit root boundary and unmount before an
|
|
// external replaceChildren call detaches Preact-managed nodes.
|
|
export function renderUiRoot(container: HTMLElement, node: UiNode): void {
|
|
prepareRootContainer(container);
|
|
internalMutationContainers.add(container);
|
|
try {
|
|
render(node, container);
|
|
} finally {
|
|
internalMutationContainers.delete(container);
|
|
}
|
|
}
|
|
|
|
export function unmountUiRoot(container: HTMLElement | null): void {
|
|
if (!container) return;
|
|
if (!roots.has(container)) return;
|
|
internalMutationContainers.add(container);
|
|
try {
|
|
render(null, container);
|
|
} finally {
|
|
internalMutationContainers.delete(container);
|
|
roots.delete(container);
|
|
}
|
|
}
|
|
|
|
function prepareRootContainer(container: HTMLElement): void {
|
|
if (roots.has(container)) return;
|
|
guardExternalEmpty(container);
|
|
roots.add(container);
|
|
}
|
|
|
|
function guardExternalEmpty(container: HTMLElement): void {
|
|
if (guardedContainers.has(container)) return;
|
|
guardedContainers.add(container);
|
|
const replaceChildren = container.replaceChildren.bind(container);
|
|
container.replaceChildren = (...nodes) => {
|
|
if (!internalMutationContainers.has(container)) {
|
|
unmountUiRoot(container);
|
|
}
|
|
replaceChildren(...nodes);
|
|
};
|
|
}
|