Use getter for svg instead of path in packaged javascript version of icons (#6505)

* Use getter for 'svg' instead of 'path' in packaged javascript version of icons

* Use variable to avoid calling `escape` twice

* Convert title to HTML friendly in build script

* Update tests

* Only friendly title for SVG content

* Add equality test for SVG contents

* Add missing import

* Test using icons template

* Fix lint error

* Fix lint error in utils

* Read files synchronicly in tests

* Remove done from tests, make them pass

* Remove uneeded imports

* Remove replacements in tests

* Update with changes in develop

* Drop uneeded requirement

* Space between requirements

* Simplify encoding utility

* Fix syntax error

* Apply @ericcornelissen's suggestions

* Apply @ericcornelissen's suggestions
This commit is contained in:
Álvaro Mondéjar 2021-11-06 16:03:37 +01:00 committed by GitHub
parent 1bd58eafd7
commit 2d3485b8c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 7 deletions

View file

@ -30,7 +30,7 @@ const indexTemplate = fs.readFileSync(indexTemplateFile, UTF8);
const iconObjectTemplate = fs.readFileSync(iconObjectTemplateFile, UTF8);
const data = require(dataFile);
const { getIconSlug } = require('../utils.js');
const { getIconSlug, svgToPath, titleToHtmlFriendly } = require('../utils.js');
// Local helper functions
const escape = (value) => {
@ -54,7 +54,8 @@ const iconToObject = (icon) => {
iconObjectTemplate,
escape(icon.title),
escape(icon.slug),
escape(icon.svg),
escape(titleToHtmlFriendly(icon.title)),
escape(icon.path),
escape(icon.source),
escape(icon.hex),
icon.guidelines ? `'${escape(icon.guidelines)}'` : undefined,
@ -88,6 +89,7 @@ data.icons.forEach((icon) => {
const filename = getIconSlug(icon);
const svgFilepath = path.resolve(iconsDir, `${filename}.svg`);
icon.svg = fs.readFileSync(svgFilepath, UTF8).replace(/\r?\n/, '');
icon.path = svgToPath(icon.svg);
icon.slug = filename;
icons.push(icon);

View file

@ -1,10 +1,10 @@
{
title: '%s',
slug: '%s',
svg: '%s',
get path() {
return this.svg.match(/<path\s+d="([^"]*)/)[1];
get svg() {
return '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>%s</title><path d="' + this.path + '"/></svg>';
},
path: '%s',
source: '%s',
hex: '%s',
guidelines: %s,

View file

@ -10,6 +10,12 @@ module.exports = {
*/
getIconSlug: (icon) => icon.slug || module.exports.titleToSlug(icon.title),
/**
* Extract the path from an icon SVG content.
* @param {Object} svg The icon SVG content
**/
svgToPath: (svg) => svg.match(/<path\s+d="([^"]*)/)[1],
/**
* Converts a brand title into a slug/filename.
* @param {String} title The title to convert
@ -43,4 +49,20 @@ module.exports = {
/&(quot|amp|lt|gt);/g,
(_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]),
),
/**
* Converts a brand title (as it is seen in simple-icons.json) into a brand
* title in HTML/SVG friendly format.
* @param {String} brandTitle The title to convert
*/
titleToHtmlFriendly: (brandTitle) =>
brandTitle
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/./g, (char) => {
const charCode = char.charCodeAt(0);
return charCode > 127 ? `&#${charCode};` : char;
}),
};

View file

@ -1,9 +1,14 @@
const fs = require('fs');
const path = require('path');
const { icons } = require('../_data/simple-icons.json');
const { getIconSlug } = require('../scripts/utils.js');
const iconsDir = path.resolve(__dirname, '..', 'icons');
icons.forEach((icon) => {
const filename = getIconSlug(icon);
const subject = require(`../icons/${filename}.js`);
const svgPath = path.resolve(iconsDir, `${filename}.svg`);
test(`${icon.title} has the correct "title"`, () => {
expect(typeof subject.title).toBe('string');
@ -25,8 +30,14 @@ icons.forEach((icon) => {
expect(subject.source).toEqual(icon.source);
});
test(`${icon.title} has an "svg" value`, () => {
test(`${icon.title} has a valid "svg" value`, () => {
expect(typeof subject.svg).toBe('string');
const svgFileContents = fs
.readFileSync(svgPath, 'utf8')
.replace(/\r?\n/, '');
expect(subject.svg.substring(subject.svg.indexOf('<title>'))).toEqual(
svgFileContents.substring(svgFileContents.indexOf('<title>')),
);
});
test(`${icon.title} has a valid "path" value`, () => {

View file

@ -1,10 +1,15 @@
const path = require('path');
const fs = require('fs');
const { icons } = require('../_data/simple-icons.json');
const simpleIcons = require('../index.js');
const { getIconSlug } = require('../scripts/utils.js');
const iconsDir = path.resolve(__dirname, '..', 'icons');
icons.forEach((icon) => {
const slug = getIconSlug(icon);
const subject = simpleIcons[slug];
const svgPath = path.resolve(iconsDir, `${slug}.svg`);
test(`${icon.title} has the correct "title"`, () => {
expect(typeof subject.title).toBe('string');
@ -26,8 +31,14 @@ icons.forEach((icon) => {
expect(subject.source).toEqual(icon.source);
});
test(`${icon.title} has an "svg" value`, () => {
test(`${icon.title} has a valid "svg" value`, () => {
expect(typeof subject.svg).toBe('string');
const svgFileContents = fs
.readFileSync(svgPath, 'utf8')
.replace(/\r?\n/, '');
expect(subject.svg.substring(subject.svg.indexOf('<title>'))).toEqual(
svgFileContents.substring(svgFileContents.indexOf('<title>')),
);
});
test(`${icon.title} has a valid "path" value`, () => {