epiphany/node_modules/svgo/plugins/cleanupNumericValues.js
2023-12-09 22:48:07 -08:00

106 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
const { removeLeadingZero } = require('../lib/svgo/tools');
exports.name = 'cleanupNumericValues';
exports.description =
'rounds numeric values to the fixed precision, removes default px units';
const regNumericValues =
/^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/;
const absoluteLengths = {
// relative to px
cm: 96 / 2.54,
mm: 96 / 25.4,
in: 96,
pt: 4 / 3,
pc: 16,
px: 1,
};
/**
* Round numeric values to the fixed precision,
* remove default 'px' units.
*
* @author Kir Belevich
*
* @type {import('./plugins-types').Plugin<'cleanupNumericValues'>}
*/
exports.fn = (_root, params) => {
const {
floatPrecision = 3,
leadingZero = true,
defaultPx = true,
convertToPx = true,
} = params;
return {
element: {
enter: (node) => {
if (node.attributes.viewBox != null) {
const nums = node.attributes.viewBox.split(/\s,?\s*|,\s*/g);
node.attributes.viewBox = nums
.map((value) => {
const num = Number(value);
return Number.isNaN(num)
? value
: Number(num.toFixed(floatPrecision));
})
.join(' ');
}
for (const [name, value] of Object.entries(node.attributes)) {
// The `version` attribute is a text string and cannot be rounded
if (name === 'version') {
continue;
}
const match = value.match(regNumericValues);
// if attribute value matches regNumericValues
if (match) {
// round it to the fixed precision
let num = Number(Number(match[1]).toFixed(floatPrecision));
/**
* @type {any}
*/
let matchedUnit = match[3] || '';
/**
* @type{'' | keyof typeof absoluteLengths}
*/
let units = matchedUnit;
// convert absolute values to pixels
if (convertToPx && units !== '' && units in absoluteLengths) {
const pxNum = Number(
(absoluteLengths[units] * Number(match[1])).toFixed(
floatPrecision
)
);
if (pxNum.toString().length < match[0].length) {
num = pxNum;
units = 'px';
}
}
// and remove leading zero
let str;
if (leadingZero) {
str = removeLeadingZero(num);
} else {
str = num.toString();
}
// remove default 'px' units
if (defaultPx && units === 'px') {
units = '';
}
node.attributes[name] = str + units;
}
}
},
},
};
};