diff --git a/.vscode/settings.json b/.vscode/settings.json index cfb04fb0..1d7c3b7b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "corg", "cssnano", "esserializer", + "fontawesome", "fsegurai", "gantt", "gitgraph", @@ -30,6 +31,7 @@ "Stackable", "tailwindcss", "uparrow", + "webfonts", "zenuml" ], "vitest.commandLine": "pnpm test:unit", diff --git a/package.json b/package.json index 4b29e59a..9429f231 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ ] }, "engines": { - "node": ">=20.19.1" + "node": ">=20.19.0" }, "packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39", "pnpm": { diff --git a/src/lib/components/Actions.svelte b/src/lib/components/Actions.svelte index 8346ea8d..73d707d3 100644 --- a/src/lib/components/Actions.svelte +++ b/src/lib/components/Actions.svelte @@ -19,38 +19,56 @@ import ExternalLinkIcon from '~icons/material-symbols/open-in-new-rounded'; import WidthIcon from '~icons/material-symbols/width-rounded'; - const FONT_AWESOME_URL = `https://cdnjs.cloudflare.com/ajax/libs/font-awesome/${FAVersion}`; + const fontAwesomeURLs = (() => { + const baseUrl = `https://cdnjs.cloudflare.com/ajax/libs/font-awesome/${FAVersion}`; + return { + css: `${baseUrl}/css/all.min.css`, + woff2: `${baseUrl}/webfonts/fa-solid-900.woff2` + }; + })(); type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void; const getFileName = (extension: string) => `mermaid-diagram-${dayjs().format('YYYY-MM-DD-HHmmss')}.${extension}`; - const getSvgElement = () => { - const svgElement = document.querySelector('#container svg')?.cloneNode(true) as HTMLElement; - svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); - return svgElement; + const getSvgElement = async () => { + try { + $inputStateStore.panZoom = false; + await new Promise((resolve) => setTimeout(resolve, 1000)); + await waitForRender(); + const svgElement = document.querySelector('#container svg'); + if (!svgElement) { + throw new Error('svg not found'); + } + svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); + return { + svg: svgElement.cloneNode(true) as HTMLElement, + box: svgElement.querySelector('g')!.getBoundingClientRect() + }; + } finally { + setTimeout(() => { + $inputStateStore.panZoom = true; + }, 10000); + } }; - const getBase64SVG = async ( - svg?: HTMLElement, - width?: number, - height?: number - ): Promise => { - if (svg) { - // Prevents the SVG size of the interface from being changed - svg = svg.cloneNode(true) as HTMLElement; - } - height && svg?.setAttribute('height', `${height}px`); - width && svg?.setAttribute('width', `${width}px`); // Workaround https://stackoverflow.com/questions/28690643/firefox-error-rendering-an-svg-image-to-html5-canvas-with-drawimage - - if (!svg) { - svg = getSvgElement(); + const injectFontAwesome = async ({ + svgString, + fontAwesomeEmbedMode + }: { + svgString: string; + fontAwesomeEmbedMode: 'raw' | 'url'; + }) => { + if (fontAwesomeEmbedMode === 'url') { + return ` + +${svgString}`; } const [fontAwesomeCSS, fontBlob] = await Promise.all([ - fetch(`${FONT_AWESOME_URL}/css/all.min.css`).then((response) => response.text()), - fetch(`${FONT_AWESOME_URL}/webfonts/fa-solid-900.woff2`).then((res) => res.blob()) + fetch(fontAwesomeURLs.css).then((response) => response.text()), + fetch(fontAwesomeURLs.woff2).then((res) => res.blob()) ]); const reader = new FileReader(); const fontBase64 = await new Promise((resolve) => { @@ -61,7 +79,7 @@ }; reader.readAsDataURL(fontBlob); }); - const fontFaceCSS = ` + const styleString = ` @font-face { font-family: 'Font Awesome 6 Free'; font-style: normal; @@ -77,14 +95,47 @@ width: 16px; fill: black; } -`; +${fontAwesomeCSS} +`; + return svgString.replace('