diff --git a/docs/.vitepress/imgit/client/index.ts b/docs/.vitepress/imgit/client/index.ts index e69de29bb..c7984a541 100644 --- a/docs/.vitepress/imgit/client/index.ts +++ b/docs/.vitepress/imgit/client/index.ts @@ -0,0 +1,3 @@ +import { observeMutations } from "./mutation"; + +observeMutations(); diff --git a/docs/.vitepress/imgit/client/observe.ts b/docs/.vitepress/imgit/client/intersection.ts similarity index 73% rename from docs/.vitepress/imgit/client/observe.ts rename to docs/.vitepress/imgit/client/intersection.ts index a555a8740..466f10a84 100644 --- a/docs/.vitepress/imgit/client/observe.ts +++ b/docs/.vitepress/imgit/client/intersection.ts @@ -1,8 +1,11 @@ -export function observe() { - if (!canObserve()) return; - const observer = new IntersectionObserver(handleIntersections); - for (const element of document.querySelectorAll("video.imgit-video")) - observer.observe(element); +const observer = canObserve() ? new IntersectionObserver(handleIntersections) : undefined; + +export function observeIntersections(element: HTMLElement) { + observer?.observe(element); +} + +export function unobserveIntersections(element: HTMLElement) { + observer?.unobserve(element); } function canObserve() { diff --git a/docs/.vitepress/imgit/client/mutation.ts b/docs/.vitepress/imgit/client/mutation.ts new file mode 100644 index 000000000..9f362432b --- /dev/null +++ b/docs/.vitepress/imgit/client/mutation.ts @@ -0,0 +1,39 @@ +import { observeIntersections, unobserveIntersections } from "./intersection"; + +const observer = canObserve() ? new MutationObserver(handleMutations) : undefined; + +export function observeMutations() { + observer?.observe(document.body, { childList: true, subtree: true }); + if (canObserve()) handleAddedNode(document.body); +} + +function canObserve() { + return typeof document === "object" && "MutationObserver" in window; +} + +function handleMutations(mutations: MutationRecord[]) { + for (const mutation of mutations) + handleMutation(mutation); +} + +function handleMutation(mutation: MutationRecord) { + if (mutation.type !== "childList") return; + for (const node of mutation.addedNodes) + if (node instanceof HTMLElement) + handleAddedNode(node); + for (const node of mutation.removedNodes) + if (node instanceof HTMLElement) + handleRemovedNode(node); +} + +function handleAddedNode(added: HTMLElement) { + for (const element of added.querySelectorAll("video.imgit-video")) + if (element instanceof HTMLElement) + observeIntersections(element); +} + +function handleRemovedNode(removed: HTMLElement) { + for (const element of removed.querySelectorAll("video.imgit-video")) + if (element instanceof HTMLElement) + unobserveIntersections(element); +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 8aff5e061..c65ce9ab2 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -1,17 +1,6 @@ -import { EnhanceAppContext } from "vitepress"; -import { observe } from "../imgit/client/observe"; import DefaultTheme from "vitepress/theme-without-fonts"; +import "../imgit/client"; import "./style.css"; // https://vitepress.dev/guide/extending-default-theme -// noinspection JSUnusedGlobalSymbols - -export default { - extends: { - Layout: DefaultTheme.Layout, - enhanceApp: (app: EnhanceAppContext) => { - DefaultTheme.enhanceApp(app); - app.router.onAfterRouteChanged = _ => void setTimeout(observe, 0); - } - } -}; +export default { extends: { Layout: DefaultTheme.Layout } };