mirror of
https://github.com/svg/svgo.git
synced 2025-07-29 20:21:14 +03:00
Implement preset-default plugin (#1513)
I saw complaints about `extendDefaultPlugins` api - it cannot be used when svgo is installed globally - it requires svgo to be installed when using svgo-loader or svgo-jsx - it prevents using serializable config formats like json In this diff I introduced the new plugin which is a bundle of all default plugins. ```js module.exports = { plugins: [ 'preset_default', // or { name: 'preset_default', floatPrecision: 4, overrides: { convertPathData: { applyTransforms: false } } } ] } ```
This commit is contained in:
203
README.md
203
README.md
@ -2,7 +2,6 @@
|
||||
<img src="./logo/logo-web.svg" width="348.61" height="100" alt="SVGO logo"/>
|
||||
</div>
|
||||
|
||||
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://discord.gg/z8jX8NYxrE)
|
||||
|
||||
**SVG O**ptimizer is a Node.js-based tool for optimizing SVG vector graphics files.
|
||||
@ -53,8 +52,8 @@ module.exports = {
|
||||
js2svg: {
|
||||
indent: 2, // string with spaces or number of spaces. 4 by default
|
||||
pretty: true, // boolean, false by default
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
SVGO has a plugin-based architecture, so almost every optimization is a separate plugin.
|
||||
@ -67,97 +66,83 @@ module.exports = {
|
||||
'builtinPluginName',
|
||||
// or by expanded version
|
||||
{
|
||||
name: 'builtinPluginName'
|
||||
name: 'builtinPluginName',
|
||||
},
|
||||
// some plugins allow/require to pass options
|
||||
{
|
||||
name: 'builtinPluginName',
|
||||
params: {
|
||||
optionName: 'optionValue'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
optionName: 'optionValue',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
The default list is fully overridden if the `plugins` field is specified. To extend the default
|
||||
list use the `extendDefaultPlugins` utility:
|
||||
|
||||
```js
|
||||
const { extendDefaultPlugins } = require('svgo');
|
||||
module.exports = {
|
||||
plugins: extendDefaultPlugins([
|
||||
{
|
||||
name: 'builtinPluginName',
|
||||
params: {
|
||||
optionName: 'optionValue'
|
||||
}
|
||||
}
|
||||
])
|
||||
}
|
||||
```
|
||||
|
||||
To disable one of the default plugins use the `active` field:
|
||||
|
||||
```js
|
||||
const { extendDefaultPlugins } = require('svgo');
|
||||
module.exports = {
|
||||
plugins: extendDefaultPlugins([
|
||||
{
|
||||
name: 'builtinPluginName',
|
||||
active: false
|
||||
}
|
||||
])
|
||||
}
|
||||
```
|
||||
|
||||
See the list of the default plugins:
|
||||
The default preset of plugins is fully overridden if the `plugins` field is specified.
|
||||
Use `preset-default` plugin to customize plugins options.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'removeDoctype',
|
||||
'removeXMLProcInst',
|
||||
'removeComments',
|
||||
'removeMetadata',
|
||||
'removeEditorsNSData',
|
||||
'cleanupAttrs',
|
||||
'mergeStyles',
|
||||
'inlineStyles',
|
||||
'minifyStyles',
|
||||
'cleanupIDs',
|
||||
'removeUselessDefs',
|
||||
'cleanupNumericValues',
|
||||
'convertColors',
|
||||
'removeUnknownsAndDefaults',
|
||||
'removeNonInheritableGroupAttrs',
|
||||
'removeUselessStrokeAndFill',
|
||||
'removeViewBox',
|
||||
'cleanupEnableBackground',
|
||||
'removeHiddenElems',
|
||||
'removeEmptyText',
|
||||
'convertShapeToPath',
|
||||
'convertEllipseToCircle',
|
||||
'moveElemsAttrsToGroup',
|
||||
'moveGroupAttrsToElems',
|
||||
'collapseGroups',
|
||||
'convertPathData',
|
||||
'convertTransform',
|
||||
'removeEmptyAttrs',
|
||||
'removeEmptyContainers',
|
||||
'mergePaths',
|
||||
'removeUnusedNS',
|
||||
'sortDefsChildren',
|
||||
'removeTitle',
|
||||
'removeDesc'
|
||||
]
|
||||
}
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
// customize options
|
||||
builtinPluginName: {
|
||||
optionName: 'optionValue',
|
||||
},
|
||||
// or disable plugins
|
||||
anotherBuiltinPlugin: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Default preset includes the following list of plugins:
|
||||
|
||||
- removeDoctype
|
||||
- removeXMLProcInst
|
||||
- removeComments
|
||||
- removeMetadata
|
||||
- removeEditorsNSData
|
||||
- cleanupAttrs
|
||||
- mergeStyles
|
||||
- inlineStyles
|
||||
- minifyStyles
|
||||
- cleanupIDs
|
||||
- removeUselessDefs
|
||||
- cleanupNumericValues
|
||||
- convertColors
|
||||
- removeUnknownsAndDefaults
|
||||
- removeNonInheritableGroupAttrs
|
||||
- removeUselessStrokeAndFill
|
||||
- removeViewBox
|
||||
- cleanupEnableBackground
|
||||
- removeHiddenElems
|
||||
- removeEmptyText
|
||||
- convertShapeToPath
|
||||
- convertEllipseToCircle
|
||||
- moveElemsAttrsToGroup
|
||||
- moveGroupAttrsToElems
|
||||
- collapseGroups
|
||||
- convertPathData
|
||||
- convertTransform
|
||||
- removeEmptyAttrs
|
||||
- removeEmptyContainers
|
||||
- mergePaths
|
||||
- removeUnusedNS
|
||||
- sortDefsChildren
|
||||
- removeTitle
|
||||
- removeDesc
|
||||
|
||||
It's also possible to specify a custom plugin:
|
||||
|
||||
```js
|
||||
const anotherCustomPlugin = require('./another-custom-plugin.js')
|
||||
const anotherCustomPlugin = require('./another-custom-plugin.js');
|
||||
module.exports = {
|
||||
plugins: [
|
||||
{
|
||||
@ -166,11 +151,11 @@ module.exports = {
|
||||
params: {
|
||||
optionName: 'optionValue',
|
||||
},
|
||||
fn: (ast, params, info) => {}
|
||||
fn: (ast, params, info) => {},
|
||||
},
|
||||
anotherCustomPlugin
|
||||
]
|
||||
}
|
||||
anotherCustomPlugin,
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## API usage
|
||||
@ -187,9 +172,9 @@ const result = optimize(svgString, {
|
||||
// optional but recommended field
|
||||
path: 'path-to.svg',
|
||||
// all config fields are also available here
|
||||
multipass: true
|
||||
})
|
||||
const optimizedSvgString = result.data
|
||||
multipass: true,
|
||||
});
|
||||
const optimizedSvgString = result.data;
|
||||
```
|
||||
|
||||
### loadConfig
|
||||
@ -198,16 +183,16 @@ If you write a tool on top of SVGO you might need a way to load SVGO config.
|
||||
|
||||
```js
|
||||
const { loadConfig } = require('svgo');
|
||||
const config = await loadConfig()
|
||||
const config = await loadConfig();
|
||||
|
||||
// you can also specify a relative or absolute path and customize the current working directory
|
||||
const config = await loadConfig(configFile, cwd)
|
||||
const config = await loadConfig(configFile, cwd);
|
||||
```
|
||||
|
||||
## Built-in plugins
|
||||
|
||||
| Plugin | Description | Default |
|
||||
| ------ | ----------- | ------- |
|
||||
| ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
||||
| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | cleanup attributes from newlines, trailing, and repeating spaces | `enabled` |
|
||||
| [mergeStyles](https://github.com/svg/svgo/blob/master/plugins/mergeStyles.js) | merge multiple style elements into one | `enabled` |
|
||||
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | move and merge styles from `<style>` elements to element `style` attributes | `enabled` |
|
||||
@ -261,31 +246,31 @@ const config = await loadConfig(configFile, cwd)
|
||||
|
||||
## Other Ways to Use SVGO
|
||||
|
||||
* as a web app – [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
* as a GitHub Action – [SVGO Action](https://github.com/marketplace/actions/svgo-action)
|
||||
* as a Grunt task – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* as a Gulp task – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
* as a Mimosa module – [mimosa-minify-svg](https://github.com/dbashford/mimosa-minify-svg)
|
||||
* as an OSX Folder Action – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
* as a webpack loader – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* as a Telegram Bot – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
* as a PostCSS plugin – [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* as an Inkscape plugin – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
* as a Sketch plugin - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
* as a macOS app - [Image Shrinker](https://image-shrinker.com)
|
||||
* as a Rollup plugin - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
* as a VS Code plugin - [vscode-svgo](https://github.com/1000ch/vscode-svgo)
|
||||
* as a Atom plugin - [atom-svgo](https://github.com/1000ch/atom-svgo)
|
||||
* as a Sublime plugin - [Sublime-svgo](https://github.com/1000ch/Sublime-svgo)
|
||||
* as a Figma plugin - [Advanced SVG Export](https://www.figma.com/c/plugin/782713260363070260/Advanced-SVG-Export)
|
||||
* as a Linux app - [Oh My SVG](https://github.com/sonnyp/OhMySVG)
|
||||
* as a Browser extension - [SVG Gobbler](https://github.com/rossmoody/svg-gobbler)
|
||||
* as an API - [Vector Express](https://github.com/smidyo/vectorexpress-api#convertor-svgo)
|
||||
- as a web app – [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
- as a GitHub Action – [SVGO Action](https://github.com/marketplace/actions/svgo-action)
|
||||
- as a Grunt task – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
- as a Gulp task – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
- as a Mimosa module – [mimosa-minify-svg](https://github.com/dbashford/mimosa-minify-svg)
|
||||
- as an OSX Folder Action – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
- as a webpack loader – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
- as a Telegram Bot – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
- as a PostCSS plugin – [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
- as an Inkscape plugin – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
- as a Sketch plugin - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
- as a macOS app - [Image Shrinker](https://image-shrinker.com)
|
||||
- as a Rollup plugin - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
- as a VS Code plugin - [vscode-svgo](https://github.com/1000ch/vscode-svgo)
|
||||
- as a Atom plugin - [atom-svgo](https://github.com/1000ch/atom-svgo)
|
||||
- as a Sublime plugin - [Sublime-svgo](https://github.com/1000ch/Sublime-svgo)
|
||||
- as a Figma plugin - [Advanced SVG Export](https://www.figma.com/c/plugin/782713260363070260/Advanced-SVG-Export)
|
||||
- as a Linux app - [Oh My SVG](https://github.com/sonnyp/OhMySVG)
|
||||
- as a Browser extension - [SVG Gobbler](https://github.com/rossmoody/svg-gobbler)
|
||||
- as an API - [Vector Express](https://github.com/smidyo/vectorexpress-api#convertor-svgo)
|
||||
|
||||
## Donators
|
||||
|
||||
| [<img src="https://sheetjs.com/sketch128.png" width="80">](https://sheetjs.com/) | [<img src="https://raw.githubusercontent.com/fontello/fontello/master/fontello-image.svg" width="80">](https://fontello.com/) |
|
||||
|:-:|:-:|
|
||||
| :------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: |
|
||||
| [SheetJS LLC](https://sheetjs.com/) | [Fontello](https://fontello.com/) |
|
||||
|
||||
## License and Copyright
|
||||
|
12
lib/svgo.js
12
lib/svgo.js
@ -7,7 +7,7 @@ const {
|
||||
} = require('./svgo/config.js');
|
||||
const svg2js = require('./svgo/svg2js.js');
|
||||
const js2svg = require('./svgo/js2svg.js');
|
||||
const invokePlugins = require('./svgo/plugins.js');
|
||||
const { invokePlugins } = require('./svgo/plugins.js');
|
||||
const JSAPI = require('./svgo/jsAPI.js');
|
||||
const { encodeSVGDatauri } = require('./svgo/tools.js');
|
||||
|
||||
@ -42,10 +42,12 @@ const optimize = (input, config) => {
|
||||
"Invalid plugins list. Provided 'plugins' in config should be an array."
|
||||
);
|
||||
}
|
||||
const resolvedPlugins = plugins.map((plugin) =>
|
||||
resolvePluginConfig(plugin, config)
|
||||
);
|
||||
svgjs = invokePlugins(svgjs, info, resolvedPlugins);
|
||||
const resolvedPlugins = plugins.map(resolvePluginConfig);
|
||||
const globalOverrides = {};
|
||||
if (config.floatPrecision != null) {
|
||||
globalOverrides.floatPrecision = config.floatPrecision;
|
||||
}
|
||||
svgjs = invokePlugins(svgjs, info, resolvedPlugins, null, globalOverrides);
|
||||
svgjs = js2svg(svgjs, config.js2svg);
|
||||
if (svgjs.error) {
|
||||
throw Error(svgjs.error);
|
||||
|
122
lib/svgo.test.js
Normal file
122
lib/svgo.test.js
Normal file
@ -0,0 +1,122 @@
|
||||
'use strict';
|
||||
|
||||
const { optimize } = require('./svgo.js');
|
||||
|
||||
test('allow to setup default preset', () => {
|
||||
const svg = `
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 120 120">
|
||||
<desc>
|
||||
Not standard description
|
||||
</desc>
|
||||
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
|
||||
</svg>
|
||||
`;
|
||||
expect(
|
||||
optimize(svg, {
|
||||
plugins: ['preset-default'],
|
||||
js2svg: { pretty: true, indent: 2 },
|
||||
}).data
|
||||
).toMatchInlineSnapshot(`
|
||||
"<svg viewBox=\\"0 0 120 120\\">
|
||||
<circle fill=\\"red\\" cx=\\"60\\" cy=\\"60\\" r=\\"50\\"/>
|
||||
</svg>
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('allow to disable and customize plugins in preset', () => {
|
||||
const svg = `
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 120 120">
|
||||
<desc>
|
||||
Not standard description
|
||||
</desc>
|
||||
<circle fill="#ff0000" cx="60" cy="60" r="50"/>
|
||||
</svg>
|
||||
`;
|
||||
expect(
|
||||
optimize(svg, {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
removeXMLProcInst: false,
|
||||
removeDesc: {
|
||||
removeAny: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
js2svg: { pretty: true, indent: 2 },
|
||||
}).data
|
||||
).toMatchInlineSnapshot(`
|
||||
"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>
|
||||
<svg viewBox=\\"0 0 120 120\\">
|
||||
<desc>
|
||||
Not standard description
|
||||
</desc>
|
||||
<circle fill=\\"red\\" cx=\\"60\\" cy=\\"60\\" r=\\"50\\"/>
|
||||
</svg>
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('allow to customize precision for preset', () => {
|
||||
const svg = `
|
||||
<svg viewBox="0 0 120 120">
|
||||
<circle fill="#ff0000" cx="60.444444" cy="60" r="50"/>
|
||||
</svg>
|
||||
`;
|
||||
expect(
|
||||
optimize(svg, {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
floatPrecision: 4,
|
||||
},
|
||||
},
|
||||
],
|
||||
js2svg: { pretty: true, indent: 2 },
|
||||
}).data
|
||||
).toMatchInlineSnapshot(`
|
||||
"<svg viewBox=\\"0 0 120 120\\">
|
||||
<circle fill=\\"red\\" cx=\\"60.4444\\" cy=\\"60\\" r=\\"50\\"/>
|
||||
</svg>
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('plugin precision should override preset precision', () => {
|
||||
const svg = `
|
||||
<svg viewBox="0 0 120 120">
|
||||
<circle fill="#ff0000" cx="60.444444" cy="60" r="50"/>
|
||||
</svg>
|
||||
`;
|
||||
expect(
|
||||
optimize(svg, {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
floatPrecision: 4,
|
||||
overrides: {
|
||||
cleanupNumericValues: {
|
||||
floatPrecision: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
js2svg: { pretty: true, indent: 2 },
|
||||
}).data
|
||||
).toMatchInlineSnapshot(`
|
||||
"<svg viewBox=\\"0 0 120 120\\">
|
||||
<circle fill=\\"red\\" cx=\\"60.44444\\" cy=\\"60\\" r=\\"50\\"/>
|
||||
</svg>
|
||||
"
|
||||
`);
|
||||
});
|
@ -58,12 +58,30 @@ const defaultPlugins = pluginsOrder.filter((name) => pluginsMap[name].active);
|
||||
exports.defaultPlugins = defaultPlugins;
|
||||
|
||||
const extendDefaultPlugins = (plugins) => {
|
||||
console.warn(
|
||||
'\n"extendDefaultPlugins" utility is deprecated.\n' +
|
||||
'Use "preset-default" plugin with overrides instead.\n' +
|
||||
'For example:\n' +
|
||||
`{\n` +
|
||||
` name: 'preset-default',\n` +
|
||||
` params: {\n` +
|
||||
` overrides: {\n` +
|
||||
` // customize plugin options\n` +
|
||||
` convertShapeToPath: {\n` +
|
||||
` convertArcs: true\n` +
|
||||
` },\n` +
|
||||
` // disable plugins\n` +
|
||||
` convertPathData: false\n` +
|
||||
` }\n` +
|
||||
` }\n` +
|
||||
`}\n`
|
||||
);
|
||||
const extendedPlugins = pluginsOrder.map((name) => ({
|
||||
name,
|
||||
active: pluginsMap[name].active,
|
||||
}));
|
||||
for (const plugin of plugins) {
|
||||
const resolvedPlugin = resolvePluginConfig(plugin, {});
|
||||
const resolvedPlugin = resolvePluginConfig(plugin);
|
||||
const index = pluginsOrder.indexOf(resolvedPlugin.name);
|
||||
if (index === -1) {
|
||||
extendedPlugins.push(plugin);
|
||||
@ -75,11 +93,8 @@ const extendDefaultPlugins = (plugins) => {
|
||||
};
|
||||
exports.extendDefaultPlugins = extendDefaultPlugins;
|
||||
|
||||
const resolvePluginConfig = (plugin, config) => {
|
||||
const resolvePluginConfig = (plugin) => {
|
||||
let configParams = {};
|
||||
if ('floatPrecision' in config) {
|
||||
configParams.floatPrecision = config.floatPrecision;
|
||||
}
|
||||
if (typeof plugin === 'string') {
|
||||
// resolve builtin plugin specified as string
|
||||
const pluginConfig = pluginsMap[plugin];
|
||||
|
@ -7,47 +7,40 @@ const { visit } = require('../xast.js');
|
||||
*
|
||||
* @module plugins
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} ast input ast
|
||||
* @param {Object} info extra information
|
||||
* @param {Array} plugins plugins object from config
|
||||
* @return {Object} output data
|
||||
* @return {Object} output ast
|
||||
*/
|
||||
module.exports = function (data, info, plugins) {
|
||||
// Try to group sequential elements of plugins array
|
||||
// to optimize ast traversing
|
||||
const groups = [];
|
||||
let prev;
|
||||
const invokePlugins = (ast, info, plugins, overrides, globalOverrides) => {
|
||||
for (const plugin of plugins) {
|
||||
if (prev && plugin.type == prev[0].type) {
|
||||
prev.push(plugin);
|
||||
} else {
|
||||
prev = [plugin];
|
||||
groups.push(prev);
|
||||
const override = overrides == null ? null : overrides[plugin.name];
|
||||
if (override === false) {
|
||||
continue;
|
||||
}
|
||||
const params = { ...plugin.params, ...globalOverrides, ...override };
|
||||
|
||||
if (plugin.type === 'perItem') {
|
||||
ast = perItem(ast, info, plugin, params);
|
||||
}
|
||||
for (const group of groups) {
|
||||
switch (group[0].type) {
|
||||
case 'perItem':
|
||||
data = perItem(data, info, group);
|
||||
break;
|
||||
case 'perItemReverse':
|
||||
data = perItem(data, info, group, true);
|
||||
break;
|
||||
case 'full':
|
||||
data = full(data, info, group);
|
||||
break;
|
||||
case 'visitor':
|
||||
for (const plugin of group) {
|
||||
if (plugin.type === 'perItemReverse') {
|
||||
ast = perItem(ast, info, plugin, params, true);
|
||||
}
|
||||
if (plugin.type === 'full') {
|
||||
if (plugin.active) {
|
||||
const visitor = plugin.fn(data, plugin.params, info);
|
||||
visit(data, visitor);
|
||||
ast = plugin.fn(ast, params, info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (plugin.type === 'visitor') {
|
||||
if (plugin.active) {
|
||||
const visitor = plugin.fn(ast, params, info);
|
||||
visit(ast, visitor);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return ast;
|
||||
};
|
||||
exports.invokePlugins = invokePlugins;
|
||||
|
||||
/**
|
||||
* Direct or reverse per-item loop.
|
||||
@ -58,53 +51,41 @@ module.exports = function (data, info, plugins) {
|
||||
* @param {boolean} [reverse] reverse pass?
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function perItem(data, info, plugins, reverse) {
|
||||
function perItem(data, info, plugin, params, reverse) {
|
||||
function monkeys(items) {
|
||||
items.children = items.children.filter(function (item) {
|
||||
// reverse pass
|
||||
if (reverse && item.children) {
|
||||
monkeys(item);
|
||||
}
|
||||
|
||||
// main filter
|
||||
var filter = true;
|
||||
|
||||
for (var i = 0; filter && i < plugins.length; i++) {
|
||||
var plugin = plugins[i];
|
||||
|
||||
if (plugin.active && plugin.fn(item, plugin.params, info) === false) {
|
||||
filter = false;
|
||||
let kept = true;
|
||||
if (plugin.active) {
|
||||
kept = plugin.fn(item, params, info) !== false;
|
||||
}
|
||||
}
|
||||
|
||||
// direct pass
|
||||
if (!reverse && item.children) {
|
||||
monkeys(item);
|
||||
}
|
||||
|
||||
return filter;
|
||||
return kept;
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
return monkeys(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Full" plugins.
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Array} plugins plugins list to process
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function full(data, info, plugins) {
|
||||
plugins.forEach(function (plugin) {
|
||||
if (plugin.active) {
|
||||
data = plugin.fn(data, plugin.params, info);
|
||||
const createPreset = ({ name, plugins }) => {
|
||||
return {
|
||||
name,
|
||||
type: 'full',
|
||||
fn: (ast, params, info) => {
|
||||
const { floatPrecision, overrides } = params;
|
||||
const globalOverrides = {};
|
||||
if (floatPrecision != null) {
|
||||
globalOverrides.floatPrecision = floatPrecision;
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
return invokePlugins(ast, info, plugins, overrides, globalOverrides);
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.createPreset = createPreset;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { closestByName } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'addAttributesToSVGElement';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'addClassesToSVGElement';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'cleanupAttrs';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description =
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { traverse } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'cleanupEnableBackground';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -3,6 +3,8 @@
|
||||
const { traverse, traverseBreak } = require('../lib/xast.js');
|
||||
const { parseName } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'cleanupIDs';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { removeLeadingZero } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'cleanupListOfValues';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'cleanupNumericValues';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { inheritableAttrs, elemsGroups } = require('./_collections');
|
||||
|
||||
exports.name = 'collapseGroups';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'convertColors';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'convertEllipseToCircle';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||
|
@ -6,6 +6,7 @@ const { path2js, js2path } = require('./_path.js');
|
||||
const { applyTransforms } = require('./_applyTransforms.js');
|
||||
const { cleanupOutData } = require('../lib/svgo/tools');
|
||||
|
||||
exports.name = 'convertPathData';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description =
|
||||
|
@ -3,6 +3,7 @@
|
||||
const { stringifyPathData } = require('../lib/path.js');
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'convertShapeToPath';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'converts basic shapes to more compact path form';
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'convertStyleToAttrs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'convertTransform';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -4,6 +4,8 @@ const csstree = require('css-tree');
|
||||
const { querySelectorAll, closestByName } = require('../lib/xast.js');
|
||||
const cssTools = require('../lib/css-tools');
|
||||
|
||||
exports.name = 'inlineStyles';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -4,6 +4,7 @@ const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { path2js, js2path, intersects } = require('./_path.js');
|
||||
|
||||
exports.name = 'mergePaths';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'merges multiple paths in one if possible';
|
||||
|
@ -3,6 +3,7 @@
|
||||
const { closestByName, detachNodeFromParent } = require('../lib/xast.js');
|
||||
const JSAPI = require('../lib/svgo/jsAPI.js');
|
||||
|
||||
exports.name = 'mergeStyles';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'merge multiple style elements into one';
|
||||
|
@ -3,6 +3,8 @@
|
||||
const csso = require('csso');
|
||||
const { traverse } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'minifyStyles';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { inheritableAttrs, pathElems } = require('./_collections');
|
||||
|
||||
exports.name = 'moveElemsAttrsToGroup';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { pathElems, referencesProps } = require('./_collections.js');
|
||||
|
||||
exports.name = 'moveGroupAttrsToElems';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
// builtin presets
|
||||
exports['preset-default'] = require('./preset-default.js');
|
||||
|
||||
// builtin plugins
|
||||
exports.addAttributesToSVGElement = require('./addAttributesToSVGElement.js');
|
||||
exports.addClassesToSVGElement = require('./addClassesToSVGElement.js');
|
||||
exports.cleanupAttrs = require('./cleanupAttrs.js');
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'prefixIds';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
80
plugins/preset-default.js
Normal file
80
plugins/preset-default.js
Normal file
@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
const { createPreset } = require('../lib/svgo/plugins.js');
|
||||
|
||||
const removeDoctype = require('./removeDoctype.js');
|
||||
const removeXMLProcInst = require('./removeXMLProcInst.js');
|
||||
const removeComments = require('./removeComments.js');
|
||||
const removeMetadata = require('./removeMetadata.js');
|
||||
const removeEditorsNSData = require('./removeEditorsNSData.js');
|
||||
const cleanupAttrs = require('./cleanupAttrs.js');
|
||||
const mergeStyles = require('./mergeStyles.js');
|
||||
const inlineStyles = require('./inlineStyles.js');
|
||||
const minifyStyles = require('./minifyStyles.js');
|
||||
const cleanupIDs = require('./cleanupIDs.js');
|
||||
const removeUselessDefs = require('./removeUselessDefs.js');
|
||||
const cleanupNumericValues = require('./cleanupNumericValues.js');
|
||||
const convertColors = require('./convertColors.js');
|
||||
const removeUnknownsAndDefaults = require('./removeUnknownsAndDefaults.js');
|
||||
const removeNonInheritableGroupAttrs = require('./removeNonInheritableGroupAttrs.js');
|
||||
const removeUselessStrokeAndFill = require('./removeUselessStrokeAndFill.js');
|
||||
const removeViewBox = require('./removeViewBox.js');
|
||||
const cleanupEnableBackground = require('./cleanupEnableBackground.js');
|
||||
const removeHiddenElems = require('./removeHiddenElems.js');
|
||||
const removeEmptyText = require('./removeEmptyText.js');
|
||||
const convertShapeToPath = require('./convertShapeToPath.js');
|
||||
const convertEllipseToCircle = require('./convertEllipseToCircle.js');
|
||||
const moveElemsAttrsToGroup = require('./moveElemsAttrsToGroup.js');
|
||||
const moveGroupAttrsToElems = require('./moveGroupAttrsToElems.js');
|
||||
const collapseGroups = require('./collapseGroups.js');
|
||||
const convertPathData = require('./convertPathData.js');
|
||||
const convertTransform = require('./convertTransform.js');
|
||||
const removeEmptyAttrs = require('./removeEmptyAttrs.js');
|
||||
const removeEmptyContainers = require('./removeEmptyContainers.js');
|
||||
const mergePaths = require('./mergePaths.js');
|
||||
const removeUnusedNS = require('./removeUnusedNS.js');
|
||||
const sortDefsChildren = require('./sortDefsChildren.js');
|
||||
const removeTitle = require('./removeTitle.js');
|
||||
const removeDesc = require('./removeDesc.js');
|
||||
|
||||
const presetDefault = createPreset({
|
||||
name: 'presetDefault',
|
||||
plugins: [
|
||||
removeDoctype,
|
||||
removeXMLProcInst,
|
||||
removeComments,
|
||||
removeMetadata,
|
||||
removeEditorsNSData,
|
||||
cleanupAttrs,
|
||||
mergeStyles,
|
||||
inlineStyles,
|
||||
minifyStyles,
|
||||
cleanupIDs,
|
||||
removeUselessDefs,
|
||||
cleanupNumericValues,
|
||||
convertColors,
|
||||
removeUnknownsAndDefaults,
|
||||
removeNonInheritableGroupAttrs,
|
||||
removeUselessStrokeAndFill,
|
||||
removeViewBox,
|
||||
cleanupEnableBackground,
|
||||
removeHiddenElems,
|
||||
removeEmptyText,
|
||||
convertShapeToPath,
|
||||
convertEllipseToCircle,
|
||||
moveElemsAttrsToGroup,
|
||||
moveGroupAttrsToElems,
|
||||
collapseGroups,
|
||||
convertPathData,
|
||||
convertTransform,
|
||||
removeEmptyAttrs,
|
||||
removeEmptyContainers,
|
||||
mergePaths,
|
||||
removeUnusedNS,
|
||||
sortDefsChildren,
|
||||
removeTitle,
|
||||
removeDesc,
|
||||
],
|
||||
});
|
||||
|
||||
module.exports = presetDefault;
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeAttributesBySelector';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
var DEFAULT_SEPARATOR = ':';
|
||||
|
||||
exports.name = 'removeAttrs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeComments';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes comments';
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeDesc';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes <desc>';
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeDimensions';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeDoctype';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes doctype declaration';
|
||||
|
@ -3,6 +3,8 @@
|
||||
const { parseName } = require('../lib/svgo/tools.js');
|
||||
const { editorNamespaces } = require('./_collections');
|
||||
|
||||
exports.name = 'removeEditorsNSData';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeElementsByAttr';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { attrsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeEmptyAttrs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { elemsGroups } = require('./_collections');
|
||||
|
||||
exports.name = 'removeEmptyContainers';
|
||||
|
||||
exports.type = 'perItemReverse';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeEmptyText';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes empty <text> elements';
|
||||
|
@ -8,6 +8,7 @@ const {
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { parsePathData } = require('../lib/path.js');
|
||||
|
||||
exports.name = 'removeHiddenElems';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description =
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeMetadata';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes <metadata>';
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeNonInheritableGroupAttrs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeOffCanvasPaths';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeRasterImages';
|
||||
exports.type = 'visitor';
|
||||
exports.active = false;
|
||||
exports.description = 'removes raster images (disabled by default)';
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeScriptElement';
|
||||
exports.type = 'visitor';
|
||||
exports.active = false;
|
||||
exports.description = 'removes <script> elements (disabled by default)';
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeStyleElement';
|
||||
exports.type = 'visitor';
|
||||
exports.active = false;
|
||||
exports.description = 'removes <style> element (disabled by default)';
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeTitle';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes <title>';
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { parseName } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'removeUnknownsAndDefaults';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -3,6 +3,8 @@
|
||||
const { traverse } = require('../lib/xast.js');
|
||||
const { parseName } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'removeUnusedNS';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { elemsGroups } = require('./_collections');
|
||||
|
||||
exports.name = 'removeUselessDefs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeUselessStrokeAndFill';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { closestByName } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeViewBox';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeXMLNS';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeXMLProcInst';
|
||||
exports.type = 'visitor';
|
||||
exports.active = true;
|
||||
exports.description = 'removes XML processing instructions';
|
||||
|
@ -3,6 +3,8 @@
|
||||
const { traverse } = require('../lib/xast.js');
|
||||
const JSAPI = require('../lib/svgo/jsAPI');
|
||||
|
||||
exports.name = 'reusePaths';
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const { parseName } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'sortAttrs';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'sortDefsChildren';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = true;
|
||||
|
@ -13,7 +13,7 @@ describe('config', function () {
|
||||
{ name: 'removeDoctype', active: false },
|
||||
{ name: 'convertColors', params: { shorthex: false } },
|
||||
{ name: 'removeRasterImages', params: { param: true } },
|
||||
].map((plugin) => resolvePluginConfig(plugin, {}));
|
||||
].map((plugin) => resolvePluginConfig(plugin));
|
||||
const removeDoctype = getPlugin('removeDoctype', plugins);
|
||||
const convertColors = getPlugin('convertColors', plugins);
|
||||
const removeRasterImages = getPlugin('removeRasterImages', plugins);
|
||||
@ -62,19 +62,15 @@ describe('config', function () {
|
||||
describe('replace default config with custom', function () {
|
||||
const config = {
|
||||
multipass: true,
|
||||
floatPrecision: 2,
|
||||
plugins: [
|
||||
'convertPathData',
|
||||
{ name: 'cleanupNumericValues' },
|
||||
{ name: 'customPlugin', fn: () => {} },
|
||||
],
|
||||
};
|
||||
const plugins = config.plugins.map((plugin) =>
|
||||
resolvePluginConfig(plugin, config)
|
||||
);
|
||||
const plugins = config.plugins.map((plugin) => resolvePluginConfig(plugin));
|
||||
const cleanupNumericValues = getPlugin('cleanupNumericValues', plugins);
|
||||
const convertPathData = getPlugin('convertPathData', plugins);
|
||||
const customPlugin = getPlugin('customPlugin', plugins);
|
||||
|
||||
it('should have "multipass"', function () {
|
||||
expect(config.multipass).toEqual(true);
|
||||
@ -88,12 +84,6 @@ describe('config', function () {
|
||||
expect(cleanupNumericValues.active).toEqual(true);
|
||||
expect(convertPathData.active).toEqual(true);
|
||||
});
|
||||
|
||||
it('plugins should inherit floatPrecision top level config', function () {
|
||||
expect(cleanupNumericValues.params.floatPrecision).toEqual(2);
|
||||
expect(convertPathData.params.floatPrecision).toEqual(2);
|
||||
expect(customPlugin.params.floatPrecision).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom plugins', function () {
|
||||
@ -104,7 +94,7 @@ describe('config', function () {
|
||||
type: 'perItem',
|
||||
fn: function () {},
|
||||
},
|
||||
].map((plugin) => resolvePluginConfig(plugin, {}));
|
||||
].map((plugin) => resolvePluginConfig(plugin));
|
||||
const customPlugin = getPlugin('aCustomPlugin', plugins);
|
||||
|
||||
it('custom plugin should be enabled', function () {
|
||||
@ -123,7 +113,7 @@ describe('config', function () {
|
||||
type: 'perItem',
|
||||
fn: function () {},
|
||||
},
|
||||
].map((plugin) => resolvePluginConfig(plugin, {}));
|
||||
].map((plugin) => resolvePluginConfig(plugin));
|
||||
const customPlugin = getPlugin('aCustomPlugin', plugins);
|
||||
|
||||
it('config.plugins should have length 1', function () {
|
||||
@ -167,20 +157,17 @@ describe('config', function () {
|
||||
});
|
||||
it('should activate inactive by default plugins', () => {
|
||||
const removeAttrsPlugin = resolvePluginConfig(
|
||||
extendedPlugins[removeAttrsIndex],
|
||||
{}
|
||||
extendedPlugins[removeAttrsIndex]
|
||||
);
|
||||
const cleanupIDsPlugin = resolvePluginConfig(
|
||||
extendedPlugins[cleanupIDsIndex],
|
||||
{}
|
||||
extendedPlugins[cleanupIDsIndex]
|
||||
);
|
||||
expect(removeAttrsPlugin.active).toEqual(true);
|
||||
expect(cleanupIDsPlugin.active).toEqual(true);
|
||||
});
|
||||
it('should leave not extended inactive plugins to be inactive', () => {
|
||||
const inactivePlugin = resolvePluginConfig(
|
||||
extendedPlugins.find((item) => item.name === 'addClassesToSVGElement'),
|
||||
{}
|
||||
extendedPlugins.find((item) => item.name === 'addClassesToSVGElement')
|
||||
);
|
||||
expect(inactivePlugin.active).toEqual(false);
|
||||
});
|
||||
@ -189,18 +176,6 @@ describe('config', function () {
|
||||
'customPlugin'
|
||||
);
|
||||
});
|
||||
it('should pass global floatPrecision when plugin one not specified', () => {
|
||||
const convertPathDataPlugin = resolvePluginConfig(
|
||||
extendedPlugins.find((item) => item.name === 'convertPathData'),
|
||||
{ floatPrecision: 1 }
|
||||
);
|
||||
const convertTransformPlugin = resolvePluginConfig(
|
||||
extendedPlugins.find((item) => item.name === 'convertTransform'),
|
||||
{}
|
||||
);
|
||||
expect(convertPathDataPlugin.params.floatPrecision).toEqual(1);
|
||||
expect(convertTransformPlugin.params.floatPrecision).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('config', () => {
|
||||
|
@ -3,7 +3,7 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { EOL } = require('os');
|
||||
const { optimize, extendDefaultPlugins } = require('../../lib/svgo.js');
|
||||
const { optimize } = require('../../lib/svgo.js');
|
||||
|
||||
const regEOL = new RegExp(EOL, 'g');
|
||||
|
||||
@ -37,11 +37,7 @@ describe('svgo', () => {
|
||||
const [original, expected] = await parseFixture('multipass-prefix-ids.svg');
|
||||
const result = optimize(original, {
|
||||
multipass: true,
|
||||
plugins: extendDefaultPlugins([
|
||||
{
|
||||
name: 'prefixIds',
|
||||
},
|
||||
]),
|
||||
plugins: ['preset-default', 'prefixIds'],
|
||||
});
|
||||
expect(normalize(result.data)).toEqual(expected);
|
||||
});
|
||||
|
@ -12,8 +12,8 @@
|
||||
},
|
||||
"include": ["lib/**/*", "plugins/**/*", "test/**/*"],
|
||||
"exclude": [
|
||||
"**/*.test.js",
|
||||
"lib/svgo-node.js",
|
||||
"lib/style.test.js",
|
||||
"lib/svgo/coa.js",
|
||||
"lib/svgo/config.js",
|
||||
"lib/svgo/js2svg.js",
|
||||
@ -62,20 +62,11 @@
|
||||
"plugins/removeXMLNS.js",
|
||||
"plugins/reusePaths.js",
|
||||
"plugins/sortDefsChildren.js",
|
||||
"plugins/preset-default.js",
|
||||
"lib/svgo/jsAPI.js",
|
||||
"test/browser.js",
|
||||
"test/coa/_index.test.js",
|
||||
"test/config/_index.test.js",
|
||||
"test/config/fixtures/invalid-array.js",
|
||||
"test/config/fixtures/invalid-null.js",
|
||||
"test/config/fixtures/invalid-string.js",
|
||||
"test/config/fixtures/invalid/svgo.config.js",
|
||||
"test/config/fixtures/module-not-found.js",
|
||||
"test/config/fixtures/one/two/config.js",
|
||||
"test/jsapi/_index.test.js",
|
||||
"test/plugins/_index.test.js",
|
||||
"test/config/fixtures/**/*.js",
|
||||
"test/regression.js",
|
||||
"test/svg2js/_index.test.js",
|
||||
"test/svgo/_index.test.js"
|
||||
"lib/svgo/plugins.js"
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user