Files
WRNexusJS/packages/block-editor/src/download.ts
T

45 lines
1.4 KiB
TypeScript

const downloads = new WeakMap<HTMLElement, () => void>();
/** Keep a direct user-gesture fallback until replaced or the editor is removed. */
export function offerBuilderDownload(
host: HTMLElement,
content: string,
type: string,
filename: string,
): void {
const outlet = host.querySelector<HTMLElement>("[data-builder-download]");
if (!outlet) throw new Error("Download outlet is unavailable");
const url = URL.createObjectURL(new Blob([content], { type }));
const link = host.ownerDocument.createElement("a");
link.href = url;
link.download = filename;
link.textContent = `Download prepared file: ${filename}`;
let disposed = false;
const observer = new MutationObserver(() => {
if (!host.isConnected) dispose();
});
const dispose = () => {
if (disposed) return;
disposed = true;
observer.disconnect();
URL.revokeObjectURL(url);
link.remove();
if (downloads.get(host) === dispose) downloads.delete(host);
};
try {
downloads.get(host)?.();
outlet.replaceChildren(link);
observer.observe(host.ownerDocument.documentElement, { childList: true, subtree: true });
downloads.set(host, dispose);
} catch (error) {
dispose();
throw error;
}
// A blocked automatic click must not destroy the direct-click fallback.
try {
link.click();
} catch {
/* The visible link remains available. */
}
}