🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

svgo

Package Overview
Dependencies
Maintainers
4
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svgo - npm Package Compare versions

Comparing version
4.0.1
to
4.0.2
+11
-7
lib/path.js

@@ -195,9 +195,9 @@ /**

const position = args.length;
if (position === 0 || position === 1) {
// allow only positive number without sign as first two arguments
if (c !== '+' && c !== '-') {
[newCursor, number] = readNumber(string, i);
}
}
if (position === 2 || position === 5 || position === 6) {
if (
position === 0 ||
position === 1 ||
position === 2 ||
position === 5 ||
position === 6
) {
[newCursor, number] = readNumber(string, i);

@@ -226,2 +226,6 @@ }

if (args.length === argsCount) {
if (command === 'A' || command === 'a') {
args[0] = Math.abs(args[0]);
args[1] = Math.abs(args[1]);
}
pathData.push({ command, args });

@@ -228,0 +232,0 @@ // subsequent moveto coordinates are treated as implicit lineto commands

@@ -5,3 +5,3 @@ import fs from 'fs';

import { fileURLToPath } from 'url';
import { decodeSVGDatauri, encodeSVGDatauri } from './tools.js';
import { decodeSVGDatauri } from './tools.js';
import { loadConfig, optimize } from '../svgo-node.js';

@@ -410,5 +410,2 @@ import { builtinPlugins } from '../builtin.js';

}
if (config.datauri) {
result.data = encodeSVGDatauri(result.data, config.datauri);
}
const resultFileSize = Buffer.byteLength(result.data, 'utf8');

@@ -415,0 +412,0 @@ const processingTime = Date.now() - startTime;

@@ -173,3 +173,3 @@ import { attrsGroups, referencesProps } from '../../plugins/_collections.js';

attrValue != null &&
attrValue.trimStart().startsWith('javascript:'),
attrValue.trimStart().toLowerCase().startsWith('javascript:'),
);

@@ -200,2 +200,14 @@

/**
* @param {string} body
* @returns {boolean}
* If body includes syntax that resembles a CSS custom property reference.
* @example
* "black" → false
* "var(--css-custom-property)" → true
*/
export const includesCssVarReference = (body) => {
return /var\s*\(\s*--/.test(body);
};
/**
* @param {string} attribute

@@ -202,0 +214,0 @@ * @param {string} value

@@ -16,2 +16,3 @@ import { AddAttributesToSVGElementParams } from '../plugins/addAttributesToSVGElement.js';

import { PrefixIdsParams } from '../plugins/prefixIds.js';
import { RemoveAttributesBySelectorParams } from '../plugins/removeAttributesBySelector.js';
import { RemoveAttrsParams } from '../plugins/removeAttrs.js';

@@ -103,3 +104,3 @@ import { RemoveCommentsParams } from '../plugins/removeComments.js';

addClassesToSVGElement: AddClassesToSVGElementParams;
removeAttributesBySelector: any;
removeAttributesBySelector: RemoveAttributesBySelectorParams;
removeAttrs: RemoveAttrsParams;

@@ -106,0 +107,0 @@ removeElementsByAttr: RemoveElementsByAttrParams;

@@ -7,2 +7,2 @@ /**

*/
export const VERSION = '4.0.1';
export const VERSION = '4.0.2';
{
"packageManager": "yarn@3.8.7",
"name": "svgo",
"version": "4.0.1",
"version": "4.0.2",
"description": "SVGO is a Node.js library and command-line application for optimizing vector images.",

@@ -6,0 +6,0 @@ "license": "MIT",

import { colorsNames, colorsProps, colorsShortNames } from './_collections.js';
import { includesUrlReference } from '../lib/svgo/tools.js';
import {
includesCssVarReference,
includesUrlReference,
} from '../lib/svgo/tools.js';

@@ -142,2 +145,3 @@ /**

!includesUrlReference(val) &&
!includesCssVarReference(val) &&
val !== 'currentColor'

@@ -144,0 +148,0 @@ ) {

@@ -158,3 +158,2 @@ import { js2path, path2js } from './_path.js';

computedStyle['stroke-linecap'].value !== 'butt');
const maybeHasStrokeAndLinecap = maybeHasStroke && maybeHasLinecap;
const isSafeToUseZ = maybeHasStroke

@@ -166,2 +165,15 @@ ? computedStyle['stroke-linecap']?.type === 'static' &&

: true;
const isSafeToRemove = (
/** @type {boolean} */ isFirstDraw,
/** @type {boolean} */ safeIfNotFirstDraw,
) => {
if (!maybeHasStroke) {
return true;
}
if (isFirstDraw) {
return !maybeHasLinecap;
} else {
return safeIfNotFirstDraw;
}
};

@@ -179,3 +191,3 @@ let data = path2js(node);

isSafeToUseZ,
maybeHasStrokeAndLinecap,
isSafeToRemove,
hasMarkerMid,

@@ -384,10 +396,6 @@ });

* @param {InternalParams} params
* @param {{ isSafeToUseZ: boolean, maybeHasStrokeAndLinecap: boolean, hasMarkerMid: boolean }} param2
* @param {{ isSafeToUseZ: boolean, isSafeToRemove: (isFirstDraw: boolean, safeIfNotFirstDraw: boolean) => boolean, hasMarkerMid: boolean }} param2
* @returns {import('../lib/types.js').PathDataItem[]}
*/
function filters(
path,
params,
{ isSafeToUseZ, maybeHasStrokeAndLinecap, hasMarkerMid },
) {
function filters(path, params, { isSafeToUseZ, isSafeToRemove, hasMarkerMid }) {
const stringify = data2Path.bind(null, params);

@@ -669,16 +677,23 @@ const relSubpoint = [0, 0];

data = data.slice(-2);
} else if (command === 'q' && isCurveStraightLine(data)) {
if (next && next.command == 't') {
} else if (
(command === 'q' && isCurveStraightLine(data)) ||
(command === 't' && prev.command !== 'q' && prev.command !== 't')
) {
if (command == 'q' && next && next.command == 't') {
makeLonghand(next, data);
} // fix up next curve
if (command == 't' && next && next.command == 't') {
next.command = 'q';
next.args.unshift(
// @ts-expect-error
// prettier-ignore
(2 * item.coords[0] - item.base[0]) - item.coords[0],
// @ts-expect-error
// prettier-ignore
(2 * item.coords[1] - item.base[1]) - item.coords[1],
);
} // fix up next curve
command = 'l';
data = data.slice(-2);
} else if (
command === 't' &&
prev.command !== 'q' &&
prev.command !== 't'
) {
command = 'l';
data = data.slice(-2);
} else if (
command === 'a' &&

@@ -843,3 +858,6 @@ (data[0] === 0 ||

// remove useless non-first path segments
if (params.removeUseless && !maybeHasStrokeAndLinecap) {
if (
params.removeUseless &&
isSafeToRemove(prev.command == 'm' || prev.command == 'M', true)
) {
// l 0,0 / h 0 / v 0 / q 0,0 0,0 / t 0,0 / c 0,0 0,0 0,0 / s 0,0 0,0

@@ -900,3 +918,6 @@ if (

params.removeUseless &&
isSafeToUseZ &&
isSafeToRemove(
prev.command == 'm' || prev.command == 'M',
isSafeToUseZ,
) &&
// @ts-expect-error

@@ -903,0 +924,0 @@ Math.abs(item.base[0] - item.coords[0]) < error / 10 &&

@@ -52,4 +52,4 @@ import { collectStylesheet, computeStyle } from '../lib/style.js';

/** @type {import('../lib/types.js').XastChild[]} */
const elementsToRemove = [];
/** @type {Set<import('../lib/types.js').XastChild>} */
const elementsToRemove = new Set();
let prevChild = node.children[0];

@@ -148,3 +148,3 @@ let prevPathData = null;

prevPathData.push(...currentPathData);
elementsToRemove.push(child);
elementsToRemove.add(child);
continue;

@@ -166,3 +166,3 @@ }

node.children = node.children.filter(
(child) => !elementsToRemove.includes(child),
(child) => !elementsToRemove.has(child),
);

@@ -169,0 +169,0 @@ },

import { querySelectorAll } from '../lib/xast.js';
/**
* @typedef AttributesBySelector
* @property {string} selector
* @property {string | string[]} attributes
* @property {never} selectors
*/
/**
* @typedef AttributesBySelectors
* @property {never} selector
* @property {never} attributes
* @property {Array<AttributesBySelector>} selectors
*/
/**
* @typedef {(AttributesBySelector | AttributesBySelectors)} RemoveAttributesBySelectorParams
*/
export const name = 'removeAttributesBySelector';

@@ -7,2 +25,6 @@ export const description =

const ENOATTRS = `Warning: The plugin "removeAttributesBySelector" is missing parameters.
It should have a list of "selectors", or one "selector" and one "attributes".
Without either, the plugin is a noop.`;
/**

@@ -17,3 +39,3 @@ * Removes attributes of elements that match a css selector.

* params: {
* selector: "[fill='#00ff00']"
* selector: "[fill='#00ff00']",
* attributes: "fill"

@@ -72,9 +94,17 @@ * }

*
* @link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors
* @link https://developer.mozilla.org/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors
*
* @author Bradley Mease
*
* @type {import('../lib/types.js').Plugin<any>}
* @type {import('../lib/types.js').Plugin<RemoveAttributesBySelectorParams>}
*/
export const fn = (root, params) => {
if (
!Array.isArray(params.selectors) &&
(!params.selector || !params.attributes)
) {
console.warn(ENOATTRS);
return null;
}
const selectors = Array.isArray(params.selectors)

@@ -81,0 +111,0 @@ ? params.selectors

@@ -16,3 +16,34 @@ import { attrsGroups } from './_collections.js';

/** Namespaces that support executable <script> elements. */
const SCRIPT_NAMESPACES = [
'http://www.w3.org/2000/svg',
'http://www.w3.org/1999/xhtml',
];
/**
* @param {string} elem
* @param {string} targetElem
* @param {ReadonlyMap<string, string[]>} prefixes
* @param {string[]} targetNamespaces
* @returns {boolean}
*/
function isNamespaceAwareElem(elem, targetElem, prefixes, targetNamespaces) {
if (elem === targetElem) {
return true;
}
if (elem.includes(':')) {
const [prefix, effectiveTag] = elem.split(':', 2);
if (targetElem === effectiveTag) {
const namespaces = /** @type {string[]} */ (prefixes.get(prefix));
const namespace = namespaces[namespaces.length - 1];
return targetNamespaces.includes(namespace);
}
}
return false;
}
/**
* Remove scripts.

@@ -26,6 +57,30 @@ *

export const fn = () => {
/**
* Map of XML namespace prefixes to the XML namespace. Each value is a stack
* as XML namespaces can be pushed to in children elements and revert back
* previous namespace when we exit that node.
*
* @type {Map<string, string[]>} */
const prefixes = new Map();
return {
element: {
enter: (node, parentNode) => {
if (node.name === 'script') {
for (const [k, v] of Object.entries(node.attributes)) {
if (!k.startsWith('xmlns:')) {
continue;
}
const prefix = k.slice(6);
if (!prefixes.has(prefix)) {
prefixes.set(prefix, [v]);
} else {
/** @type {string[]} */ (prefixes.get(prefix)).push(v);
}
}
if (
isNamespaceAwareElem(node.name, 'script', prefixes, SCRIPT_NAMESPACES)
) {
detachNodeFromParent(node, parentNode);

@@ -42,2 +97,11 @@ return;

exit: (node, parentNode) => {
for (const k of Object.keys(node.attributes)) {
if (!k.startsWith('xmlns:')) {
continue;
}
const prefix = k.slice(6);
/** @type {string[]} */ (prefixes.get(prefix)).pop();
}
if (node.name !== 'a') {

@@ -51,3 +115,6 @@ return;

node.attributes[attr] == null ||
!node.attributes[attr].trimStart().startsWith('javascript:')
!node.attributes[attr]
.trimStart()
.toLowerCase()
.startsWith('javascript:')
) {

@@ -54,0 +121,0 @@ continue;

@@ -7,2 +7,3 @@ export function encodeSVGDatauri(str: string, type?: import("../types.js").DataUri | undefined): string;

export function includesUrlReference(body: string): boolean;
export function includesCssVarReference(body: string): boolean;
export function findReferences(attribute: string, value: string): string[];

@@ -9,0 +10,0 @@ export function toFixed(num: number, precision: number): number;

@@ -16,2 +16,3 @@ import { AddAttributesToSVGElementParams } from '../plugins/addAttributesToSVGElement.js';

import { PrefixIdsParams } from '../plugins/prefixIds.js';
import { RemoveAttributesBySelectorParams } from '../plugins/removeAttributesBySelector.js';
import { RemoveAttrsParams } from '../plugins/removeAttrs.js';

@@ -99,3 +100,3 @@ import { RemoveCommentsParams } from '../plugins/removeComments.js';

addClassesToSVGElement: AddClassesToSVGElementParams;
removeAttributesBySelector: any;
removeAttributesBySelector: RemoveAttributesBySelectorParams;
removeAttrs: RemoveAttrsParams;

@@ -102,0 +103,0 @@ removeElementsByAttr: RemoveElementsByAttrParams;

@@ -0,1 +1,16 @@

/**
* @typedef AttributesBySelector
* @property {string} selector
* @property {string | string[]} attributes
* @property {never} selectors
*/
/**
* @typedef AttributesBySelectors
* @property {never} selector
* @property {never} attributes
* @property {Array<AttributesBySelector>} selectors
*/
/**
* @typedef {(AttributesBySelector | AttributesBySelectors)} RemoveAttributesBySelectorParams
*/
export const name: "removeAttributesBySelector";

@@ -12,3 +27,3 @@ export const description: "removes attributes of elements that match a css selector";

* params: {
* selector: "[fill='#00ff00']"
* selector: "[fill='#00ff00']",
* attributes: "fill"

@@ -67,8 +82,19 @@ * }

*
* @link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors
* @link https://developer.mozilla.org/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors
*
* @author Bradley Mease
*
* @type {import('../lib/types.js').Plugin<any>}
* @type {import('../lib/types.js').Plugin<RemoveAttributesBySelectorParams>}
*/
export const fn: import("../lib/types.js").Plugin<any>;
export const fn: import("../lib/types.js").Plugin<RemoveAttributesBySelectorParams>;
export type AttributesBySelector = {
selector: string;
attributes: string | string[];
selectors: never;
};
export type AttributesBySelectors = {
selector: never;
attributes: never;
selectors: Array<AttributesBySelector>;
};
export type RemoveAttributesBySelectorParams = (AttributesBySelector | AttributesBySelectors);

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display