2
0
mirror of https://github.com/iconify/iconify.git synced 2024-09-19 16:59:02 +00:00

fix(utils): do not assume that attributes are separated with spaces in loader

This commit is contained in:
Vjacheslav Trushkin 2023-01-06 14:43:22 +02:00
parent 2e3ad11248
commit 78f9ae1c12
5 changed files with 17 additions and 11 deletions

View File

@ -3,6 +3,7 @@ import type { IconifyLoaderOptions } from './types';
const svgWidthRegex = /width\s*=\s*["'](\w+)["']/;
const svgHeightRegex = /height\s*=\s*["'](\w+)["']/;
const svgTagRegex = /<svg\s+/;
function configureSvgSize(
svg: string,
@ -59,12 +60,12 @@ export async function mergeIconProps(
// add xml namespaces if necessary
if (addXmlNs) {
// add svg xmlns if missing
if (!svg.includes(' xmlns=') && !props['xmlns']) {
if (!svg.includes('xmlns=') && !props['xmlns']) {
props['xmlns'] = 'http://www.w3.org/2000/svg';
}
// add xmlns:xlink if xlink present and the xmlns missing
if (
!svg.includes(' xmlns:xlink=') &&
!svg.includes('xmlns:xlink=') &&
svg.includes('xlink:') &&
!props['xmlns:xlink']
) {
@ -80,18 +81,18 @@ export async function mergeIconProps(
)
.filter((p) => p != null);
if (propsToAdd.length) {
svg = svg.replace('<svg ', `<svg ${propsToAdd.join(' ')} `);
svg = svg.replace(svgTagRegex, `<svg ${propsToAdd.join(' ')} `);
}
if (options) {
const { defaultStyle, defaultClass } = options;
// additional props and iconCustomizer takes precedence
if (defaultClass && !svg.includes(' class=')) {
svg = svg.replace('<svg ', `<svg class="${defaultClass}" `);
if (defaultClass && !svg.includes('class=')) {
svg = svg.replace(svgTagRegex, `<svg class="${defaultClass}" `);
}
// additional props and iconCustomizer takes precedence
if (defaultStyle && !svg.includes(' style=')) {
svg = svg.replace('<svg ', `<svg style="${defaultStyle}" `);
if (defaultStyle && !svg.includes('style=')) {
svg = svg.replace(svgTagRegex, `<svg style="${defaultStyle}" `);
}
}

View File

@ -17,7 +17,7 @@ describe('Testing FileSystemIconLoader', () => {
test('FileSystemIconLoader with transform', async () => {
const result = await FileSystemIconLoader(fixturesDir, (icon) => {
return icon.replace('<svg ', '<svg width="1em" height="1em" ');
return icon.replace(/<svg\s+/, '<svg width="1em" height="1em" ');
})('circle');
expect(result && result.indexOf('width="1em"') > -1).toBeTruthy();
expect(result && result.indexOf('height="1em"') > -1).toBeTruthy();

View File

@ -1 +1,6 @@
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg"><circle cx="60" cy="60" r="50"/></svg>
<svg
viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="60" cy="60" r="50"/>
</svg>

Before

Width:  |  Height:  |  Size: 101 B

After

Width:  |  Height:  |  Size: 116 B

View File

@ -61,7 +61,7 @@ describe('Testing getCustomIcon', () => {
},
transform(svg) {
return svg.replace(
'<svg ',
/<svg\s+/,
'<svg width="1em" height="1em" '
);
},

View File

@ -51,7 +51,7 @@ describe('Testing loadIcon', () => {
customizations: {
transform(svg) {
return svg.replace(
'<svg ',
/<svg\s+/,
'<svg width="1em" height="1em" '
);
},