1
0
mirror of https://github.com/svg/svgo.git synced 2025-08-09 02:22:08 +03:00

Covert removeHiddenElems with types (#1532)

Covered removeHiddenElems plugin and big part of our code
- path parser and stringifier
- style manager
This commit is contained in:
Bogdan Chadkin
2021-08-21 14:55:05 +03:00
committed by GitHub
parent 1368f8dc93
commit e4918ccdd1
8 changed files with 205 additions and 61 deletions

View File

@@ -1,5 +1,10 @@
'use strict';
/**
* @typedef {import('./types').PathDataItem} PathDataItem
* @typedef {import('./types').PathDataCommand} PathDataCommand
*/
// Based on https://www.w3.org/TR/SVG11/paths.html#PathDataBNF
const argsCountPerCommand = {
@@ -26,14 +31,14 @@ const argsCountPerCommand = {
};
/**
* @param {string} c
* @type {(c: string) => c is PathDataCommand}
*/
const isCommand = (c) => {
return c in argsCountPerCommand;
};
/**
* @param {string} c
* @type {(c: string) => boolean}
*/
const isWsp = (c) => {
const codePoint = c.codePointAt(0);
@@ -46,7 +51,7 @@ const isWsp = (c) => {
};
/**
* @param {string} c
* @type {(c: string) => boolean}
*/
const isDigit = (c) => {
const codePoint = c.codePointAt(0);
@@ -61,9 +66,7 @@ const isDigit = (c) => {
*/
/**
* @param {string} string
* @param {number} cursor
* @return {[number, number | null]}
* @type {(string: string, cursor: number) => [number, number | null]}
*/
const readNumber = (string, cursor) => {
let i = cursor;
@@ -130,10 +133,16 @@ const readNumber = (string, cursor) => {
};
/**
* @param {string} string
* @type {(string: string) => Array<PathDataItem>}
*/
const parsePathData = (string) => {
/**
* @type {Array<PathDataItem>}
*/
const pathData = [];
/**
* @type {null | PathDataCommand}
*/
let command = null;
let args = /** @type {number[]} */ ([]);
let argsCount = 0;
@@ -232,15 +241,9 @@ const parsePathData = (string) => {
exports.parsePathData = parsePathData;
/**
* @typedef {{
* number: number;
* precision?: number;
* }} StringifyNumberOptions
* @type {(number: number, precision?: number) => string}
*/
/**
* @param {StringifyNumberOptions} param
*/
const stringifyNumber = ({ number, precision }) => {
const stringifyNumber = (number, precision) => {
if (precision != null) {
const ratio = 10 ** precision;
number = Math.round(number * ratio) / ratio;
@@ -250,31 +253,22 @@ const stringifyNumber = ({ number, precision }) => {
};
/**
* @typedef {{
* command: string;
* args: number[];
* precision?: number;
* disableSpaceAfterFlags?: boolean;
* }} StringifyArgsOptions
*/
/**
*
* Elliptical arc large-arc and sweep flags are rendered with spaces
* because many non-browser environments are not able to parse such paths
*
* @param {StringifyArgsOptions} param
* @type {(
* command: string,
* args: number[],
* precision?: number,
* disableSpaceAfterFlags?: boolean
* ) => string}
*/
const stringifyArgs = ({
command,
args,
precision,
disableSpaceAfterFlags,
}) => {
const stringifyArgs = (command, args, precision, disableSpaceAfterFlags) => {
let result = '';
let prev = '';
for (let i = 0; i < args.length; i += 1) {
const number = args[i];
const numberString = stringifyNumber({ number, precision });
const numberString = stringifyNumber(number, precision);
if (
disableSpaceAfterFlags &&
(command === 'A' || command === 'a') &&
@@ -298,21 +292,15 @@ const stringifyArgs = ({
};
/**
*
* @typedef {{
* command: string;
* args: number[];
* }} Command
*/
/**
* @typedef {{
* pathData: Command[];
* pathData: Array<PathDataItem>;
* precision?: number;
* disableSpaceAfterFlags?: boolean;
* }} StringifyPathDataOptions
*/
/**
* @param {StringifyPathDataOptions} param
* @type {(options: StringifyPathDataOptions) => string}
*/
const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
// combine sequence of the same commands
@@ -322,6 +310,9 @@ const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
if (i === 0) {
combined.push({ command, args });
} else {
/**
* @type {PathDataItem}
*/
const last = combined[combined.length - 1];
// match leading moveto with following lineto
if (i === 1) {
@@ -349,8 +340,7 @@ const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
let result = '';
for (const { command, args } of combined) {
result +=
command +
stringifyArgs({ command, args, precision, disableSpaceAfterFlags });
command + stringifyArgs(command, args, precision, disableSpaceAfterFlags);
}
return result;
};