From fc945ad107638deb2d716020c486bca935d2f8b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gu=CC=88nther?= Date: Sun, 15 Dec 2024 20:29:35 +0100 Subject: [PATCH] TASK: Simplify the dataUri with base64 --- .../utils-helpers/src/svgToDataUri.spec.js | 21 ++++++++ packages/utils-helpers/src/svgToDataUri.ts | 51 +++---------------- 2 files changed, 28 insertions(+), 44 deletions(-) create mode 100644 packages/utils-helpers/src/svgToDataUri.spec.js diff --git a/packages/utils-helpers/src/svgToDataUri.spec.js b/packages/utils-helpers/src/svgToDataUri.spec.js new file mode 100644 index 0000000000..662040a8eb --- /dev/null +++ b/packages/utils-helpers/src/svgToDataUri.spec.js @@ -0,0 +1,21 @@ +import svgToDataUri from './svgToDataUri'; + +describe('svgToDataUri', () => { + it('should convert an SVG string to a valid data URI', () => { + const svgContent = ``; + const base64Content = 'PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9ImJsdWUiLz48L3N2Zz4='; + const dataUri = svgToDataUri(svgContent); + expect(dataUri).toBe(`data:image/svg+xml;base64,${base64Content}`); + }); + + it('should handle special characters correctly', () => { + const svgContent = `Héllo, Wörld!`; + const base64Content = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0ZXh0IHg9IjEwIiB5PSIyMCI+SMOpbGxvLCBXw7ZybGQhPC90ZXh0Pjwvc3ZnPg=='; + const dataUri = svgToDataUri(svgContent); + expect(dataUri).toBe(`data:image/svg+xml;base64,${base64Content}`); + }); + + it('should throw an error for invalid SVG input', () => { + expect(() => svgToDataUri('
Not an SVG
')).not.toThrow(); + }); +}); diff --git a/packages/utils-helpers/src/svgToDataUri.ts b/packages/utils-helpers/src/svgToDataUri.ts index fcd0465bd7..de56ffa1cd 100644 --- a/packages/utils-helpers/src/svgToDataUri.ts +++ b/packages/utils-helpers/src/svgToDataUri.ts @@ -1,47 +1,10 @@ -const REGEX = { - whitespace: /\s+/g, - urlHexPairs: /%[\dA-F]{2}/g, - quotes: /"/g +/** + * Function to convert an SVG content string to a tiny data URI using base64 encoding. + * @param svgContent + */ +const svgToDataUri = (svgContent: string): string => { + const base64EncodedSVG = btoa(unescape(encodeURIComponent(svgContent))); + return `data:image/svg+xml;base64,${base64EncodedSVG}`; }; -// Function to collapse whitespace in a string -const collapseWhitespace = (str: string): string => - str.trim().replace(REGEX.whitespace, ' '); - -// Function to encode data for a URI payload -const dataURIPayload = (string: string): string => - encodeURIComponent(string).replace(REGEX.urlHexPairs, specialHexEncode); - -// Function to handle special hex encoding -const specialHexEncode = (match: string): string => { - switch (match) { - case '%20': - return ' '; - case '%3D': - return '='; - case '%3A': - return ':'; - case '%2F': - return '/'; - default: - return match.toLowerCase(); // Compresses better - } -}; - -// Function to convert an SVG string to a tiny data URI -const svgToDataUri = (svgString: string): string => { - // Strip the Byte-Order Mark if the SVG has one - if (svgString.charCodeAt(0) === 0xfeff) { - svgString = svgString.slice(1); - } - - const body = collapseWhitespace(svgString); - return `data:image/svg+xml,${dataURIPayload(body)}`; -}; - -// Add a static method to handle srcset conversions -svgToDataUri.toSrcset = (svgString: string): string => - svgToDataUri(svgString).replace(/ /g, '%20'); - -// Export the function as the default export export default svgToDataUri;