2
0
mirror of https://github.com/iconify/iconify.git synced 2024-09-20 01:09:04 +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 svgWidthRegex = /width\s*=\s*["'](\w+)["']/;
const svgHeightRegex = /height\s*=\s*["'](\w+)["']/; const svgHeightRegex = /height\s*=\s*["'](\w+)["']/;
const svgTagRegex = /<svg\s+/;
function configureSvgSize( function configureSvgSize(
svg: string, svg: string,
@ -80,18 +81,18 @@ export async function mergeIconProps(
) )
.filter((p) => p != null); .filter((p) => p != null);
if (propsToAdd.length) { if (propsToAdd.length) {
svg = svg.replace('<svg ', `<svg ${propsToAdd.join(' ')} `); svg = svg.replace(svgTagRegex, `<svg ${propsToAdd.join(' ')} `);
} }
if (options) { if (options) {
const { defaultStyle, defaultClass } = options; const { defaultStyle, defaultClass } = options;
// additional props and iconCustomizer takes precedence // additional props and iconCustomizer takes precedence
if (defaultClass && !svg.includes('class=')) { if (defaultClass && !svg.includes('class=')) {
svg = svg.replace('<svg ', `<svg class="${defaultClass}" `); svg = svg.replace(svgTagRegex, `<svg class="${defaultClass}" `);
} }
// additional props and iconCustomizer takes precedence // additional props and iconCustomizer takes precedence
if (defaultStyle && !svg.includes('style=')) { if (defaultStyle && !svg.includes('style=')) {
svg = svg.replace('<svg ', `<svg style="${defaultStyle}" `); svg = svg.replace(svgTagRegex, `<svg style="${defaultStyle}" `);
} }
} }

View File

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

View File

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