diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index e09ac4c74..000000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-# These are supported funding model platforms
-
-open_collective: svgo
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index 7a6e08a62..000000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Security Policy
-
-## Reporting a Vulnerability
-
-Please report security vulnerabilities to [trysound@yandex.ru](mailto:trysound@yandex.ru).
diff --git a/docs/03-plugins/convert-path-data.mdx b/docs/03-plugins/convert-path-data.mdx
index 23ca9e7e0..66848688f 100644
--- a/docs/03-plugins/convert-path-data.mdx
+++ b/docs/03-plugins/convert-path-data.mdx
@@ -30,6 +30,9 @@ svgo:
transformPrecision:
description: Number of decimal places to round to, using conventional rounding rules.
default: 5
+ smartArcRounding:
+ description: Round the radius of circular arcs when the effective change is under the error. The effective change is determined using the sagitta of the arc.
+ default: true
removeUseless:
description: Remove redundant path commands that don't draw anything.
default: true
diff --git a/docs/03-plugins/merge-text.mdx b/docs/03-plugins/merge-text.mdx
new file mode 100644
index 000000000..38b19d2ae
--- /dev/null
+++ b/docs/03-plugins/merge-text.mdx
@@ -0,0 +1,15 @@
+---
+title: Merge Text
+svgo:
+ pluginId: mergeText
+---
+
+Merge adjacent `` elements and remove `` when it is the only child of a `` element.
+
+If the SVG contains any `
+
+
+@@@
+
+
diff --git a/test/plugins/mergeText.07.svg b/test/plugins/mergeText.07.svg
new file mode 100644
index 000000000..0b2284a19
--- /dev/null
+++ b/test/plugins/mergeText.07.svg
@@ -0,0 +1,20 @@
+Do not collapse if present.
+
+===
+
+
+
+@@@
+
+
diff --git a/test/plugins/mergeText.08.svg b/test/plugins/mergeText.08.svg
new file mode 100644
index 000000000..2feb9474f
--- /dev/null
+++ b/test/plugins/mergeText.08.svg
@@ -0,0 +1,17 @@
+Don't merge elements with children.
+
+===
+
+
+
+@@@
+
+
diff --git a/test/plugins/prefixIds.test.js b/test/plugins/prefixIds.test.js
index 97f1a8fd1..8ae2b33b8 100644
--- a/test/plugins/prefixIds.test.js
+++ b/test/plugins/prefixIds.test.js
@@ -8,17 +8,17 @@ test('should extract prefix from path basename', () => {
optimize(svg, {
plugins: ['prefixIds'],
}).data,
- ).toEqual(``);
+ ).toBe(``);
expect(
optimize(svg, {
plugins: ['prefixIds'],
path: 'input.svg',
}).data,
- ).toEqual(``);
+ ).toBe(``);
expect(
optimize(svg, {
plugins: ['prefixIds'],
path: 'path/to/input.svg',
}).data,
- ).toEqual(``);
+ ).toBe(``);
});
diff --git a/test/regression-extract.js b/test/regression-extract.js
index 2c0e6232f..e5a594e65 100644
--- a/test/regression-extract.js
+++ b/test/regression-extract.js
@@ -73,7 +73,7 @@ const extractTarGz = async (url, baseDir, include) => {
(async () => {
try {
- console.info('Download W3C SVG 1.1 Test Suite and extract SVG files');
+ console.info('Downloading W3C SVG 1.1 Test Suite and extracting files');
await extractTarGz(
'https://www.w3.org/Graphics/SVG/Test/20110816/archives/W3C_SVG_11_TestSuite.tar.gz',
path.join(__dirname, 'regression-fixtures', 'w3c-svg-11-test-suite'),
diff --git a/test/svg2js/_index.test.js b/test/svg2js/_index.test.js
index 77c9075fd..ece064284 100644
--- a/test/svg2js/_index.test.js
+++ b/test/svg2js/_index.test.js
@@ -22,7 +22,7 @@ describe('svg2js', function () {
describe('root', function () {
it('should exist', function () {
- expect(root).toEqual(expect.anything());
+ expect(root).toStrictEqual(expect.anything());
});
it('should be an instance of Object', function () {
@@ -45,7 +45,7 @@ describe('svg2js', function () {
});
it('the first node should be instruction', () => {
- expect(root.children[0]).toEqual({
+ expect(root.children[0]).toStrictEqual({
type: 'instruction',
name: 'xml',
value: 'version="1.0" encoding="utf-8"',
@@ -53,7 +53,7 @@ describe('svg2js', function () {
});
it('the second node should be comment', () => {
- expect(root.children[1]).toEqual({
+ expect(root.children[1]).toStrictEqual({
type: 'comment',
value:
'Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)',
@@ -61,7 +61,7 @@ describe('svg2js', function () {
});
it('the third node should be doctype', () => {
- expect(root.children[2]).toEqual({
+ expect(root.children[2]).toStrictEqual({
type: 'doctype',
name: 'svg',
data: {
@@ -73,7 +73,7 @@ describe('svg2js', function () {
describe('name', function () {
it('should have property name: "svg"', function () {
- expect(root.children[3]).toEqual(
+ expect(root.children[3]).toStrictEqual(
expect.objectContaining({
name: 'svg',
}),
@@ -83,7 +83,7 @@ describe('svg2js', function () {
describe('children', function () {
it('should exist', function () {
- expect(root.children[3].children).toEqual(expect.anything());
+ expect(root.children[3].children).toStrictEqual(expect.anything());
});
it('should be an instance of Array', function () {
@@ -98,7 +98,7 @@ describe('svg2js', function () {
describe('text nodes', function () {
it('should contain preserved whitespace', function () {
const textNode = root.children[3].children[1].children[0].children[1];
- expect(textNode.children[0].value).toEqual(' test ');
+ expect(textNode.children[0].value).toBe(' test ');
});
});
});
diff --git a/test/svgo/_index.test.js b/test/svgo/_index.test.js
index a9e5f06c7..9d922852d 100644
--- a/test/svgo/_index.test.js
+++ b/test/svgo/_index.test.js
@@ -24,24 +24,24 @@ describe('svgo', () => {
plugins: [],
js2svg: { pretty: true, indent: 2 },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should handle plugins order properly', async () => {
const [original, expected] = await parseFixture('plugins-order.svg');
const result = optimize(original, { path: 'input.svg' });
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should handle empty svg tag', async () => {
const result = optimize('', { path: 'input.svg' });
- expect(result.data).toEqual('');
+ expect(result.data).toBe('');
});
it('should preserve style specificity over attributes', async () => {
- const [original, expected] = await parseFixture('style-specifity.svg');
+ const [original, expected] = await parseFixture('style-specificity.svg');
const result = optimize(original, {
path: 'input.svg',
js2svg: { pretty: true },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should inline entities', async () => {
const [original, expected] = await parseFixture('entities.svg');
@@ -50,7 +50,7 @@ describe('svgo', () => {
plugins: [],
js2svg: { pretty: true },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should preserve whitespaces between tspan tags', async () => {
const [original, expected] = await parseFixture('whitespaces.svg');
@@ -58,7 +58,7 @@ describe('svgo', () => {
path: 'input.svg',
js2svg: { pretty: true },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should preserve "to" keyframe selector', async () => {
const [original, expected] = await parseFixture('keyframe-selectors.svg');
@@ -66,14 +66,14 @@ describe('svgo', () => {
path: 'input.svg',
js2svg: { pretty: true },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should not trim whitespace at start and end of pre element', async () => {
const [original, expected] = await parseFixture('pre-element.svg');
const result = optimize(original, {
path: 'input.svg',
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
it('should not add whitespace in pre element', async () => {
const [original, expected] = await parseFixture('pre-element-pretty.svg');
@@ -81,6 +81,6 @@ describe('svgo', () => {
path: 'input.svg',
js2svg: { pretty: true },
});
- expect(normalize(result.data)).toEqual(expected);
+ expect(normalize(result.data)).toStrictEqual(expected);
});
});
diff --git a/test/svgo/style-specifity.svg b/test/svgo/style-specificity.svg
similarity index 100%
rename from test/svgo/style-specifity.svg
rename to test/svgo/style-specificity.svg
diff --git a/yarn.lock b/yarn.lock
index 8baf0bdf7..e6b23d23c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -976,19 +976,19 @@ __metadata:
languageName: node
linkType: hard
-"@types/css-tree@npm:*, @types/css-tree@npm:^2.0.0":
- version: 2.0.0
- resolution: "@types/css-tree@npm:2.0.0"
- checksum: 52d89f5c52c6ec5feac674a3f28f35994211f26c662cc8718f21ebabad992329e8c810da1e070aa61c49f89e92cd5ef7b460e81de52f0d0f5973618d87ebc3ae
+"@types/css-tree@npm:*, @types/css-tree@npm:^2.3.4":
+ version: 2.3.4
+ resolution: "@types/css-tree@npm:2.3.4"
+ checksum: b06173d3ae048b74e7030cceae01d3d6e5589f7348e8e4b907427f91baeda76807bbde8c5be4c41e22b952268b46edcba7ab96e16efedb2d0b37ce2bf90d1835
languageName: node
linkType: hard
-"@types/csso@npm:~5.0.3":
- version: 5.0.3
- resolution: "@types/csso@npm:5.0.3"
+"@types/csso@npm:^5.0.4":
+ version: 5.0.4
+ resolution: "@types/csso@npm:5.0.4"
dependencies:
"@types/css-tree": "*"
- checksum: 3d299ea755732f9b913cfb3d94849e173cd1019559058af0a372aa1ca8f48a3c63aa74932fdfa2f2f25ee78255a115feaaec01ae4fe9578e76b7c4acd8ae3f2a
+ checksum: 606ea4de171e807ffc8908f7ffec774c8a40f3c81e7c60f8a84c7f5327eb00f3c9948b021b91e2e8fe3a76af4623ac58538780f0789f1e03947b7de96c5f7994
languageName: node
linkType: hard
@@ -1687,7 +1687,17 @@ __metadata:
languageName: node
linkType: hard
-"css-tree@npm:^2.2.1, css-tree@npm:~2.2.0":
+"css-tree@npm:^2.3.1":
+ version: 2.3.1
+ resolution: "css-tree@npm:2.3.1"
+ dependencies:
+ mdn-data: 2.0.30
+ source-map-js: ^1.0.1
+ checksum: 493cc24b5c22b05ee5314b8a0d72d8a5869491c1458017ae5ed75aeb6c3596637dbe1b11dac2548974624adec9f7a1f3a6cf40593dc1f9185eb0e8279543fbc0
+ languageName: node
+ linkType: hard
+
+"css-tree@npm:~2.2.0":
version: 2.2.1
resolution: "css-tree@npm:2.2.1"
dependencies:
@@ -1704,7 +1714,7 @@ __metadata:
languageName: node
linkType: hard
-"csso@npm:5.0.5":
+"csso@npm:^5.0.5":
version: 5.0.5
resolution: "csso@npm:5.0.5"
dependencies:
@@ -3390,6 +3400,13 @@ __metadata:
languageName: node
linkType: hard
+"mdn-data@npm:2.0.30":
+ version: 2.0.30
+ resolution: "mdn-data@npm:2.0.30"
+ checksum: d6ac5ac7439a1607df44b22738ecf83f48e66a0874e4482d6424a61c52da5cde5750f1d1229b6f5fa1b80a492be89465390da685b11f97d62b8adcc6e88189aa
+ languageName: node
+ linkType: hard
+
"merge-stream@npm:^2.0.0":
version: 2.0.0
resolution: "merge-stream@npm:2.0.0"
@@ -4429,14 +4446,14 @@ __metadata:
"@rollup/plugin-commonjs": ^22.0.2
"@rollup/plugin-node-resolve": ^14.1.0
"@trysound/sax": 0.2.0
- "@types/css-tree": ^2.0.0
- "@types/csso": ~5.0.3
+ "@types/css-tree": ^2.3.4
+ "@types/csso": ^5.0.4
"@types/jest": ^29.5.5
commander: ^7.2.0
css-select: ^5.1.0
- css-tree: ^2.2.1
+ css-tree: ^2.3.1
css-what: ^6.1.0
- csso: 5.0.5
+ csso: ^5.0.5
del: ^6.0.0
eslint: ^8.55.0
jest: ^29.5.5