diff --git a/client/src/utils/__tests__/svg.test.ts b/client/src/utils/__tests__/svg.test.ts index 6d9b05f6bf..9b21fd1bdd 100644 --- a/client/src/utils/__tests__/svg.test.ts +++ b/client/src/utils/__tests__/svg.test.ts @@ -118,6 +118,24 @@ describe('isMonochromeSvg', () => { ''; expect(isMonochromeSvg(svg)).toBe(true); }); + + it('rejects a background rect using root width/height when no viewBox is present', () => { + const svg = + ''; + expect(isMonochromeSvg(svg)).toBe(false); + }); + + it('rejects a background rect when root dimensions carry units', () => { + const svg = + ''; + expect(isMonochromeSvg(svg)).toBe(false); + }); + + it('does not confuse stroke-width with the canvas width', () => { + const svg = + ''; + expect(isMonochromeSvg(svg)).toBe(false); + }); }); }); diff --git a/client/src/utils/svg.ts b/client/src/utils/svg.ts index 454c02da9b..01aad53a9e 100644 --- a/client/src/utils/svg.ts +++ b/client/src/utils/svg.ts @@ -104,13 +104,27 @@ function extractColors(svg: string): string[] { } const VIEWBOX_REGEX = /viewBox\s*=\s*["']\s*[-\d.]+\s+[-\d.]+\s+([\d.]+)\s+([\d.]+)/i; +const SVG_TAG_REGEX = /]*>/i; const RECT_REGEX = /]*>/gi; function getAttr(tag: string, name: string): string | null { - const match = tag.match(new RegExp(`\\b${name}\\s*=\\s*["']([^"']*)["']`, 'i')); + const match = tag.match(new RegExp(`(?` at the origin spanning the - * viewBox). Such SVGs cannot be tinted via a CSS mask, since the opaque + * canvas). Such SVGs cannot be tinted via a CSS mask, since the opaque * background fills the whole area with the tint color instead of the glyph. + * Canvas dimensions come from the viewBox, falling back to the root `` + * width and height when no viewBox is present. */ function hasOpaqueBackground(svg: string): boolean { const viewBox = svg.match(VIEWBOX_REGEX); - const width = viewBox ? parseFloat(viewBox[1]) : null; - const height = viewBox ? parseFloat(viewBox[2]) : null; + const width = viewBox ? parseFloat(viewBox[1]) : rootDimension(svg, 'width'); + const height = viewBox ? parseFloat(viewBox[2]) : rootDimension(svg, 'height'); const rects = svg.match(RECT_REGEX) ?? []; for (const rect of rects) {