mirror of
https://github.com/svg/svgo.git
synced 2025-08-01 18:46:52 +03:00
chore: apply more eslint rules (#2116)
This commit is contained in:
@ -34,6 +34,8 @@ export default [
|
||||
{
|
||||
files: ['**/*.js', '**/*.mjs'],
|
||||
rules: {
|
||||
'one-var': ['error', 'never'],
|
||||
curly: 'error',
|
||||
strict: 'error',
|
||||
},
|
||||
},
|
||||
|
@ -158,7 +158,7 @@ export const parseSvg = (data, from) => {
|
||||
|
||||
sax.onopentag = (data) => {
|
||||
/** @type {XastElement} */
|
||||
let element = {
|
||||
const element = {
|
||||
type: 'element',
|
||||
name: data.name,
|
||||
attributes: {},
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as csstree from 'css-tree';
|
||||
import * as csswhat from 'css-what';
|
||||
import { syntax } from 'csso';
|
||||
import { visit, matches } from './xast.js';
|
||||
import { matches, visit } from './xast.js';
|
||||
import {
|
||||
attrsGroups,
|
||||
inheritableAttrs,
|
||||
|
@ -3,12 +3,12 @@ import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import {
|
||||
VERSION,
|
||||
optimize as optimizeAgnostic,
|
||||
_collections,
|
||||
builtinPlugins,
|
||||
mapNodesToParents,
|
||||
optimize as optimizeAgnostic,
|
||||
querySelector,
|
||||
querySelectorAll,
|
||||
_collections,
|
||||
} from './svgo.js';
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { optimize, loadConfig } from './svgo-node.js';
|
||||
import { loadConfig, optimize } from './svgo-node.js';
|
||||
|
||||
const describeLF = os.EOL === '\r\n' ? describe.skip : describe;
|
||||
const describeCRLF = os.EOL === '\r\n' ? describe : describe.skip;
|
||||
|
@ -2,7 +2,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import colors from 'picocolors';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { encodeSVGDatauri, decodeSVGDatauri } from './tools.js';
|
||||
import { decodeSVGDatauri, encodeSVGDatauri } from './tools.js';
|
||||
import { loadConfig, optimize } from '../svgo-node.js';
|
||||
import { builtin } from '../builtin.js';
|
||||
import { SvgoParserError } from '../parser.js';
|
||||
@ -151,7 +151,7 @@ async function action(args, opts, command) {
|
||||
|
||||
if (process?.versions?.node && PKG.engines.node) {
|
||||
// @ts-expect-error We control this and ensure it is never null.
|
||||
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
||||
const nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
||||
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
|
||||
throw Error(
|
||||
`${PKG.name} requires Node.js version ${nodeVersion} or higher.`,
|
||||
@ -224,7 +224,7 @@ async function action(args, opts, command) {
|
||||
if (input.length && input[0] != '-') {
|
||||
if (output.length == 1 && checkIsDir(output[0])) {
|
||||
const dir = output[0];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
output[i] = checkIsDir(input[i])
|
||||
? input[i]
|
||||
: path.resolve(dir, path.basename(input[i]));
|
||||
@ -245,7 +245,7 @@ async function action(args, opts, command) {
|
||||
|
||||
// --folder
|
||||
if (opts.folder) {
|
||||
var outputFolder = (output && output[0]) || opts.folder;
|
||||
const outputFolder = (output && output[0]) || opts.folder;
|
||||
await optimizeFolder(config, opts.folder, outputFolder);
|
||||
}
|
||||
|
||||
@ -254,8 +254,8 @@ async function action(args, opts, command) {
|
||||
// STDIN
|
||||
if (input[0] === '-') {
|
||||
return new Promise((resolve, reject) => {
|
||||
var data = '',
|
||||
file = output[0];
|
||||
let data = '';
|
||||
const file = output[0];
|
||||
|
||||
process.stdin
|
||||
.on('data', (chunk) => (data += chunk))
|
||||
@ -274,7 +274,7 @@ async function action(args, opts, command) {
|
||||
|
||||
// --string
|
||||
} else if (opts.string) {
|
||||
var data = decodeSVGDatauri(opts.string);
|
||||
const data = decodeSVGDatauri(opts.string);
|
||||
|
||||
return processSVGData(config, null, data, output[0]);
|
||||
}
|
||||
@ -308,7 +308,7 @@ function optimizeFolder(config, dir, output) {
|
||||
*/
|
||||
function processDirectory(config, dir, files, output) {
|
||||
// take only *.svg files, recursively if necessary
|
||||
var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
|
||||
const svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
|
||||
|
||||
return svgFilesDescriptions.length
|
||||
? Promise.all(
|
||||
@ -396,8 +396,8 @@ function optimizeFile(config, file, output) {
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
function processSVGData(config, info, data, output, input = undefined) {
|
||||
var startTime = Date.now(),
|
||||
prevFileSize = Buffer.byteLength(data, 'utf8');
|
||||
const startTime = Date.now();
|
||||
const prevFileSize = Buffer.byteLength(data, 'utf8');
|
||||
|
||||
let result;
|
||||
try {
|
||||
@ -413,8 +413,8 @@ function processSVGData(config, info, data, output, input = undefined) {
|
||||
if (config.datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, config.datauri);
|
||||
}
|
||||
var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
|
||||
processingTime = Date.now() - startTime;
|
||||
const resultFileSize = Buffer.byteLength(result.data, 'utf8');
|
||||
const processingTime = Date.now() - startTime;
|
||||
|
||||
return writeOutput(input, output, result.data).then(
|
||||
function () {
|
||||
|
@ -23,7 +23,7 @@ const regReferencesBegin = /(\w+)\.[a-zA-Z]/;
|
||||
* @returns {string}
|
||||
*/
|
||||
export const encodeSVGDatauri = (str, type) => {
|
||||
var prefix = 'data:image/svg+xml';
|
||||
let prefix = 'data:image/svg+xml';
|
||||
if (!type || type === 'base64') {
|
||||
// base64
|
||||
prefix += ';base64,';
|
||||
@ -45,13 +45,15 @@ export const encodeSVGDatauri = (str, type) => {
|
||||
* @returns {string}
|
||||
*/
|
||||
export const decodeSVGDatauri = (str) => {
|
||||
var regexp = /data:image\/svg\+xml(;charset=[^;,]*)?(;base64)?,(.*)/;
|
||||
var match = regexp.exec(str);
|
||||
const regexp = /data:image\/svg\+xml(;charset=[^;,]*)?(;base64)?,(.*)/;
|
||||
const match = regexp.exec(str);
|
||||
|
||||
// plain string
|
||||
if (!match) return str;
|
||||
if (!match) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var data = match[3];
|
||||
const data = match[3];
|
||||
|
||||
if (match[2]) {
|
||||
// base64
|
||||
@ -88,13 +90,17 @@ export const cleanupOutData = (data, params, command) => {
|
||||
delimiter = ' ';
|
||||
|
||||
// no extra space in front of first number
|
||||
if (i == 0) delimiter = '';
|
||||
if (i == 0) {
|
||||
delimiter = '';
|
||||
}
|
||||
|
||||
// no extra space after arc command flags (large-arc and sweep flags)
|
||||
// a20 60 45 0 1 30 20 → a20 60 45 0130 20
|
||||
if (params.noSpaceAfterFlags && (command == 'A' || command == 'a')) {
|
||||
var pos = i % 7;
|
||||
if (pos == 4 || pos == 5) delimiter = '';
|
||||
const pos = i % 7;
|
||||
if (pos == 4 || pos == 5) {
|
||||
delimiter = '';
|
||||
}
|
||||
}
|
||||
|
||||
// remove floating-point numbers leading zeros
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { selectAll, selectOne, is } from 'css-select';
|
||||
import { is, selectAll, selectOne } from 'css-select';
|
||||
import { createAdapter } from './svgo/css-select-adapter.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('css-select').Options<XastNode & { children?: any }, XastElement>} Options
|
||||
* @typedef {import('./types.js').Visitor} Visitor
|
||||
* @typedef {import('./types.js').XastChild} XastChild
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastNode} XastNode
|
||||
* @typedef {import('./types.js').XastChild} XastChild
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').Visitor} Visitor
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { detachNodeFromParent, visit, visitSkip } from './xast.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||
*/
|
||||
|
||||
import { visit, visitSkip, detachNodeFromParent } from './xast.js';
|
||||
|
||||
/**
|
||||
* @param {XastElement[]} children
|
||||
* @returns {XastRoot}
|
||||
|
@ -133,7 +133,7 @@
|
||||
"pixelmatch": "^7.1.0",
|
||||
"playwright": "^1.51.1",
|
||||
"pngjs": "^7.0.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.5.3",
|
||||
"rimraf": "^5.0.7",
|
||||
"rollup": "^4.22.4",
|
||||
"tar-stream": "^3.1.7",
|
||||
|
166
plugins/_path.js
166
plugins/_path.js
@ -24,7 +24,7 @@ import { parsePathData, stringifyPathData } from '../lib/path.js';
|
||||
*/
|
||||
|
||||
/** @type {[number, number]} */
|
||||
var prevCtrlPoint;
|
||||
let prevCtrlPoint;
|
||||
|
||||
/**
|
||||
* Convert path string to JS representation.
|
||||
@ -34,7 +34,10 @@ var prevCtrlPoint;
|
||||
*/
|
||||
export const path2js = (path) => {
|
||||
// @ts-expect-error legacy
|
||||
if (path.pathJS) return path.pathJS;
|
||||
if (path.pathJS) {
|
||||
// @ts-expect-error legacy
|
||||
return path.pathJS;
|
||||
}
|
||||
/** @type {PathDataItem[]} */
|
||||
const pathData = []; // JS representation of the path data
|
||||
const newPathData = parsePathData(path.attributes.d);
|
||||
@ -59,8 +62,8 @@ export const path2js = (path) => {
|
||||
const convertRelativeToAbsolute = (data) => {
|
||||
/** @type {PathDataItem[]} */
|
||||
const newData = [];
|
||||
let start = [0, 0];
|
||||
let cursor = [0, 0];
|
||||
const start = [0, 0];
|
||||
const cursor = [0, 0];
|
||||
|
||||
for (let { command, args } of data) {
|
||||
args = args.slice();
|
||||
@ -259,8 +262,9 @@ export const intersects = function (path1, path2) {
|
||||
);
|
||||
});
|
||||
})
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a convex hull from points of each subpath. Has the most complexity O(n·log n).
|
||||
const hullNest1 = points1.list.map(convexHull);
|
||||
@ -268,15 +272,19 @@ export const intersects = function (path1, path2) {
|
||||
|
||||
// Check intersection of every subpath of the first path with every subpath of the second.
|
||||
return hullNest1.some(function (hull1) {
|
||||
if (hull1.list.length < 3) return false;
|
||||
if (hull1.list.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hullNest2.some(function (hull2) {
|
||||
if (hull2.list.length < 3) return false;
|
||||
if (hull2.list.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var simplex = [getSupport(hull1, hull2, [1, 0])], // create the initial simplex
|
||||
direction = minus(simplex[0]); // set the direction to point towards the origin
|
||||
const simplex = [getSupport(hull1, hull2, [1, 0])]; // create the initial simplex
|
||||
const direction = minus(simplex[0]); // set the direction to point towards the origin
|
||||
|
||||
var iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
|
||||
let iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
|
||||
|
||||
while (true) {
|
||||
if (iterations-- == 0) {
|
||||
@ -288,9 +296,13 @@ export const intersects = function (path1, path2) {
|
||||
// add a new point
|
||||
simplex.push(getSupport(hull1, hull2, direction));
|
||||
// see if the new point was on the correct side of the origin
|
||||
if (dot(direction, simplex[simplex.length - 1]) <= 0) return false;
|
||||
if (dot(direction, simplex[simplex.length - 1]) <= 0) {
|
||||
return false;
|
||||
}
|
||||
// process the simplex
|
||||
if (processSimplex(simplex, direction)) return true;
|
||||
if (processSimplex(simplex, direction)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -316,16 +328,16 @@ export const intersects = function (path1, path2) {
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function supportPoint(polygon, direction) {
|
||||
var index =
|
||||
direction[1] >= 0
|
||||
? direction[0] < 0
|
||||
? polygon.maxY
|
||||
: polygon.maxX
|
||||
: direction[0] < 0
|
||||
? polygon.minX
|
||||
: polygon.minY,
|
||||
max = -Infinity,
|
||||
value;
|
||||
let index =
|
||||
direction[1] >= 0
|
||||
? direction[0] < 0
|
||||
? polygon.maxY
|
||||
: polygon.maxX
|
||||
: direction[0] < 0
|
||||
? polygon.minX
|
||||
: polygon.minY;
|
||||
let max = -Infinity;
|
||||
let value;
|
||||
while ((value = dot(polygon.list[index], direction)) > max) {
|
||||
max = value;
|
||||
index = ++index % polygon.list.length;
|
||||
@ -343,10 +355,10 @@ function processSimplex(simplex, direction) {
|
||||
// we only need to handle to 1-simplex and 2-simplex
|
||||
if (simplex.length == 2) {
|
||||
// 1-simplex
|
||||
let a = simplex[1],
|
||||
b = simplex[0],
|
||||
AO = minus(simplex[1]),
|
||||
AB = sub(b, a);
|
||||
const a = simplex[1];
|
||||
const b = simplex[0];
|
||||
const AO = minus(simplex[1]);
|
||||
const AB = sub(b, a);
|
||||
// AO is in the same direction as AB
|
||||
if (dot(AO, AB) > 0) {
|
||||
// get the vector perpendicular to AB facing O
|
||||
@ -358,14 +370,14 @@ function processSimplex(simplex, direction) {
|
||||
}
|
||||
} else {
|
||||
// 2-simplex
|
||||
let a = simplex[2], // [a, b, c] = simplex
|
||||
b = simplex[1],
|
||||
c = simplex[0],
|
||||
AB = sub(b, a),
|
||||
AC = sub(c, a),
|
||||
AO = minus(a),
|
||||
ACB = orth(AB, AC), // the vector perpendicular to AB facing away from C
|
||||
ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
|
||||
const a = simplex[2]; // [a, b, c] = simplex
|
||||
const b = simplex[1];
|
||||
const c = simplex[0];
|
||||
const AB = sub(b, a);
|
||||
const AC = sub(c, a);
|
||||
const AO = minus(a);
|
||||
const ACB = orth(AB, AC); // the vector perpendicular to AB facing away from C
|
||||
const ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
|
||||
|
||||
if (dot(ACB, AO) > 0) {
|
||||
if (dot(AB, AO) > 0) {
|
||||
@ -388,7 +400,9 @@ function processSimplex(simplex, direction) {
|
||||
simplex.splice(0, 2); // simplex = [a]
|
||||
}
|
||||
} // region 7
|
||||
else return true;
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -425,7 +439,7 @@ function dot(v1, v2) {
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function orth(v, from) {
|
||||
var o = [-v[1], v[0]];
|
||||
const o = [-v[1], v[0]];
|
||||
return dot(o, minus(from)) < 0 ? minus(o) : o;
|
||||
}
|
||||
|
||||
@ -477,10 +491,10 @@ function gatherPoints(pathData) {
|
||||
points.list.length === 0
|
||||
? { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 }
|
||||
: points.list[points.list.length - 1];
|
||||
let prev = i === 0 ? null : pathData[i - 1];
|
||||
const prev = i === 0 ? null : pathData[i - 1];
|
||||
let basePoint =
|
||||
subPath.list.length === 0 ? null : subPath.list[subPath.list.length - 1];
|
||||
let data = pathDataItem.args;
|
||||
const data = pathDataItem.args;
|
||||
let ctrlPoint = basePoint;
|
||||
|
||||
// TODO fix null hack
|
||||
@ -580,7 +594,7 @@ function gatherPoints(pathData) {
|
||||
if (basePoint != null) {
|
||||
// Convert the arc to Bézier curves and use the same approximation
|
||||
// @ts-expect-error no idea what's going on here
|
||||
var curves = a2c.apply(0, basePoint.concat(data));
|
||||
const curves = a2c.apply(0, basePoint.concat(data));
|
||||
for (
|
||||
var cData;
|
||||
(cData = curves.splice(0, 6).map(toAbsolute)).length;
|
||||
@ -600,14 +614,18 @@ function gatherPoints(pathData) {
|
||||
0.5 * (cData[2] + cData[4]),
|
||||
0.5 * (cData[3] + cData[5]),
|
||||
]);
|
||||
if (curves.length) addPoint(subPath, (basePoint = cData.slice(-2)));
|
||||
if (curves.length) {
|
||||
addPoint(subPath, (basePoint = cData.slice(-2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Save final command coordinates
|
||||
if (data.length >= 2) addPoint(subPath, data.slice(-2));
|
||||
if (data.length >= 2) {
|
||||
addPoint(subPath, data.slice(-2));
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
@ -626,9 +644,9 @@ function convexHull(points) {
|
||||
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
|
||||
});
|
||||
|
||||
var lower = [],
|
||||
minY = 0,
|
||||
bottom = 0;
|
||||
const lower = [];
|
||||
let minY = 0;
|
||||
let bottom = 0;
|
||||
for (let i = 0; i < points.list.length; i++) {
|
||||
while (
|
||||
lower.length >= 2 &&
|
||||
@ -644,9 +662,9 @@ function convexHull(points) {
|
||||
lower.push(points.list[i]);
|
||||
}
|
||||
|
||||
var upper = [],
|
||||
maxY = points.list.length - 1,
|
||||
top = 0;
|
||||
const upper = [];
|
||||
let maxY = points.list.length - 1;
|
||||
let top = 0;
|
||||
for (let i = points.list.length; i--; ) {
|
||||
while (
|
||||
upper.length >= 2 &&
|
||||
@ -748,17 +766,17 @@ const a2c = (
|
||||
y1 = rotateY(x1, y1, -rad);
|
||||
x2 = rotateX(x2, y2, -rad);
|
||||
y2 = rotateY(x2, y2, -rad);
|
||||
var x = (x1 - x2) / 2,
|
||||
y = (y1 - y2) / 2;
|
||||
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
||||
const x = (x1 - x2) / 2;
|
||||
const y = (y1 - y2) / 2;
|
||||
let h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
||||
if (h > 1) {
|
||||
h = Math.sqrt(h);
|
||||
rx = h * rx;
|
||||
ry = h * ry;
|
||||
}
|
||||
var rx2 = rx * rx;
|
||||
var ry2 = ry * ry;
|
||||
var k =
|
||||
const rx2 = rx * rx;
|
||||
const ry2 = ry * ry;
|
||||
const k =
|
||||
(large_arc_flag == sweep_flag ? -1 : 1) *
|
||||
Math.sqrt(
|
||||
Math.abs(
|
||||
@ -786,11 +804,11 @@ const a2c = (
|
||||
cx = recursive[2];
|
||||
cy = recursive[3];
|
||||
}
|
||||
var df = f2 - f1;
|
||||
let df = f2 - f1;
|
||||
if (Math.abs(df) > _120) {
|
||||
var f2old = f2,
|
||||
x2old = x2,
|
||||
y2old = y2;
|
||||
const f2old = f2;
|
||||
const x2old = x2;
|
||||
const y2old = y2;
|
||||
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
|
||||
x2 = cx + rx * Math.cos(f2);
|
||||
y2 = cy + ry * Math.sin(f2);
|
||||
@ -802,27 +820,27 @@ const a2c = (
|
||||
]);
|
||||
}
|
||||
df = f2 - f1;
|
||||
var c1 = Math.cos(f1),
|
||||
s1 = Math.sin(f1),
|
||||
c2 = Math.cos(f2),
|
||||
s2 = Math.sin(f2),
|
||||
t = Math.tan(df / 4),
|
||||
hx = (4 / 3) * rx * t,
|
||||
hy = (4 / 3) * ry * t,
|
||||
m = [
|
||||
-hx * s1,
|
||||
hy * c1,
|
||||
x2 + hx * s2 - x1,
|
||||
y2 - hy * c2 - y1,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
];
|
||||
const c1 = Math.cos(f1);
|
||||
const s1 = Math.sin(f1);
|
||||
const c2 = Math.cos(f2);
|
||||
const s2 = Math.sin(f2);
|
||||
const t = Math.tan(df / 4);
|
||||
const hx = (4 / 3) * rx * t;
|
||||
const hy = (4 / 3) * ry * t;
|
||||
const m = [
|
||||
-hx * s1,
|
||||
hy * c1,
|
||||
x2 + hx * s2 - x1,
|
||||
y2 - hy * c2 - y1,
|
||||
x2 - x1,
|
||||
y2 - y1,
|
||||
];
|
||||
if (recursive) {
|
||||
return m.concat(res);
|
||||
} else {
|
||||
res = m.concat(res);
|
||||
var newres = [];
|
||||
for (var i = 0, n = res.length; i < n; i++) {
|
||||
const newres = [];
|
||||
for (let i = 0, n = res.length; i < n; i++) {
|
||||
newres[i] =
|
||||
i % 2
|
||||
? rotateY(res[i - 1], res[i], rad)
|
||||
|
@ -514,10 +514,10 @@ const transformToMatrix = (transform) => {
|
||||
];
|
||||
case 'rotate':
|
||||
// [cos(a), sin(a), -sin(a), cos(a), x, y]
|
||||
var cos = mth.cos(transform.data[0]),
|
||||
sin = mth.sin(transform.data[0]),
|
||||
cx = transform.data[1] || 0,
|
||||
cy = transform.data[2] || 0;
|
||||
var cos = mth.cos(transform.data[0]);
|
||||
var sin = mth.sin(transform.data[0]);
|
||||
var cx = transform.data[1] || 0;
|
||||
var cy = transform.data[2] || 0;
|
||||
return [
|
||||
cos,
|
||||
sin,
|
||||
@ -719,13 +719,13 @@ const round = (data) => {
|
||||
*/
|
||||
const smartRound = (precision, data) => {
|
||||
for (
|
||||
var i = data.length,
|
||||
let i = data.length,
|
||||
tolerance = +Math.pow(0.1, precision).toFixed(precision);
|
||||
i--;
|
||||
|
||||
) {
|
||||
if (toFixed(data[i], precision) !== data[i]) {
|
||||
var rounded = +data[i].toFixed(precision - 1);
|
||||
const rounded = +data[i].toFixed(precision - 1);
|
||||
data[i] =
|
||||
+Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance
|
||||
? +data[i].toFixed(precision)
|
||||
|
@ -7,7 +7,7 @@
|
||||
export const name = 'addAttributesToSVGElement';
|
||||
export const description = 'adds attributes to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
|
||||
const ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
|
||||
It should have a list of "attributes" or one "attribute".
|
||||
Config example:
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
export const name = 'addClassesToSVGElement';
|
||||
export const description = 'adds classnames to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
|
||||
const ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
|
||||
It should have a list of classes in "classNames" or one "className".
|
||||
Config example:
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { path2js } from './_path.js';
|
||||
import {
|
||||
transformsMultiply,
|
||||
transform2js,
|
||||
transformArc,
|
||||
transformsMultiply,
|
||||
} from './_transforms.js';
|
||||
import { referencesProps, attrsGroupsDefaults } from './_collections.js';
|
||||
import { attrsGroupsDefaults, referencesProps } from './_collections.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
|
||||
import { removeLeadingZero, includesUrlReference } from '../lib/svgo/tools.js';
|
||||
import { includesUrlReference, removeLeadingZero } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { visitSkip } from '../lib/xast.js';
|
||||
import { hasScripts, findReferences } from '../lib/svgo/tools.js';
|
||||
import { findReferences, hasScripts } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
@ -224,7 +224,7 @@ export const fn = (_root, params) => {
|
||||
// replace referenced IDs with the minified ones
|
||||
if (minify && isIdPreserved(id) === false) {
|
||||
/** @type {?string} */
|
||||
let currentIdString = null;
|
||||
let currentIdString;
|
||||
do {
|
||||
currentId = generateId(currentId);
|
||||
currentIdString = getIdString(currentId);
|
||||
|
@ -64,7 +64,7 @@ export const fn = (_root, params) => {
|
||||
// round it to the fixed precision
|
||||
let num = Number(Number(match[1]).toFixed(floatPrecision));
|
||||
/** @type {any} */
|
||||
let matchedUnit = match[3] || '';
|
||||
const matchedUnit = match[3] || '';
|
||||
/** @type {'' | keyof typeof absoluteLengths} */
|
||||
let units = matchedUnit;
|
||||
|
||||
|
@ -10,7 +10,7 @@ import { removeLeadingZero } from '../lib/svgo/tools.js';
|
||||
|
||||
export const name = 'cleanupNumericValues';
|
||||
export const description =
|
||||
'rounds numeric values to the fixed precision, removes default ‘px’ units';
|
||||
'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|%)?$/;
|
||||
@ -26,8 +26,7 @@ const absoluteLengths = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Round numeric values to the fixed precision,
|
||||
* remove default 'px' units.
|
||||
* Round numeric values to the fixed precision, remove default 'px' units.
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
@ -69,7 +68,7 @@ export const fn = (_root, params) => {
|
||||
// round it to the fixed precision
|
||||
let num = Number(Number(match[1]).toFixed(floatPrecision));
|
||||
/** @type {any} */
|
||||
let matchedUnit = match[3] || '';
|
||||
const matchedUnit = match[3] || '';
|
||||
/** @type {'' | keyof typeof absoluteLengths} */
|
||||
let units = matchedUnit;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { computeStyle, collectStylesheet } from '../lib/style.js';
|
||||
import { inheritableAttrs, elemsGroups } from './_collections.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { elemsGroups, inheritableAttrs } from './_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').Plugin} Plugin
|
||||
|
@ -121,9 +121,9 @@ export const fn = (_root, params) => {
|
||||
|
||||
// convert rgb() to long hex
|
||||
if (rgb2hex) {
|
||||
let match = val.match(regRGB);
|
||||
const match = val.match(regRGB);
|
||||
if (match != null) {
|
||||
let nums = match.slice(1, 4).map((m) => {
|
||||
const nums = match.slice(1, 4).map((m) => {
|
||||
let n;
|
||||
if (m.indexOf('%') > -1) {
|
||||
n = Math.round(parseFloat(m) * 2.55);
|
||||
@ -146,7 +146,7 @@ export const fn = (_root, params) => {
|
||||
|
||||
// convert long hex to short hex
|
||||
if (shorthex) {
|
||||
let match = regHEX.exec(val);
|
||||
const match = regHEX.exec(val);
|
||||
if (match != null) {
|
||||
val = '#' + match[0][1] + match[0][3] + match[0][5];
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { attrsGroupsDefaults, colorsProps } from './_collections.js';
|
||||
import {
|
||||
detachNodeFromParent,
|
||||
querySelectorAll,
|
||||
querySelector,
|
||||
querySelectorAll,
|
||||
} from '../lib/xast.js';
|
||||
import { computeStyle, collectStylesheet } from '../lib/style.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').Plugin} Plugin
|
||||
@ -64,7 +64,7 @@ export const fn = (root) => {
|
||||
});
|
||||
|
||||
const href = node.attributes['xlink:href'] || node.attributes['href'];
|
||||
let effectiveNode =
|
||||
const effectiveNode =
|
||||
stops.length === 0 && href != null && href.startsWith('#')
|
||||
? querySelector(root, href)
|
||||
: node;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { path2js, js2path } from './_path.js';
|
||||
import { js2path, path2js } from './_path.js';
|
||||
import { pathElems } from './_collections.js';
|
||||
import { applyTransforms } from './applyTransforms.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
@ -217,8 +217,8 @@ export const fn = (root, params) => {
|
||||
* @returns {PathDataItem[]}
|
||||
*/
|
||||
const convertToRelative = (pathData) => {
|
||||
let start = [0, 0];
|
||||
let cursor = [0, 0];
|
||||
const start = [0, 0];
|
||||
const cursor = [0, 0];
|
||||
let prevCoords = [0, 0];
|
||||
|
||||
for (let i = 0; i < pathData.length; i += 1) {
|
||||
@ -413,8 +413,8 @@ function filters(
|
||||
let next = path[index + 1];
|
||||
|
||||
if (command !== 'Z' && command !== 'z') {
|
||||
var sdata = data,
|
||||
circle;
|
||||
let sdata = data;
|
||||
let circle;
|
||||
|
||||
if (command === 's') {
|
||||
sdata = [0, 0].concat(data);
|
||||
@ -434,31 +434,31 @@ function filters(
|
||||
isConvex(sdata) &&
|
||||
(circle = findCircle(sdata))
|
||||
) {
|
||||
var r = roundData([circle.radius])[0],
|
||||
angle = findArcAngle(sdata, circle),
|
||||
sweep = sdata[5] * sdata[0] - sdata[4] * sdata[1] > 0 ? 1 : 0,
|
||||
/** @type {PathDataItem} */
|
||||
arc = {
|
||||
command: 'a',
|
||||
args: [r, r, 0, 0, sweep, sdata[4], sdata[5]],
|
||||
// @ts-expect-error
|
||||
coords: item.coords.slice(),
|
||||
// @ts-expect-error
|
||||
base: item.base,
|
||||
},
|
||||
/** @type {PathDataItem[]} */
|
||||
output = [arc],
|
||||
// relative coordinates to adjust the found circle
|
||||
/** @type {Point} */
|
||||
relCenter = [
|
||||
circle.center[0] - sdata[4],
|
||||
circle.center[1] - sdata[5],
|
||||
],
|
||||
relCircle = { center: relCenter, radius: circle.radius },
|
||||
arcCurves = [item],
|
||||
hasPrev = 0,
|
||||
suffix = '',
|
||||
nextLonghand;
|
||||
const r = roundData([circle.radius])[0];
|
||||
let angle = findArcAngle(sdata, circle);
|
||||
const sweep = sdata[5] * sdata[0] - sdata[4] * sdata[1] > 0 ? 1 : 0;
|
||||
/** @type {PathDataItem} */
|
||||
let arc = {
|
||||
command: 'a',
|
||||
args: [r, r, 0, 0, sweep, sdata[4], sdata[5]],
|
||||
// @ts-expect-error
|
||||
coords: item.coords.slice(),
|
||||
// @ts-expect-error
|
||||
base: item.base,
|
||||
};
|
||||
/** @type {PathDataItem[]} */
|
||||
const output = [arc];
|
||||
// relative coordinates to adjust the found circle
|
||||
/** @type {Point} */
|
||||
const relCenter = [
|
||||
circle.center[0] - sdata[4],
|
||||
circle.center[1] - sdata[5],
|
||||
];
|
||||
const relCircle = { center: relCenter, radius: circle.radius };
|
||||
const arcCurves = [item];
|
||||
let hasPrev = 0;
|
||||
let suffix = '';
|
||||
let nextLonghand;
|
||||
|
||||
if (
|
||||
(prev.command == 'c' &&
|
||||
@ -473,8 +473,8 @@ function filters(
|
||||
arc.args[5] = arc.coords[0] - arc.base[0];
|
||||
// @ts-expect-error
|
||||
arc.args[6] = arc.coords[1] - arc.base[1];
|
||||
var prevData = prev.command == 'a' ? prev.sdata : prev.args;
|
||||
var prevAngle = findArcAngle(prevData, {
|
||||
const prevData = prev.command == 'a' ? prev.sdata : prev.args;
|
||||
const prevAngle = findArcAngle(prevData, {
|
||||
center: [
|
||||
prevData[4] + circle.center[0],
|
||||
prevData[5] + circle.center[1],
|
||||
@ -482,7 +482,9 @@ function filters(
|
||||
radius: circle.radius,
|
||||
});
|
||||
angle += prevAngle;
|
||||
if (angle > Math.PI) arc.args[3] = 1;
|
||||
if (angle > Math.PI) {
|
||||
arc.args[3] = 1;
|
||||
}
|
||||
hasPrev = 1;
|
||||
}
|
||||
|
||||
@ -492,7 +494,7 @@ function filters(
|
||||
(next = path[++j]) && (next.command === 'c' || next.command === 's');
|
||||
|
||||
) {
|
||||
var nextData = next.args;
|
||||
let nextData = next.args;
|
||||
if (next.command == 's') {
|
||||
nextLonghand = makeLonghand(
|
||||
{ command: 's', args: next.args.slice() },
|
||||
@ -504,8 +506,12 @@ function filters(
|
||||
}
|
||||
if (isConvex(nextData) && isArc(nextData, relCircle)) {
|
||||
angle += findArcAngle(nextData, relCircle);
|
||||
if (angle - 2 * Math.PI > 1e-3) break; // more than 360°
|
||||
if (angle > Math.PI) arc.args[3] = 1;
|
||||
if (angle - 2 * Math.PI > 1e-3) {
|
||||
break;
|
||||
} // more than 360°
|
||||
if (angle > Math.PI) {
|
||||
arc.args[3] = 1;
|
||||
}
|
||||
arcCurves.push(next);
|
||||
if (2 * Math.PI - angle > 1e-3) {
|
||||
// less than 360°
|
||||
@ -550,7 +556,9 @@ function filters(
|
||||
}
|
||||
relCenter[0] -= nextData[4];
|
||||
relCenter[1] -= nextData[5];
|
||||
} else break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((stringify(output) + suffix).length < stringify(arcCurves).length) {
|
||||
@ -558,7 +566,7 @@ function filters(
|
||||
makeLonghand(path[j], path[j - 1].args);
|
||||
}
|
||||
if (hasPrev) {
|
||||
var prevArc = output.shift();
|
||||
const prevArc = output.shift();
|
||||
// @ts-expect-error
|
||||
roundData(prevArc.args);
|
||||
// @ts-expect-error
|
||||
@ -580,7 +588,9 @@ function filters(
|
||||
// filter out consumed next items
|
||||
path.splice(index + 1, arcCurves.length - 1 - hasPrev, ...output);
|
||||
}
|
||||
if (!arc) return false;
|
||||
if (!arc) {
|
||||
return false;
|
||||
}
|
||||
command = 'a';
|
||||
data = arc.args;
|
||||
// @ts-expect-error
|
||||
@ -600,7 +610,7 @@ function filters(
|
||||
command === 's' ||
|
||||
command === 'c'
|
||||
) {
|
||||
for (var i = data.length; i--; ) {
|
||||
for (let i = data.length; i--; ) {
|
||||
// @ts-expect-error
|
||||
data[i] += item.base[i % 2] - relSubpoint[i % 2];
|
||||
}
|
||||
@ -618,9 +628,11 @@ function filters(
|
||||
}
|
||||
roundData(data);
|
||||
|
||||
if (command == 'h') relSubpoint[0] += data[0];
|
||||
else if (command == 'v') relSubpoint[1] += data[0];
|
||||
else {
|
||||
if (command == 'h') {
|
||||
relSubpoint[0] += data[0];
|
||||
} else if (command == 'v') {
|
||||
relSubpoint[1] += data[0];
|
||||
} else {
|
||||
relSubpoint[0] += data[data.length - 2];
|
||||
relSubpoint[1] += data[data.length - 1];
|
||||
}
|
||||
@ -656,11 +668,15 @@ function filters(
|
||||
(command === 'c' && isCurveStraightLine(data)) ||
|
||||
(command === 's' && isCurveStraightLine(sdata))
|
||||
) {
|
||||
if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
|
||||
if (next && next.command == 's') {
|
||||
makeLonghand(next, data);
|
||||
} // fix up next curve
|
||||
command = 'l';
|
||||
data = data.slice(-2);
|
||||
} else if (command === 'q' && isCurveStraightLine(data)) {
|
||||
if (next && next.command == 't') makeLonghand(next, data); // fix up next curve
|
||||
if (next && next.command == 't') {
|
||||
makeLonghand(next, data);
|
||||
} // fix up next curve
|
||||
command = 'l';
|
||||
data = data.slice(-2);
|
||||
} else if (
|
||||
@ -708,12 +724,14 @@ function filters(
|
||||
y1 + y2 - item.base[1],
|
||||
);
|
||||
roundData(newData);
|
||||
const originalLength = cleanupOutData(data, params).length,
|
||||
newLength = cleanupOutData(newData, params).length;
|
||||
const originalLength = cleanupOutData(data, params).length;
|
||||
const newLength = cleanupOutData(newData, params).length;
|
||||
if (newLength < originalLength) {
|
||||
command = 'q';
|
||||
data = newData;
|
||||
if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
|
||||
if (next && next.command == 's') {
|
||||
makeLonghand(next, data);
|
||||
} // fix up next curve
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -877,7 +895,9 @@ function filters(
|
||||
// z resets coordinates
|
||||
relSubpoint[0] = pathBase[0];
|
||||
relSubpoint[1] = pathBase[1];
|
||||
if (prev.command === 'Z' || prev.command === 'z') return false;
|
||||
if (prev.command === 'Z' || prev.command === 'z') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (
|
||||
(command === 'Z' || command === 'z') &&
|
||||
@ -887,8 +907,9 @@ function filters(
|
||||
Math.abs(item.base[0] - item.coords[0]) < error / 10 &&
|
||||
// @ts-expect-error
|
||||
Math.abs(item.base[1] - item.coords[1]) < error / 10
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (command === 'q') {
|
||||
// @ts-expect-error
|
||||
@ -919,19 +940,21 @@ function filters(
|
||||
* @returns {PathDataItem[]}
|
||||
*/
|
||||
function convertToMixed(path, params) {
|
||||
var prev = path[0];
|
||||
let prev = path[0];
|
||||
|
||||
path = path.filter(function (item, index) {
|
||||
if (index == 0) return true;
|
||||
if (index == 0) {
|
||||
return true;
|
||||
}
|
||||
if (item.command === 'Z' || item.command === 'z') {
|
||||
prev = item;
|
||||
return true;
|
||||
}
|
||||
|
||||
var command = item.command,
|
||||
data = item.args,
|
||||
adata = data.slice(),
|
||||
rdata = data.slice();
|
||||
const command = item.command;
|
||||
const data = item.args;
|
||||
const adata = data.slice();
|
||||
const rdata = data.slice();
|
||||
|
||||
if (
|
||||
command === 'm' ||
|
||||
@ -941,7 +964,7 @@ function convertToMixed(path, params) {
|
||||
command === 's' ||
|
||||
command === 'c'
|
||||
) {
|
||||
for (var i = adata.length; i--; ) {
|
||||
for (let i = adata.length; i--; ) {
|
||||
// @ts-expect-error
|
||||
adata[i] += item.base[i % 2];
|
||||
}
|
||||
@ -961,8 +984,8 @@ function convertToMixed(path, params) {
|
||||
roundData(adata);
|
||||
roundData(rdata);
|
||||
|
||||
var absoluteDataStr = cleanupOutData(adata, params),
|
||||
relativeDataStr = cleanupOutData(rdata, params);
|
||||
const absoluteDataStr = cleanupOutData(adata, params);
|
||||
const relativeDataStr = cleanupOutData(rdata, params);
|
||||
|
||||
// Convert to absolute coordinates if it's shorter or forceAbsolutePath is true.
|
||||
// v-20 -> V0
|
||||
@ -1002,7 +1025,7 @@ function convertToMixed(path, params) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isConvex(data) {
|
||||
var center = getIntersection([
|
||||
const center = getIntersection([
|
||||
0,
|
||||
0,
|
||||
data[2],
|
||||
@ -1030,19 +1053,21 @@ function isConvex(data) {
|
||||
*/
|
||||
function getIntersection(coords) {
|
||||
// Prev line equation parameters.
|
||||
var a1 = coords[1] - coords[3], // y1 - y2
|
||||
b1 = coords[2] - coords[0], // x2 - x1
|
||||
c1 = coords[0] * coords[3] - coords[2] * coords[1], // x1 * y2 - x2 * y1
|
||||
// Next line equation parameters
|
||||
a2 = coords[5] - coords[7], // y1 - y2
|
||||
b2 = coords[6] - coords[4], // x2 - x1
|
||||
c2 = coords[4] * coords[7] - coords[5] * coords[6], // x1 * y2 - x2 * y1
|
||||
denom = a1 * b2 - a2 * b1;
|
||||
const a1 = coords[1] - coords[3]; // y1 - y2
|
||||
const b1 = coords[2] - coords[0]; // x2 - x1
|
||||
const c1 = coords[0] * coords[3] - coords[2] * coords[1]; // x1 * y2 - x2 * y1
|
||||
// Next line equation parameters
|
||||
const a2 = coords[5] - coords[7]; // y1 - y2
|
||||
const b2 = coords[6] - coords[4]; // x2 - x1
|
||||
const c2 = coords[4] * coords[7] - coords[5] * coords[6]; // x1 * y2 - x2 * y1
|
||||
const denom = a1 * b2 - a2 * b1;
|
||||
|
||||
if (!denom) return; // parallel lines haven't an intersection
|
||||
if (!denom) {
|
||||
return;
|
||||
} // parallel lines haven't an intersection
|
||||
|
||||
/** @type {Point} */
|
||||
var cross = [(b1 * c2 - b2 * c1) / denom, (a1 * c2 - a2 * c1) / -denom];
|
||||
const cross = [(b1 * c2 - b2 * c1) / denom, (a1 * c2 - a2 * c1) / -denom];
|
||||
if (
|
||||
!isNaN(cross[0]) &&
|
||||
!isNaN(cross[1]) &&
|
||||
@ -1083,7 +1108,7 @@ function strongRound(data) {
|
||||
* @returns {number[]}
|
||||
*/
|
||||
function round(data) {
|
||||
for (var i = data.length; i-- > 0; ) {
|
||||
for (let i = data.length; i-- > 0; ) {
|
||||
data[i] = Math.round(data[i]);
|
||||
}
|
||||
return data;
|
||||
@ -1098,17 +1123,20 @@ function round(data) {
|
||||
*/
|
||||
function isCurveStraightLine(data) {
|
||||
// Get line equation a·x + b·y + c = 0 coefficients a, b (c = 0) by start and end points.
|
||||
var i = data.length - 2,
|
||||
a = -data[i + 1], // y1 − y2 (y1 = 0)
|
||||
b = data[i], // x2 − x1 (x1 = 0)
|
||||
d = 1 / (a * a + b * b); // same part for all points
|
||||
let i = data.length - 2;
|
||||
const a = -data[i + 1]; // y1 − y2 (y1 = 0)
|
||||
const b = data[i]; // x2 − x1 (x1 = 0)
|
||||
const d = 1 / (a * a + b * b); // same part for all points
|
||||
|
||||
if (i <= 1 || !isFinite(d)) return false; // curve that ends at start point isn't the case
|
||||
if (i <= 1 || !isFinite(d)) {
|
||||
return false;
|
||||
} // curve that ends at start point isn't the case
|
||||
|
||||
// Distance from point (x0, y0) to the line is sqrt((c − a·x0 − b·y0)² / (a² + b²))
|
||||
while ((i -= 2) >= 0) {
|
||||
if (Math.sqrt(Math.pow(a * data[i] + b * data[i + 1], 2) * d) > error)
|
||||
if (Math.sqrt(Math.pow(a * data[i] + b * data[i + 1], 2) * d) > error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1122,11 +1150,17 @@ function isCurveStraightLine(data) {
|
||||
* @returns {number | undefined}
|
||||
*/
|
||||
function calculateSagitta(data) {
|
||||
if (data[3] === 1) return undefined;
|
||||
if (data[3] === 1) {
|
||||
return undefined;
|
||||
}
|
||||
const [rx, ry] = data;
|
||||
if (Math.abs(rx - ry) > error) return undefined;
|
||||
if (Math.abs(rx - ry) > error) {
|
||||
return undefined;
|
||||
}
|
||||
const chord = Math.hypot(data[5], data[6]);
|
||||
if (chord > rx * 2) return undefined;
|
||||
if (chord > rx * 2) {
|
||||
return undefined;
|
||||
}
|
||||
return rx - Math.sqrt(rx ** 2 - 0.25 * chord ** 2);
|
||||
}
|
||||
|
||||
@ -1185,10 +1219,10 @@ function reflectPoint(controlPoint, base) {
|
||||
* @returns {Point}
|
||||
*/
|
||||
function getCubicBezierPoint(curve, t) {
|
||||
var sqrT = t * t,
|
||||
cubT = sqrT * t,
|
||||
mt = 1 - t,
|
||||
sqrMt = mt * mt;
|
||||
const sqrT = t * t;
|
||||
const cubT = sqrT * t;
|
||||
const mt = 1 - t;
|
||||
const sqrMt = mt * mt;
|
||||
|
||||
return [
|
||||
3 * sqrMt * t * curve[0] + 3 * mt * sqrT * curve[2] + cubT * curve[4],
|
||||
@ -1203,22 +1237,25 @@ function getCubicBezierPoint(curve, t) {
|
||||
* @returns {Circle | undefined}
|
||||
*/
|
||||
function findCircle(curve) {
|
||||
var midPoint = getCubicBezierPoint(curve, 1 / 2),
|
||||
m1 = [midPoint[0] / 2, midPoint[1] / 2],
|
||||
m2 = [(midPoint[0] + curve[4]) / 2, (midPoint[1] + curve[5]) / 2],
|
||||
center = getIntersection([
|
||||
m1[0],
|
||||
m1[1],
|
||||
m1[0] + m1[1],
|
||||
m1[1] - m1[0],
|
||||
m2[0],
|
||||
m2[1],
|
||||
m2[0] + (m2[1] - midPoint[1]),
|
||||
m2[1] - (m2[0] - midPoint[0]),
|
||||
]),
|
||||
radius = center && getDistance([0, 0], center),
|
||||
const midPoint = getCubicBezierPoint(curve, 1 / 2);
|
||||
const m1 = [midPoint[0] / 2, midPoint[1] / 2];
|
||||
const m2 = [(midPoint[0] + curve[4]) / 2, (midPoint[1] + curve[5]) / 2];
|
||||
const center = getIntersection([
|
||||
m1[0],
|
||||
m1[1],
|
||||
m1[0] + m1[1],
|
||||
m1[1] - m1[0],
|
||||
m2[0],
|
||||
m2[1],
|
||||
m2[0] + (m2[1] - midPoint[1]),
|
||||
m2[1] - (m2[0] - midPoint[0]),
|
||||
]);
|
||||
const radius = center && getDistance([0, 0], center);
|
||||
const tolerance = Math.min(
|
||||
arcThreshold * error,
|
||||
// @ts-expect-error
|
||||
tolerance = Math.min(arcThreshold * error, (arcTolerance * radius) / 100);
|
||||
(arcTolerance * radius) / 100,
|
||||
);
|
||||
|
||||
if (
|
||||
center &&
|
||||
@ -1232,9 +1269,10 @@ function findCircle(curve) {
|
||||
) <= tolerance
|
||||
);
|
||||
})
|
||||
)
|
||||
) {
|
||||
// @ts-expect-error
|
||||
return { center: center, radius: radius };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1245,7 +1283,7 @@ function findCircle(curve) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isArc(curve, circle) {
|
||||
var tolerance = Math.min(
|
||||
const tolerance = Math.min(
|
||||
arcThreshold * error,
|
||||
(arcTolerance * circle.radius) / 100,
|
||||
);
|
||||
@ -1282,10 +1320,10 @@ function isArcPrev(curve, circle) {
|
||||
* @returns {number}
|
||||
*/
|
||||
function findArcAngle(curve, relCircle) {
|
||||
var x1 = -relCircle.center[0],
|
||||
y1 = -relCircle.center[1],
|
||||
x2 = curve[4] - relCircle.center[0],
|
||||
y2 = curve[5] - relCircle.center[1];
|
||||
const x1 = -relCircle.center[0];
|
||||
const y1 = -relCircle.center[1];
|
||||
const x2 = curve[4] - relCircle.center[0];
|
||||
const y2 = curve[5] - relCircle.center[1];
|
||||
|
||||
return Math.acos(
|
||||
(x1 * x2 + y1 * y2) / Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)),
|
||||
@ -1301,7 +1339,7 @@ function findArcAngle(curve, relCircle) {
|
||||
*/
|
||||
function data2Path(params, pathData) {
|
||||
return pathData.reduce(function (pathString, item) {
|
||||
var strData = '';
|
||||
let strData = '';
|
||||
if (item.args) {
|
||||
strData = cleanupOutData(roundData(item.args.slice()), params);
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ export const fn = (root, params) => {
|
||||
// Values like '100%' compute to NaN, thus running after
|
||||
// cleanupNumericValues when 'px' units has already been removed.
|
||||
// TODO: Calculate sizes from % and non-px units if possible.
|
||||
if (Number.isNaN(x - y + width - height)) return;
|
||||
if (Number.isNaN(x - y + width - height)) {
|
||||
return;
|
||||
}
|
||||
/** @type {PathDataItem[]} */
|
||||
const pathData = [
|
||||
{ command: 'M', args: [x, y] },
|
||||
@ -69,7 +71,9 @@ export const fn = (root, params) => {
|
||||
const y1 = Number(node.attributes.y1 || '0');
|
||||
const x2 = Number(node.attributes.x2 || '0');
|
||||
const y2 = Number(node.attributes.y2 || '0');
|
||||
if (Number.isNaN(x1 - y1 + x2 - y2)) return;
|
||||
if (Number.isNaN(x1 - y1 + x2 - y2)) {
|
||||
return;
|
||||
}
|
||||
/** @type {PathDataItem[]} */
|
||||
const pathData = [
|
||||
{ command: 'M', args: [x1, y1] },
|
||||
|
@ -111,8 +111,8 @@ export const fn = (_root, params) => {
|
||||
if (styles.length) {
|
||||
styles = styles.filter(function (style) {
|
||||
if (style[0]) {
|
||||
var prop = style[0].toLowerCase(),
|
||||
val = style[1];
|
||||
const prop = style[0].toLowerCase();
|
||||
let val = style[1];
|
||||
|
||||
if (rQuotedString.test(val)) {
|
||||
val = val.slice(1, -1);
|
||||
|
@ -205,12 +205,12 @@ const floatDigits = (n) => {
|
||||
* @returns {TransformItem[]}
|
||||
*/
|
||||
const convertToShorts = (transforms, params) => {
|
||||
for (var i = 0; i < transforms.length; i++) {
|
||||
for (let i = 0; i < transforms.length; i++) {
|
||||
let transform = transforms[i];
|
||||
|
||||
// convert matrix to the short aliases
|
||||
if (params.matrixToTransform && transform.name === 'matrix') {
|
||||
var decomposed = matrixToTransform(transform, params);
|
||||
const decomposed = matrixToTransform(transform, params);
|
||||
if (
|
||||
js2transform(decomposed, params).length <=
|
||||
js2transform([transform], params).length
|
||||
|
@ -2,9 +2,9 @@ import * as csstree from 'css-tree';
|
||||
import { syntax } from 'csso';
|
||||
import { attrsGroups, pseudoClasses } from './_collections.js';
|
||||
import {
|
||||
visitSkip,
|
||||
querySelectorAll,
|
||||
detachNodeFromParent,
|
||||
querySelectorAll,
|
||||
visitSkip,
|
||||
} from '../lib/xast.js';
|
||||
import { compareSpecificity, includesAttrSelector } from '../lib/style.js';
|
||||
|
||||
@ -72,7 +72,7 @@ export const fn = (root, params) => {
|
||||
* matchedElements?: XastElement[]
|
||||
* }[]}
|
||||
*/
|
||||
let selectors = [];
|
||||
const selectors = [];
|
||||
|
||||
return {
|
||||
element: {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { path2js, js2path, intersects } from './_path.js';
|
||||
import { intersects, js2path, path2js } from './_path.js';
|
||||
import { includesUrlReference } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { detachNodeFromParent, visitSkip } from '../lib/xast.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').Plugin} Plugin
|
||||
|
@ -164,7 +164,7 @@ export const fn = (_root, params, info) => {
|
||||
|
||||
const cssText = child.value;
|
||||
/** @type {?csstree.CssNode} */
|
||||
let cssAst = null;
|
||||
let cssAst;
|
||||
try {
|
||||
cssAst = csstree.parse(cssText, {
|
||||
parseValue: true,
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { elemsGroups } from './_collections.js';
|
||||
import {
|
||||
detachNodeFromParent,
|
||||
querySelector,
|
||||
visit,
|
||||
visitSkip,
|
||||
querySelector,
|
||||
detachNodeFromParent,
|
||||
} from '../lib/xast.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { parsePathData } from '../lib/path.js';
|
||||
import { hasScripts, findReferences } from '../lib/svgo/tools.js';
|
||||
import { findReferences, hasScripts } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').XastChild} XastChild
|
||||
@ -183,7 +183,9 @@ export const fn = (root, params) => {
|
||||
|
||||
if (node.name === 'use') {
|
||||
for (const attr of Object.keys(node.attributes)) {
|
||||
if (attr !== 'href' && !attr.endsWith(':href')) continue;
|
||||
if (attr !== 'href' && !attr.endsWith(':href')) {
|
||||
continue;
|
||||
}
|
||||
const value = node.attributes[attr];
|
||||
const id = value.slice(1);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
inheritableAttrs,
|
||||
attrsGroups,
|
||||
inheritableAttrs,
|
||||
presentationNonInheritableGroupAttrs,
|
||||
} from './_collections.js';
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
|
||||
export const name = 'removeNonInheritableGroupAttrs';
|
||||
export const description =
|
||||
'removes non-inheritable group’s presentational attributes';
|
||||
"removes non-inheritable group's presentational attributes";
|
||||
|
||||
/**
|
||||
* Remove non-inheritable group's "presentation" attributes.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { detachNodeFromParent, visitSkip } from '../lib/xast.js';
|
||||
import { parsePathData } from '../lib/path.js';
|
||||
import { intersects } from './_path.js';
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {
|
||||
elems,
|
||||
attrsGroups,
|
||||
elemsGroups,
|
||||
attrsGroupsDefaults,
|
||||
elems,
|
||||
elemsGroups,
|
||||
presentationNonInheritableGroupAttrs,
|
||||
} from './_collections.js';
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { detachNodeFromParent, visitSkip } from '../lib/xast.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { visit, visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { detachNodeFromParent, visit, visitSkip } from '../lib/xast.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { hasScripts } from '../lib/svgo/tools.js';
|
||||
import { elemsGroups } from './_collections.js';
|
||||
|
@ -110,7 +110,7 @@ describe('coa', function () {
|
||||
tempFolder,
|
||||
'--quiet',
|
||||
]);
|
||||
let optimizedWeight = calcFolderSvgWeight(svgFolderPath);
|
||||
const optimizedWeight = calcFolderSvgWeight(svgFolderPath);
|
||||
expect(optimizedWeight).toBeLessThanOrEqual(initWeight);
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
||||
import path from 'path';
|
||||
import { EOL } from 'os';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { VERSION, optimize, builtinPlugins } from '../../lib/svgo.js';
|
||||
import { VERSION, builtinPlugins, optimize } from '../../lib/svgo.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
|
10
yarn.lock
10
yarn.lock
@ -3952,12 +3952,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^3.2.5":
|
||||
version: 3.2.5
|
||||
resolution: "prettier@npm:3.2.5"
|
||||
"prettier@npm:^3.5.3":
|
||||
version: 3.5.3
|
||||
resolution: "prettier@npm:3.5.3"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 2ee4e1417572372afb7a13bb446b34f20f1bf1747db77cf6ccaf57a9be005f2f15c40f903d41a6b79eec3f57fff14d32a20fb6dee1f126da48908926fe43c311
|
||||
checksum: 61e97bb8e71a95d8f9c71f1fd5229c9aaa9d1e184dedb12399f76aa802fb6fdc8954ecac9df25a7f82ee7311cf8ddbd06baf5507388fc98e5b44036cc6a88a1b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -4546,7 +4546,7 @@ __metadata:
|
||||
pixelmatch: ^7.1.0
|
||||
playwright: ^1.51.1
|
||||
pngjs: ^7.0.0
|
||||
prettier: ^3.2.5
|
||||
prettier: ^3.5.3
|
||||
rimraf: ^5.0.7
|
||||
rollup: ^4.22.4
|
||||
sax: ^1.4.1
|
||||
|
Reference in New Issue
Block a user