Skip to content

Commit

Permalink
TASK: Simplify the dataUri with base64
Browse files Browse the repository at this point in the history
  • Loading branch information
markusguenther committed Dec 15, 2024
1 parent eb3a0a5 commit fc945ad
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 44 deletions.
21 changes: 21 additions & 0 deletions packages/utils-helpers/src/svgToDataUri.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import svgToDataUri from './svgToDataUri';

describe('svgToDataUri', () => {
it('should convert an SVG string to a valid data URI', () => {
const svgContent = `<svg width="1" height="1" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="blue"/></svg>`;
const base64Content = 'PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9ImJsdWUiLz48L3N2Zz4=';
const dataUri = svgToDataUri(svgContent);
expect(dataUri).toBe(`data:image/svg+xml;base64,${base64Content}`);
});

it('should handle special characters correctly', () => {
const svgContent = `<svg xmlns="http://www.w3.org/2000/svg"><text x="10" y="20">Héllo, Wörld!</text></svg>`;
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('<div>Not an SVG</div>')).not.toThrow();
});
});
51 changes: 7 additions & 44 deletions packages/utils-helpers/src/svgToDataUri.ts
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit fc945ad

Please sign in to comment.