import { watch } from 'vue'; import { accessFileUrl, fileAccessRevision, retryFileAccess } from './file-access'; /** Renew editor resources without replacing the document or changing its undo history. */ export function bindFileAccessDom(root: HTMLElement) { let scheduled = false; let stopped = false; const refresh = () => { if (stopped) return; for (const node of root.querySelectorAll('[src], [href], [poster]')) { for (const attr of ['src', 'href', 'poster']) { const source = node.getAttribute(attr); if (!source) continue; const target = accessFileUrl(source); if (target !== source) node.setAttribute(attr, target); } } }; const schedule = () => { if (scheduled || stopped) return; scheduled = true; queueMicrotask(() => { scheduled = false; refresh(); }); }; const observer = new MutationObserver(schedule); observer.observe(root, { subtree: true, childList: true, attributes: true, attributeFilter: ['src', 'href', 'poster'] }); const unwatch = watch(fileAccessRevision, schedule, { flush: 'post' }); const onError = (event: Event) => { const node = event.target; if (node instanceof HTMLElement) void retryFileAccess(node.getAttribute('src')).then(schedule); }; root.addEventListener('error', onError, true); refresh(); return () => { stopped = true; observer.disconnect(); unwatch(); root.removeEventListener('error', onError, true); }; }