Refactor external svg handler
This commit is contained in:
parent
cf5e8a34fe
commit
414fd16298
@ -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 externalResourceEls = 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 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: `<?xml version="1.0" standalone="no"?>\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'
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user