2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-13 14:13:06 +00:00

chore: skip scripts and css when formatting svg

This commit is contained in:
Vjacheslav Trushkin 2023-10-02 12:20:47 +03:00
parent aa8cb69be2
commit 7f3ea30274
2 changed files with 63 additions and 8 deletions

View File

@ -1,3 +1,8 @@
/**
* Tags to skip
*/
const skipTags = ['script', 'style'];
/**
* Prettify SVG
*/
@ -39,20 +44,30 @@ export function prettifySVG(
content = content.slice(openIndex);
closeIndex -= openIndex;
// Check for bad tag
// Check tag
const lastChar = content.slice(closeIndex - 1, closeIndex);
const isClosing = content.slice(0, 2) === '</';
let isSelfClosing = lastChar === '/' || lastChar === '?';
if (isClosing && isSelfClosing) {
// Bad code
return null;
}
// Check if tag content should be added as is
const tagName = content
.slice(isClosing ? 2 : 1)
.split(/[\s>]/)
.shift() as string;
const ignoreTagContent =
!isSelfClosing && !isClosing && skipTags.includes(tagName);
// Check for bad content after tag
if (!ignoreTagContent) {
const nextOpenIndex = content.indexOf('<', 1);
if (nextOpenIndex !== -1 && nextOpenIndex < closeIndex) {
// Fail: unexpected '<'
return null;
}
// Check tag
const lastChar = content.slice(closeIndex - 1, closeIndex);
const isClosing = content.slice(0, 2) === '</';
const isSelfClosing = lastChar === '/' || lastChar === '?';
if (isClosing && isSelfClosing) {
// Bad code
return null;
}
// Add tag
@ -65,6 +80,21 @@ export function prettifySVG(
result += content.slice(0, closeIndex + 1);
content = content.slice(closeIndex + 1);
// Add content after tag
if (ignoreTagContent) {
const closingIndex = content.indexOf('</' + tagName);
const closingEnd = content.indexOf('>', closingIndex);
if (closingIndex < 0 || closingEnd < 0) {
// Failed to find closing tag
return null;
}
result += content.slice(0, closingEnd + 1);
content = content.slice(closingEnd + 1);
// Mask as self-closing
isSelfClosing = true;
}
// Prepare for next tag
if (isClosing) {
level--;

View File

@ -47,6 +47,31 @@ describe('Prettify SVG', () => {
);
});
test('Style and script', () => {
// Basic CSS
expect(
prettifySVG('<svg><style>path { stroke-width: 1; }</style></svg>')
).toBe('<svg>\n\t<style>path { stroke-width: 1; }</style>\n</svg>\n');
// Basic script
expect(
prettifySVG(
'<svg><script lang="foo"> console.log(\'Alert\'); </script></svg>'
)
).toBe(
'<svg>\n\t<script lang="foo"> console.log(\'Alert\'); </script>\n</svg>\n'
);
// Selector with '>' and tag after that
expect(
prettifySVG(
'<svg><style>g > path { stroke-width: 1; }</style><g></g></svg>'
)
).toBe(
'<svg>\n\t<style>g > path { stroke-width: 1; }</style>\n\t<g>\n\t</g>\n</svg>\n'
);
});
test('Bad code', () => {
expect(prettifySVG('<svg><title>Incomplete SVG</title>')).toBeNull();
expect(