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),
|
path: path.resolve('public', args.path),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const externalSvgToInternal = {
|
||||||
|
name: 'externalSvgToInternal',
|
||||||
|
setup(build) {
|
||||||
build.onLoad({ filter: /\.svg$/ }, async (args) => {
|
build.onLoad({ filter: /\.svg$/ }, async (args) => {
|
||||||
const document = (await JSDOM.fromFile(args.path)).window.document;
|
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 =>
|
const refs = externalResourceEls.reduce((acc, 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 href = el.getAttributeNS(null, 'href');
|
const href = el.getAttributeNS(null, 'href');
|
||||||
const [filename] = href.match(/.+\.svg/);
|
const [filename] = href.match(/.+\.svg/);
|
||||||
const fragId = href.split('.svg').pop();
|
const fragmentIdentifier = href.split('.svg').pop();
|
||||||
const frag = readFiles[filename].querySelector(fragId);
|
|
||||||
|
|
||||||
if (frag) {
|
(acc[filename] ??= new Set()).add(fragmentIdentifier);
|
||||||
frag.querySelectorAll('use').forEach(el =>
|
el.setAttributeNS(null, 'href', fragmentIdentifier);
|
||||||
(refs[filename] ??= []).push(el.getAttributeNS(null, 'href'))
|
|
||||||
);
|
|
||||||
|
|
||||||
(refs[filename] ??= []).push(fragId);
|
return acc;
|
||||||
el.setAttributeNS(null, 'href', fragId);
|
}, {});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(refs).forEach(filename => {
|
await Promise.all(
|
||||||
const refsQuery = [...new Set([...refs[filename]])].join(', ');
|
Object.keys(refs).map(filename => JSDOM.fromFile(path.join(path.dirname(args.path), filename)))
|
||||||
const refNodes = readFiles[filename].querySelectorAll(refsQuery);
|
).then(result => {
|
||||||
const defs = document.querySelector('defs');
|
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 {
|
return {
|
||||||
contents: `<?xml version="1.0" standalone="no"?>\n${document.querySelector('svg').outerHTML}`,
|
contents: `<?xml version="1.0" standalone="no"?>\n${document.querySelector('svg').outerHTML}`,
|
||||||
loader: 'file',
|
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'],
|
entryPoints: ['src/index.js', 'src/soldier_record_block.js', 'src/map.js'],
|
||||||
bundle: true,
|
bundle: true,
|
||||||
outdir: 'build',
|
outdir: 'build',
|
||||||
plugins: [resolveImportedSvg],
|
plugins: [resolveImportedSvg, externalSvgToInternal],
|
||||||
loader: {
|
loader: {
|
||||||
'.svg': 'file'
|
'.svg': 'file'
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user