Web Dev Solutions

Catalin Mititiuc

From 414fd16298d0e870c71ffbceadec0ea84ca18142 Mon Sep 17 00:00:00 2001 From: Catalin Mititiuc Date: Fri, 31 May 2024 10:27:01 -0700 Subject: Refactor external svg handler --- esbuild-server.mjs | 61 +++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/esbuild-server.mjs b/esbuild-server.mjs index b897a09..14741c9 100644 --- a/esbuild-server.mjs +++ b/esbuild-server.mjs @@ -121,51 +121,50 @@ const resolveImportedSvg = { path: path.resolve('public', args.path), }; }); + } +} +const externalSvgToInternal = { + name: 'externalSvgToInternal', + setup(build) { build.onLoad({ filter: /\.svg$/ }, async (args) => { const document = (await JSDOM.fromFile(args.path)).window.document; - const externalResourceUseEls = Array.from(document.querySelectorAll('use[href*=".svg"')); - - const files = [...new Set([...externalResourceUseEls.map(el => - el.getAttributeNS(null, 'href').match(/.+\.svg/).at(0) - )])]; - - const readFiles = await Promise.all( - files.map(filename => JSDOM.fromFile(path.join(path.dirname(args.path), filename))) - ).then(result => result.reduce((acc, dom, index) => { - acc[files[index]] = dom.window.document; - return acc; - }, {})); + const externalResourceEls = Array.from(document.querySelectorAll('use[href*=".svg"')); - const refs = {}; - - externalResourceUseEls.forEach(el => { + const refs = externalResourceEls.reduce((acc, el) => { const href = el.getAttributeNS(null, 'href'); const [filename] = href.match(/.+\.svg/); - const fragId = href.split('.svg').pop(); - const frag = readFiles[filename].querySelector(fragId); + const fragmentIdentifier = href.split('.svg').pop(); - if (frag) { - frag.querySelectorAll('use').forEach(el => - (refs[filename] ??= []).push(el.getAttributeNS(null, 'href')) - ); + (acc[filename] ??= new Set()).add(fragmentIdentifier); + el.setAttributeNS(null, 'href', fragmentIdentifier); - (refs[filename] ??= []).push(fragId); - el.setAttributeNS(null, 'href', fragId); - } - }); + return acc; + }, {}); - Object.keys(refs).forEach(filename => { - const refsQuery = [...new Set([...refs[filename]])].join(', '); - const refNodes = readFiles[filename].querySelectorAll(refsQuery); + await Promise.all( + Object.keys(refs).map(filename => JSDOM.fromFile(path.join(path.dirname(args.path), filename))) + ).then(result => { const defs = document.querySelector('defs'); - refNodes.forEach(n => defs.appendChild(n)); + + Object.keys(refs).forEach((filename, index) => { + const external = result[index].window.document; + + refs[filename].forEach(fragmentIdentifier => { + external + .querySelectorAll(`${fragmentIdentifier} use`) + .forEach(el => refs[filename].add(el.getAttributeNS(null, 'href'))); + }); + + const refsQuery = [...refs[filename]].join(', '); + external.querySelectorAll(refsQuery).forEach(node => defs.appendChild(node)); + }); }); return { contents: `\n${document.querySelector('svg').outerHTML}`, loader: 'file', - watchFiles: Object.keys(readFiles).map(filename => path.join(path.dirname(args.path), filename)) + watchFiles: Object.keys(refs).map(filename => path.join(path.dirname(args.path), filename)) } }); } @@ -175,7 +174,7 @@ const ctx = await esbuild.context({ entryPoints: ['src/index.js', 'src/soldier_record_block.js', 'src/map.js'], bundle: true, outdir: 'build', - plugins: [resolveImportedSvg], + plugins: [resolveImportedSvg, externalSvgToInternal], loader: { '.svg': 'file' }, -- cgit v1.2.3