From cb9322c763b5cd8e43afe77d30e86a0b7d72f894 Mon Sep 17 00:00:00 2001 From: Michael Stramel Date: Mon, 25 Nov 2024 12:27:01 -0800 Subject: [PATCH] fix: handle other elements before the `svg` element (#12516) * fix multiple root nodes * add changeset * remove conditional * handle no svg case --- .changeset/eight-seahorses-attend.md | 5 ++ packages/astro/src/assets/utils/svg.ts | 8 +- packages/astro/test/core-image-svg.test.js | 11 +++ .../core-image-svg/src/assets/dragon.svg | 75 +++++++++++++++++++ .../core-image-svg/src/pages/strip.astro | 4 + 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 .changeset/eight-seahorses-attend.md create mode 100644 packages/astro/test/fixtures/core-image-svg/src/assets/dragon.svg diff --git a/.changeset/eight-seahorses-attend.md b/.changeset/eight-seahorses-attend.md new file mode 100644 index 0000000000..72ead3c15e --- /dev/null +++ b/.changeset/eight-seahorses-attend.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Handle multiple root nodes on SVG files diff --git a/packages/astro/src/assets/utils/svg.ts b/packages/astro/src/assets/utils/svg.ts index 6f9c54381c..bb6d944f97 100644 --- a/packages/astro/src/assets/utils/svg.ts +++ b/packages/astro/src/assets/utils/svg.ts @@ -5,7 +5,13 @@ import type { ImageMetadata } from '../types.js'; function parseSvg(contents: string) { const root = parse(contents); - const [{ attributes, children }] = root.children; + const svgNode = root.children.find( + ({ name, type }: { name: string; type: number }) => type === 1 /* Element */ && name === 'svg', + ); + if (!svgNode) { + throw new Error('SVG file does not contain an element'); + } + const { attributes, children } = svgNode; const body = renderSync({ ...root, children }); return { attributes, body }; diff --git a/packages/astro/test/core-image-svg.test.js b/packages/astro/test/core-image-svg.test.js index 6b720b094b..1252328d86 100644 --- a/packages/astro/test/core-image-svg.test.js +++ b/packages/astro/test/core-image-svg.test.js @@ -273,6 +273,17 @@ describe('astro:assets - SVG Components', () => { assert.equal(!!$svg.attr('xmlns:xlink'), false); assert.equal(!!$svg.attr('version'), false); }); + it('ignores additional root level nodes', () => { + let $svg = $('#additionalNodes'); + // Ensure we only have the svg node + assert.equal($svg.children().length, 1); + assert.equal($svg.children()[0].name, 'svg'); + $svg = $svg.children('svg'); + assert.equal($svg.length, 1); + assert.equal(!!$svg.attr('xmlns'), false); + assert.equal(!!$svg.attr('xmlns:xlink'), false); + assert.equal(!!$svg.attr('version'), false); + }); }); describe('additional props', () => { let $; diff --git a/packages/astro/test/fixtures/core-image-svg/src/assets/dragon.svg b/packages/astro/test/fixtures/core-image-svg/src/assets/dragon.svg new file mode 100644 index 0000000000..7338076c4e --- /dev/null +++ b/packages/astro/test/fixtures/core-image-svg/src/assets/dragon.svg @@ -0,0 +1,75 @@ + + + + + diff --git a/packages/astro/test/fixtures/core-image-svg/src/pages/strip.astro b/packages/astro/test/fixtures/core-image-svg/src/pages/strip.astro index 744b9cc8e1..d31f9c0736 100644 --- a/packages/astro/test/fixtures/core-image-svg/src/pages/strip.astro +++ b/packages/astro/test/fixtures/core-image-svg/src/pages/strip.astro @@ -1,5 +1,6 @@ --- import Alpine from '~/assets/alpine-multi-color.svg' +import Dragon from '~/assets/dragon.svg' --- @@ -9,5 +10,8 @@ import Alpine from '~/assets/alpine-multi-color.svg'
+
+ +