Skip to content

Commit

Permalink
fix: correctly handle svg class attribute within parseClassList (#6085
Browse files Browse the repository at this point in the history
)

* fix: handle svg class whithin

* add test

---------

Co-authored-by: Dominique Wirz <[email protected]>
  • Loading branch information
dwirz and Dominique Wirz authored Dec 25, 2024
1 parent af102ce commit 5d29255
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/runtime/vdom/set-accessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ const parseClassListRegex = /\s/;
* @param value className string, e.g. "foo bar baz"
* @returns list of classes, e.g. ["foo", "bar", "baz"]
*/
const parseClassList = (value: string | undefined | null): string[] => (!value ? [] : value.split(parseClassListRegex));
const parseClassList = (value: string | SVGAnimatedString | undefined | null): string[] => {
// Can't use `value instanceof SVGAnimatedString` because it'll break in non-browser environments
// see https://developer.mozilla.org/docs/Web/API/SVGAnimatedString for more information
if (typeof value === 'object' && 'baseVal' in value) {
value = value.baseVal;
}

if (!value) {
return [];
}

return value.split(parseClassListRegex);
};
const CAPTURE_EVENT_SUFFIX = 'Capture';
const CAPTURE_EVENT_REGEX = new RegExp(CAPTURE_EVENT_SUFFIX + '$');
32 changes: 32 additions & 0 deletions test/wdio/declarative-shadow-dom/cmp-svg.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @ts-ignore may not be existing when project hasn't been built
type HydrateModule = typeof import('../../hydrate');
let renderToString: HydrateModule['renderToString'];

describe('custom svg element', function () {
let originalConsoleError: typeof console.error;
before(async () => {
// @ts-ignore may not be existing when project hasn't been built
const mod = await import('/hydrate/index.mjs');
renderToString = mod.renderToString;
originalConsoleError = console.error;
});

after(() => {
console.error = originalConsoleError;
});

it('should render without errors', async () => {
const errorLogs: string[] = [];
console.error = (message) => errorLogs.push(message);

const { html } = await renderToString(`<custom-svg-element />`, { prettyHtml: true });
const stage = document.createElement('div');
stage.setAttribute('id', 'stage');
stage.setHTMLUnsafe(html);
document.body.appendChild(stage);

await expect($('custom-svg-element')).toHaveText('');

expect(errorLogs.length).toEqual(0);
});
});
15 changes: 15 additions & 0 deletions test/wdio/declarative-shadow-dom/cmp-svg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Component, h } from '@stencil/core';

@Component({
tag: 'custom-svg-element',
shadow: true,
})
export class CustomSvgElement {
render() {
return (
<svg viewBox="0 0 54 54">
<circle cx="8" cy="18" width="54" height="8" r="2" />
</svg>
);
}
}

0 comments on commit 5d29255

Please sign in to comment.